using BPA.Model.Recipe;
using BPA.SingleDevice.Services;
using System.Collections.Immutable;
using System.Linq;
using System.Windows;

namespace BPA.SingleDevice.ViewModel
{
    public class OrderMainViewModel : NotifyBase
    {
        private readonly ILogService logService;
        private readonly GlobalData global;

        public OrderMainViewModel(ILogService logService, GlobalData global)
        {
            this.logService = logService;
            this.global = global;
            Task.Run(() =>
            {
                SqlHelper.GetInstance.GetListAsync<RecipeTB>().Result.OnSuccess(s =>
                {
                    App.Current.Dispatcher.Invoke(() =>
                    {
                        s.ForEach(item =>
                        {
                            if (item.IsEnable)
                                Goods.Add(new RecipeModel() { Id = item.Id, Name = item.Name, Count = 1 });
                        });
                    });
                });
            });


            //RawMaters = SqlHelper.GetInstance.GetListAsync<RawMaterTB>().Result.Content;
            //RawMaters = SqlHelper.GetInstance.GetListAsync<MaterialTB>().Result.Content;

            DownRecipeCommand = new BPARelayCommand<object>(o =>
            {
                //var result = ActionManage.GetInstance.Send<bool>("CanIssueRecipe");
                var result = true;
                //if (result != null && result.IsSuccess && result.Content == true)
                if (result)
                {
                    if (o != null && !string.IsNullOrEmpty(o.ToString()))
                    {
                        if (MessageBoxR.ConfirmGlobal("是否下发配方？", "提示") == MessageBoxResult.Yes)
                        {
                            //GenerateRecipe(o.ToString()!);
                            GenerateRecipeAsync(o.ToString()!);
                        }
                    }
                    else
                    {
                        Message.Error("OrderMainView", "下发配方失败，输入的配方ID为Null或空，请联系人员检查后。");
                    }
                }
                else
                {
                    Message.Error("OrderMainView", "下发配方失败，当前有配方在执行工位【1】的配料流程，请检查后重试。");
                }
            });
        }

        //private List<MaterialTB> RawMaters = new List<MaterialTB>();
        //private List<RawMaterTB> RawMaters { get; set; } = new List<RawMaterTB>();
        /// <summary>
        /// 被启用的配方列表。
        /// </summary>
        public ObservableCollection<RecipeModel> Goods { get; set; } = new ObservableCollection<RecipeModel>();

        public BPARelayCommand<object> DownRecipeCommand { get; set; }

        //private void GenerateRecipe(string recipeID)
        //{
        //    if (string.IsNullOrEmpty(recipeID))
        //    {
        //        logService.LogDebugInfo($"解析配方数据失败，参数<recipeID>是Null或者Empty，在<OrderMainViewModel.GenerateRecipe()>中。");
        //    }
        //    else
        //    {
        //        //验证指定的配方号是否在配方列表中。
        //        var res = Goods.FirstOrDefault(p => p.Id == recipeID);
        //        var recipeName = res?.Name;
        //        if (res != null)
        //        {
        //            //该配方所有物料集合。
        //            List<RawMaterModel> allMaterial = new List<RawMaterModel>();
        //            //根据配方号获取所有的物料。
        //            SqlHelper.GetInstance.GetRawMaterIds(res.Id).Result.OnSuccess(s =>
        //            {
        //                s.ForEach(item =>
        //                {
        //                    var rmtb = RawMaters.FirstOrDefault(p => p.Id == item.RawMaterId);
        //                    if (rmtb != null)
        //                    {
        //                        allMaterial.Add(new RawMaterModel()
        //                        {
        //                            Weight = item.Weight,
        //                            DeviceNum = rmtb.DeviceNum,
        //                            Id = rmtb.Id,
        //                            LastModified = rmtb.LastModified,
        //                            Name = rmtb.Name,
        //                            WarehouseNum = rmtb.WarehouseNum,
        //                        });
        //                    }
        //                });
        //            });
        //            Dictionary<int, ushort[]> materialData = new();
        //            //根据设备和通道分类。
        //            var temp = allMaterial.GroupBy(p => p.DeviceNum);
        //            foreach (var device in temp)
        //            {
        //                ushort[] channelWeight = new ushort[14];
        //                //根据通道排序后的物料设备分组表。
        //                var orderedMaterial = device.OrderBy(p => p.WarehouseNum);
        //                for (int i = 0; i < 14; i++)
        //                {
        //                    var channel = orderedMaterial.FirstOrDefault(p => p.WarehouseNum == (i + 1));
        //                    if (channel is not null)
        //                    {
        //                        channelWeight[i] = (channel.Weight);
        //                    }
        //                    else
        //                    {
        //                        channelWeight[i] = 0;
        //                    }
        //                }
        //                materialData.Add(device.Key, channelWeight);
        //            }
        //            RecipeData recipeData = new(recipeID, recipeName, materialData);
        //            var str = recipeData.ToJson();
        //            for (int i = 0; i < res.Count; i++)
        //            {
        //                global.RecipeQueue.Enqueue(str.FromJSON<RecipeData>());
        //            }
        //            Message.SuccessGlobal($"下发配方【{recipeName}】，份数【{res.Count}】成功。");
        //            logService.LogUserInfo($"下发配方【{recipeName}】，份数【{res.Count}】成功。");
        //        }
        //        else
        //        {
        //            logService.LogRunInfo($"解析配方数据失败，未找到【{recipeID}】对应的配方。");
        //        }
        //    }
        //}

        private async void GenerateRecipeAsync(string recipeID)
        {
            if (string.IsNullOrEmpty(recipeID))
            {
                logService.LogDebugInfo($"解析配方数据失败，参数<recipeID>是Null或者Empty，在<OrderMainViewModel.GenerateRecipe()>中。");
            }
            else
            {
                //验证指定的配方号是否在配方列表中。
                var res = Goods.FirstOrDefault(p => p.Id == recipeID);
                var recipeName = res?.Name;
                if (res != null)
                {
                    //该配方所有物料集合。
                    List<RawMaterModel> allMaterial = new List<RawMaterModel>();
                    //根据配方号获取所有的物料。
                    var getMaterialList= await SqlHelper.GetInstance.GetRawMaterIds(res.Id);
                    #region 判断所有需要的物料都已经被绑定在设备通道了
                    List<string> allNeedMaterialCode = new();
                    getMaterialList.OnSuccess((s) =>
                    {
                        allNeedMaterialCode.Clear();
                        foreach (var item in s)
                        {
                            allNeedMaterialCode.Add(item.RawMaterId);
                        }
                    });
                    //确保所有的物料都已经绑定在设备列表。
                    List<string> allbindedMaterialCode = new();
                    var bindedMaterials = await SqlHelper.GetInstance.GetListAsync<MaterialBindTB>();
                    bindedMaterials.OnSuccess((s) =>
                    {
                        allbindedMaterialCode.Clear();
                        foreach (var item in s)
                        {
                            allbindedMaterialCode.Add(item.MaterialCode);
                        }
                    });

                    var isAllHave = allNeedMaterialCode.All(allbindedMaterialCode.Contains);
                    #endregion

                    if (getMaterialList.IsSuccess&& bindedMaterials.IsSuccess && isAllHave)
                    {
                        if (getMaterialList.IsSuccess)
                        {
                            foreach (var item in getMaterialList.Content)
                            {
                                var rmtb = bindedMaterials.Content.FirstOrDefault(m => m.MaterialCode == item.RawMaterId);
                                if (rmtb != null)
                                {
                                    allMaterial.Add(new RawMaterModel()
                                    {
                                        DeviceNum = rmtb.DeviceNum,
                                        WarehouseNum = rmtb.WarehouseNum,
                                        Name = rmtb.MaterialName,
                                        Weight = item.Weight
                                    });
                                }
                            }
                        }

                        Dictionary<int, ushort[]> materialData = new();
                        //根据设备和通道分类。
                        var temp = allMaterial.GroupBy(p => p.DeviceNum);
                        foreach (var device in temp)
                        {
                            ushort[] channelWeight = new ushort[14];
                            //根据通道排序后的物料设备分组表。
                            var orderedMaterial = device.OrderBy(p => p.WarehouseNum);
                            for (int i = 0; i < 14; i++)
                            {
                                var channel = orderedMaterial.FirstOrDefault(p => p.WarehouseNum == (i + 1));
                                if (channel is not null)
                                {
                                    channelWeight[i] = (channel.Weight);
                                }
                                else
                                {
                                    channelWeight[i] = 0;
                                }
                            }
                            materialData.Add(device.Key, channelWeight);
                        }
                        RecipeData recipeData = new(recipeID, recipeName, materialData);
                        var str = recipeData.ToJson();
                        for (int i = 0; i < res.Count; i++)
                        {
                            global.RecipeQueue.Enqueue(str.FromJSON<RecipeData>());
                        }
                        Message.Success("OrderMainView", $"下发配方【{recipeName}】，份数【{res.Count}】成功。");
                        logService.LogUserInfo($"下发配方【{recipeName}】，份数【{res.Count}】成功。");
                    }
                    else
                    {
                        Message.Error("OrderMainView", $"下发配方【{recipeName}】失败，获取物料集合失败或非所有物料都绑定到设备中。");
                    }
                    
                }
                else
                {
                    logService.LogRunInfo($"解析配方数据失败，未找到【{recipeID}】对应的配方。");
                }
            }
        }
    }
}