using BPA.KitChen.GroupMeal.Application.BaseDto;
using BPA.KitChen.GroupMeal.Application.Service.Device.PushDto.Batching;
using BPA.KitChen.GroupMeal.Application.Service.Device.PushDto.Goods;
using BPA.KitChen.GroupMeal.Application.Service.Device.PushDto.GoodsTechnology;
using BPA.KitChen.GroupMeal.Application.Service.Device.PushDto.ProductFunction;
using BPA.KitChen.GroupMeal.Core.Common.Const;
using Furion;
using Furion.FriendlyException;
using Furion.RemoteRequest.Extensions;
using Newtonsoft.Json;
using System.Reflection;

namespace BPA.KitChen.GroupMeal.Application.Service
{
    public class RequestParmsHeadlen
    {
        private string BaseServerUrl = App.GetConfig<string>("SAAS_Manage");
        public async Task<dynamic> GetParm(int type, string data, string deviceId)
        {
            var getProductFunctionurl = BaseServerUrl + "api/productfunction/getproductfunction_alm?deviceId=" + deviceId;//获取商品属性
            var responseProductFunction = await getProductFunctionurl.SetHttpMethod(HttpMethod.Get).GetAsStringAsync();
            var resProductFunction = JsonConvert.DeserializeObject<ResponDataBase>(responseProductFunction);
            if (resProductFunction.statusCode != "200") throw Oops.Oh("获取该设备的物模型数据失败");
            if (resProductFunction.data == null) throw Oops.Oh("找不到设备的物模型配置，请配置相关参数后再试");
            var dataProductFunction = JsonConvert.DeserializeObject<List<ProductFunctionDto>>(resProductFunction.data.ToString());
            dynamic obj = null;
            switch (type)
            {
                case 1: //商品下发
                    var GoodsFunction = dataProductFunction.Where(x => x.Name == "商品数据下发" && x.Type == "1").FirstOrDefault();
                    if (GoodsFunction == null) throw Oops.Oh("该设备的物模型还没配置对应功能，请配置相关参数后再试");
                    var GoodsFunctionValue = GoodsFunction.ProductFunctionValue.Where(x => x.IsDefault == true && x.ActionName == "DataSoure").First();
                    if (string.IsNullOrEmpty(GoodsFunctionValue.ActionValue)) throw Oops.Oh("该设备的物模型配置对应功能参数没有配置，请配置相关参数后再试");
                    obj = await GetGoods(data, GoodsFunctionValue.ActionValue);
                    break;
                case 2://物料下发
                    var BatchingFunction = dataProductFunction.Where(x => x.Name == "物料数据下发" && x.Type == "1").FirstOrDefault();
                    if (BatchingFunction == null) throw Oops.Oh("该设备的物模型还没配置对应功能，请配置相关参数后再试");
                    var BatchingFunctionValue = BatchingFunction.ProductFunctionValue.Where(x => x.IsDefault == true && x.ActionName == "DataSoure").First();
                    if (string.IsNullOrEmpty(BatchingFunctionValue.ActionValue)) throw Oops.Oh("该设备的物模型配置对应功能参数没有配置，请配置相关参数后再试");
                    obj = await GetBatching(data, BatchingFunctionValue.ActionValue);
                    break;
                case 4:
                    var TechnologyFunction = dataProductFunction.Where(x => x.Name == "工艺数据下发" && x.Type == "1").FirstOrDefault();
                    if (TechnologyFunction == null) throw Oops.Oh("该设备的物模型还没配置对应功能，请配置相关参数后再试");
                    var TechnologyFunctionValue = TechnologyFunction.ProductFunctionValue.Where(x => x.IsDefault == true && x.ActionName == "DataSoure").First();
                    if (string.IsNullOrEmpty(TechnologyFunctionValue.ActionValue)) throw Oops.Oh("该设备的物模型配置对应功能参数没有配置，请配置相关参数后再试");
                    obj = await GetGoodsTechnology(data, deviceId, TechnologyFunctionValue.ActionValue);
                    break;
            }
            return obj;

        }
        private async Task<dynamic> GetGoods(string data, string productFunctionData)
        {
            try
            {
                //商品信息
                var goodsData = JsonConvert.DeserializeObject<List<GoodsInfoDto>>(data);

                var cpjson = productFunctionData.Replace("\r", "").Replace("\n", "").Replace("\t", "");
                var DynamicObject = JsonConvert.DeserializeObject<dynamic>(cpjson);
                //商品信息
                if (IsPropertyExist(DynamicObject, ProductParametersConst_Goods.goodsinfo))
                {
                    var goodsinfo = GetDynamic(goodsData, DynamicObject.goodsinfo[0]);
                    DynamicObject.goodsinfo = JsonConvert.DeserializeObject<dynamic>(JsonConvert.SerializeObject(goodsinfo));
                }
                //商品属性
                if (IsPropertyExist(DynamicObject, ProductParametersConst_Goods.goodsAttribute))
                {
                    //获取商品属性
                    var getGoodsAttributeurl = BaseServerUrl + "api/goodsattribute/getgoodsattributelist_alm";//获取商品属性
                    var responseGoodsAttribute = await getGoodsAttributeurl.SetHeaders(new
                    {
                        groupId = App.User?.FindFirst(ClaimConst.GroupId)?.Value
                    }).SetHttpMethod(HttpMethod.Get).GetAsStringAsync();
                    var resGoodsAttribute = JsonConvert.DeserializeObject<ResponDataBase>(responseGoodsAttribute);
                    if (resGoodsAttribute.statusCode != "200") throw Oops.Oh("获取商品属性数据失败");
                    var dataGoodsAttribute = JsonConvert.DeserializeObject<List<GoodsAttributeDto>>(resGoodsAttribute.data.ToString());
                    var goodsAttribute = GetDynamic(dataGoodsAttribute, DynamicObject.goodsAttribute[0]);
                    DynamicObject.goodsAttribute = JsonConvert.DeserializeObject<dynamic>(JsonConvert.SerializeObject(goodsAttribute));
                }
                //商品单位
                if (IsPropertyExist(DynamicObject, ProductParametersConst_Goods.goodsUnitInfo))
                {
                    //获商品单位
                    var getGoodsUinturl = BaseServerUrl + "api/goods/getgoodsuintlist_alm";//获商品单位
                    var responseGoodsUint = await getGoodsUinturl.SetHeaders(new
                    {
                        groupId = App.User?.FindFirst(ClaimConst.GroupId)?.Value
                    }).SetHttpMethod(HttpMethod.Get).GetAsStringAsync();
                    var resGoodsUint = JsonConvert.DeserializeObject<ResponDataBase>(responseGoodsUint);
                    if (resGoodsUint.statusCode != "200") throw Oops.Oh("获取商品单位数据失败");
                    var dataGoodsUint = JsonConvert.DeserializeObject<List<GoodsUintDto>>(resGoodsUint.data.ToString());
                    var goodsUnitInfo = GetDynamic(dataGoodsUint, DynamicObject.goodsUnitInfo[0]);
                    DynamicObject.goodsUnitInfo = JsonConvert.DeserializeObject<dynamic>(JsonConvert.SerializeObject(goodsUnitInfo));
                }
                //商品分类
                if (IsPropertyExist(DynamicObject, ProductParametersConst_Goods.goodsTypeInfo))
                {
                    //获取商品分类
                    var getGoodsTypeturl = BaseServerUrl + "api/goodstype/getgoodstypelist_alm";//获取商品分类
                    var responseGoodsType = await getGoodsTypeturl.SetHeaders(new
                    {
                        groupId = App.User?.FindFirst(ClaimConst.GroupId)?.Value
                    }).SetHttpMethod(HttpMethod.Get).GetAsStringAsync();
                    var resGoodsType = JsonConvert.DeserializeObject<ResponDataBase>(responseGoodsType);
                    if (resGoodsType.statusCode != "200") throw Oops.Oh("获取商品分类数据失败");
                    var dataGoodsType = JsonConvert.DeserializeObject<List<GoodsTypeDto>>(resGoodsType.data.ToString());
                    var goodsTypeInfo = GetDynamic(dataGoodsType, DynamicObject.goodsTypeInfo[0]);
                    DynamicObject.goodsTypeInfo = JsonConvert.DeserializeObject<dynamic>(JsonConvert.SerializeObject(goodsTypeInfo));
                }
                return DynamicObject;
            }
            catch (Exception e)
            {
                throw Oops.Oh("解析数据失败");
            }

        }
        private async Task<dynamic> GetBatching(string data, string productFunctionData)
        {
            try
            {
                var cpjson = productFunctionData.Replace("\r", "").Replace("\n", "").Replace("\t", "");
                var DynamicObject = JsonConvert.DeserializeObject<dynamic>(cpjson);
                if (IsPropertyExist(DynamicObject, ProductParametersConst_Batching.batchinginfo))
                {
                    //物料信息
                    var batchingData = JsonConvert.DeserializeObject<List<BatchingDto>>(data);
                    var batchinginfo = GetDynamic(batchingData, DynamicObject.batchinginfo[0]);
                    DynamicObject.batchinginfo = JsonConvert.DeserializeObject<dynamic>(JsonConvert.SerializeObject(batchinginfo));
                }
                if (IsPropertyExist(DynamicObject, ProductParametersConst_Batching.batchingTypeinfo))
                {
                    //获取物料分类
                    var getTypeurl = BaseServerUrl + "api/batching/getbatchingtypelist_alm";//获取物料分类
                    var responseType = await getTypeurl.SetHeaders(new
                    {
                        groupId = App.User?.FindFirst(ClaimConst.GroupId)?.Value
                    }).SetHttpMethod(HttpMethod.Get).GetAsStringAsync();
                    var resType = JsonConvert.DeserializeObject<ResponDataBase>(responseType);
                    if (resType.statusCode != "200") throw Oops.Oh("获取物料分类数据失败");
                    var dataType = JsonConvert.DeserializeObject<List<BatchingTypeDto>>(resType.data.ToString());
                    var batchingTypeinfo = GetDynamic(dataType, DynamicObject.batchingTypeinfo[0]);
                    DynamicObject.batchingTypeinfo = JsonConvert.DeserializeObject<dynamic>(JsonConvert.SerializeObject(batchingTypeinfo));
                }
                if (IsPropertyExist(DynamicObject, ProductParametersConst_Batching.batchingUnitinfo))
                {
                    //获取物料单位
                    var getuinurl = BaseServerUrl + "api/batching/getbatchinguintList_alm";//获取物料单位
                    var responseUnit = await getuinurl.SetHeaders(new
                    {
                        groupId = App.User?.FindFirst(ClaimConst.GroupId)?.Value
                    }).SetHttpMethod(HttpMethod.Get).GetAsStringAsync();
                    var resUnit = JsonConvert.DeserializeObject<ResponDataBase>(responseUnit);
                    if (resUnit.statusCode != "200") throw Oops.Oh("获取物料单位数据失败");
                    var dataUnit = JsonConvert.DeserializeObject<List<BatchingUintDto>>(resUnit.data.ToString());
                    var batchingUnitinfo = GetDynamic(dataUnit, DynamicObject.batchingUnitinfo[0]);
                    DynamicObject.batchingUnitinfo = JsonConvert.DeserializeObject<dynamic>(JsonConvert.SerializeObject(batchingUnitinfo));
                }
                return DynamicObject;
            }
            catch (Exception)
            {
                throw Oops.Oh("解析数据失败");
            }

        }
        private async Task<dynamic> GetGoodsTechnology(string data, string deviceId, string productFunctionData)
        {
            try
            {
                //商品工艺信息
                var goodsTechnologData = JsonConvert.DeserializeObject<List<GoodsTechnologysDto>>(data);

                var cpjson = productFunctionData.Replace("\r", "").Replace("\n", "").Replace("\t", "");
                var DynamicObject = JsonConvert.DeserializeObject<dynamic>(cpjson);
                if (IsPropertyExist(DynamicObject, ProductParametersConst_Technology.technologysInfo))
                {
                    //获取工艺基础信息
                    var gettechnologurl = BaseServerUrl + "api/technology/gettechnologylist_alm?deviceId=" + deviceId;//获取工艺基础信息
                    var responsegetTechnologurl = await gettechnologurl.SetHeaders(new
                    {
                        groupId = App.User?.FindFirst(ClaimConst.GroupId)?.Value
                    }).SetHttpMethod(HttpMethod.Get).GetAsStringAsync();
                    var resTechnolog = JsonConvert.DeserializeObject<ResponDataBase>(responsegetTechnologurl);
                    if (resTechnolog.statusCode != "200") throw Oops.Oh("获取工艺基础信息数据失败");
                    var dataTechnolog = JsonConvert.DeserializeObject<List<TechnologyDto>>(resTechnolog.data.ToString());
                    var technologysInfo = GetDynamic(dataTechnolog, DynamicObject.technologysInfo[0]);
                    DynamicObject.technologysInfo = JsonConvert.DeserializeObject<dynamic>(JsonConvert.SerializeObject(technologysInfo));
                }
                if (IsPropertyExist(DynamicObject, ProductParametersConst_Technology.goodsTechnologysInfo))
                {
                    var goodsTechnologysInfo = GetDynamic(goodsTechnologData, DynamicObject.goodsTechnologysInfo[0]);
                    DynamicObject.goodsTechnologysInfo = JsonConvert.DeserializeObject<dynamic>(JsonConvert.SerializeObject(goodsTechnologysInfo));
                }
                return DynamicObject;
            }
            catch (Exception)
            {
                throw Oops.Oh("解析数据失败");
            }

        }
        /// <summary>
        /// 映射数据
        /// </summary>
        /// <param name="data1"></param>
        /// <param name="data2"></param>
        /// <returns></returns>
        private List<Dictionary<string, object>> GetDynamic(dynamic data1, dynamic data2)
        {
            List<Dictionary<string, object>> objws = new();
            foreach (var item in data1)
            {
                PropertyInfo[] properties = item.GetType().GetProperties(); // 获取所有公共属性
                Dictionary<string, object> objw = new();
                foreach (var property in properties)
                {
                    object value = property.GetValue(item);


                    foreach (var property1 in data2)
                    {

                        if (property.Name.ToLower() == property1?.Name?.ToLower())
                        {
                            Type dataType = property.PropertyType;
                            if (dataType.IsGenericType)
                            {
                                var sd = data2[property1.Name][0];
                                objw.Add(property1.Name, GetDynamic(value, sd));
                            }
                            else
                            {
                                objw.Add(property1.Name, value);
                            }
                        }
                    }
                }
                objws.Add(objw);
            }
            return objws;
        }
        /// <summary>
        /// 验证属性是否存在
        /// </summary>
        /// <param name="data"></param>
        /// <param name="propertyname"></param>
        /// <returns></returns>
        private bool IsPropertyExist(dynamic data, string propertyname)
        {
            var check = false;
            var sd = data.GetType().GetProperty(propertyname);
            foreach (var property1 in data)
            {
                if (property1.Name == propertyname) check = true;
            }
            return check;
        }
    }
}
