using GalaSoft.MvvmLight;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using SlnMesnac.Model.domain;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using GalaSoft.MvvmLight.Command;
using SlnMesnac.Business;
using SlnMesnac.Model.dto;
using SlnMesnac.Model.enums;
using SlnMesnac.WPF.Page;
using Newtonsoft.Json.Linq;
using System.Collections;
using Microsoft.IdentityModel.Logging;
using System.Windows.Documents;
using SlnMesnac.Common;
using HslCommunication.Profinet.GE;
using static System.Net.Mime.MediaTypeNames;
using Application = System.Windows.Application;
using LiveCharts;
using System.Threading;
using SlnMesnac.Repository.service;
using LiveCharts.Defaults;
using static MaterialDesignThemes.Wpf.Theme.ToolBar;
using LiveCharts.Wpf;
using System.Windows.Media;
using System.Windows.Threading;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using SlnMesnac.Config;

namespace SlnMesnac.WPF.ViewModel
{
    /// <summary>
    /// 生产管理ViewModel
    /// </summary>
    public class ProdMgmtViewModel : ViewModelBase
    {
        private readonly ILogger<ProdMgmtViewModel> _logger;

        private readonly ProdMgmtBusiness? _prodMgmtBusiness;

        private readonly PalletStowBusiness? _palletStowBusiness;

        private readonly IMesBaseBarcodeInfoService? _mesBaseBarcodeInfoService;

        private readonly ProdCompletionBusiness? _prodCompletionBusiness;

        private ObservableCollection<dynamic> listItems = new ObservableCollection<dynamic>();



        #region 参数定义

        #region 日产量柱状图X轴日期
        /// <summary>
        /// 日产量柱状图X轴日期
        /// </summary>
        private List<string> productionHourList = new List<string>();

        public List<string> ProductionHourList
        {
            get { return productionHourList; }
            set { productionHourList = value; }
        }
        #endregion

        #region 型号统计柱状图
        /// <summary>
        /// 型号统计柱状图
        /// </summary>
        private SeriesCollection achievement = new SeriesCollection();

        public SeriesCollection Achievement
        {
            get { return achievement; }
            set { achievement = value; }
        }
        #endregion

        /// <summary>
        /// 工位名称
        /// </summary>
        private string stationName = string.Empty;
        public string StationName
        {
            get { return stationName; }
            set { stationName = value; RaisePropertyChanged(nameof(StationName)); }
        }

        /// <summary>
        /// 订单编号
        /// </summary>
        private string orderCode = string.Empty;
        public string OrderCode
        {
            get { return orderCode; }
            set { orderCode = value; RaisePropertyChanged(nameof(OrderCode)); }
        }

        /// <summary>
        /// 计划编号
        /// </summary>
        private string planCode = string.Empty;
        public string PlanCode
        {
            get { return planCode; }
            set { planCode = value; RaisePropertyChanged(nameof(PlanCode)); }
        }

        /// <summary>
        /// 产品型号
        /// </summary>
        private string productModel = string.Empty;
        public string ProductModel
        {
            get { return productModel; }
            set { productModel = value; RaisePropertyChanged(nameof(ProductModel)); }
        }

        /// <summary>
        /// 开始时间
        /// </summary>
        private string beginTime = string.Empty;
        public string BeginTime
        {
            get { return beginTime; }
            set { beginTime = value; RaisePropertyChanged(nameof(BeginTime)); }
        }

        /// <summary>
        /// 计划数量
        /// </summary>
        private int planAmount = 0;
        public int PlanAmount
        {
            get { return planAmount; }
            set { planAmount = value; RaisePropertyChanged(nameof(planAmount)); }
        }

        /// <summary>
        /// 完成数量
        /// </summary>
        public int complateAmout;
        public int ComplateAmout
        {
            get { return complateAmout; }
            set { complateAmout = value; RaisePropertyChanged(nameof(ComplateAmout)); }
        }

        /// <summary>
        /// 差异值
        /// </summary>
        public int diffAmount;
        public int DiffAmount
        {
            get { return diffAmount; }
            set { diffAmount = value; RaisePropertyChanged(nameof(DiffAmount)); }
        }

        /// <summary>
        /// 完成率
        /// </summary>
        public decimal compleRoution;
        public decimal CompleRoution
        {
            get { return compleRoution; }
            set { compleRoution = value; RaisePropertyChanged(nameof(CompleRoution)); }
        }

        /// <summary>
        /// 计划列表DataGrid
        /// </summary>
        private ObservableCollection<MesProductPlanDto> planInfoDataGrid;

        public ObservableCollection<MesProductPlanDto> PlanInfoDataGrid
        {
            get { return planInfoDataGrid; }
            set { planInfoDataGrid = value; RaisePropertyChanged(() => PlanInfoDataGrid); }
        }

        /// <summary>
        /// LisBox数据模板
        /// </summary>
        private IEnumerable logInfoListBox;
        public IEnumerable LogInfoListBox
        {
            get { return logInfoListBox; }
            set { logInfoListBox = value; RaisePropertyChanged(() => LogInfoListBox); }
        }
        #endregion


     

        #region 事件定义

        /// <summary>
        /// 开始执行生产计划
        /// </summary>
        public RelayCommand<string> StartProdPlanCommand { get; set; }

        /// <summary>
        /// 暂停生产计划
        /// </summary>
        public RelayCommand<string> StopProdPlanCommand { get; set; }
        #endregion

        public ProdMgmtViewModel()
        {

            StartProdPlanCommand = new RelayCommand<string>(obj => StartProdPlan(obj));
            StopProdPlanCommand = new RelayCommand<string>(obj => StopProdPlan(obj));
            _logger = App.ServiceProvider.GetService<ILogger<ProdMgmtViewModel>>();
            _prodMgmtBusiness = App.ServiceProvider.GetService<ProdMgmtBusiness>();
            _palletStowBusiness = App.ServiceProvider.GetService<PalletStowBusiness>();
            _prodCompletionBusiness = App.ServiceProvider.GetService<ProdCompletionBusiness>();
            _mesBaseBarcodeInfoService = App.ServiceProvider.GetService<IMesBaseBarcodeInfoService>();
            Task.Run(() =>
            {
                _prodMgmtBusiness.RefreshProdPlanListEvent += RefreshPlanDataGrid;
                _prodMgmtBusiness.MatPutInValidEvent += MatPutInValidHandleEvent;
                _prodMgmtBusiness.PrintMessageToListBoxEvent += PrintMessageToListBox;
                DevMonitorPage.PrintMessageToListBoxEvent += PrintMessageToListBox;
                _prodMgmtBusiness.InitProdPlan();
            });
         
            Task.Run(() =>
            {
                _prodCompletionBusiness.PrintMessageToListBoxEvent += PrintMessageToListBox;

                // _prodCompletionBusiness.Init();
            });
            Init();

        }

        private void Init()
        {
            RefreChart();
            DispatcherTimer _timer = new DispatcherTimer();
            _timer.Interval = TimeSpan.FromMinutes(5);
            _timer.Tick += Timer_Tick;
            _timer.Start();
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            RefreChart();
        }



        public void test()
        {
            // gunHelper.InstanceSerialPort();
            //  HttpHelper.JudgeAgvTaskComplete();
            // HttpHelper.SendAgvTask("20245603");
            //HttpHelper.JudgeAgvTaskComplete();
        }
        /// <summary>
        /// 刷新计划执行
        /// </summary>
        /// <param name="prodPlan"></param>
        private void RefreshPlanExec(MesProductPlanDto prodPlan)
        {
            if (prodPlan != null)
            {
                StationName = "磁悬";
                OrderCode = prodPlan.OrderCode;
                PlanCode = prodPlan.PlanCode;
                ProductModel = prodPlan.MaterialName;
                BeginTime = prodPlan.RealBeginTime==null?"": prodPlan.RealBeginTime.Value.ToString("yyyy-MM-dd HH:mm:ss");
                PlanAmount = Convert.ToInt32(prodPlan.PlanAmount);
                ComplateAmout = Convert.ToInt32(prodPlan.CompleteAmount);
                DiffAmount = Convert.ToInt32(prodPlan.PlanAmount) - Convert.ToInt32(prodPlan.CompleteAmount);
                CompleRoution = Math.Round((prodPlan.CompleteAmount / prodPlan.PlanAmount) * 100, 2);
            }
            else
            {
                OrderCode = string.Empty;
                PlanCode = string.Empty;
                ProductModel = string.Empty;
                BeginTime = string.Empty;
                PlanAmount = 0;
                ComplateAmout = 0;
                DiffAmount = 0;
                CompleRoution = 0;
            }
        }

        /// <summary>
        /// 刷新生产计划
        /// </summary>
        /// <param name="list"></param>
        private async void RefreshPlanDataGrid(List<MesProductPlanDto> list)
        {
            try
            {

                await App.Current.Dispatcher.BeginInvoke((Action)(() =>
                {
                    PlanInfoDataGrid = new ObservableCollection<MesProductPlanDto>();
                    if (list != null)
                    {
                        #region  按钮状态
                        // 假设初始状态所有计划的按钮状态
                        list.ForEach(plan =>
                        {
                            plan.StartEnable = true;
                            plan.StopEnable = false;
                        });

                        // 查找是否存在正在执行的计划
                        var executingPlan = list.FirstOrDefault(x => x.PlanStatus == PlanStatusEnum.已开始);
                        if (executingPlan != null)
                        {
                            // 如果有正在执行的计划，只有该计划的暂停按钮可以点击，其他计划的按钮都不能点击
                            foreach (var plan in list)
                            {
                                if (plan == executingPlan)
                                {
                                    plan.StopEnable = true; // 执行中的计划可以暂停
                                    plan.StartEnable = false;
                                }
                                else
                                {
                                    plan.StartEnable = false; // 其他计划不能开始
                                }
                            }
                        }
                        #endregion

                       
                        list.OrderByDescending(x => x.PlanStatus);
                        list.ForEach(
                        arg =>
                        {
                            if (arg.RealBeginTime!=null && arg.RealBeginTime.Value.Year<2000)
                            {
                                arg.RealBeginTime = null;
                            }
                            PlanInfoDataGrid.Add(arg);
                        });

                        var info = list.Where(x => x.PlanStatus == PlanStatusEnum.已开始).ToList();
                        if (info.Count > 0)
                        {
                            RefreshPlanExec(info.First());
                        }

                    }
                }));
                   
            }
            catch (Exception ex)
            {
                _logger.LogError($"生产计划刷新异常：{ex.Message}");
            }
        }

        /// <summary>
        /// 开始生产计划事件
        /// </summary>
        /// <param name="obj"></param>
        private void StartProdPlan(string obj)
        {
            try
            {
                //先检查是否有正在执行的计划
                var hasPlan = planInfoDataGrid.Where(x => x.PlanStatus == PlanStatusEnum.已开始).FirstOrDefault();
                if (hasPlan != null)
                {
                    var result = MessageBox.Show("有正在执行的计划，是否确认切换计划!", "确认", MessageBoxButton.YesNo);
                    if (result == MessageBoxResult.Yes)
                    {
                        hasPlan.PlanStatus = PlanStatusEnum.待执行;
                        _prodMgmtBusiness.UpdateProdPlan(hasPlan);
                      
                    }
                    else
                    {
                        return;
                    }
                }
                _logger.LogInformation($"开始执行{obj}计划");
                var info = planInfoDataGrid.Where(x => x.PlanCode == obj).First();
                if (info != null)
                {
                    info.PlanStatus = PlanStatusEnum.已开始;
                    info.RealBeginTime = DateTime.Now;
                    info.PlanBeginTime = DateTime.Now;
                }

                _prodMgmtBusiness.UpdateProdPlan(info);

                PrintMessageToListBox($"开始执行{obj}计划");

                this.RefreshPlanExec(info);
            }
            catch (Exception e)
            {
                _logger.LogError($"开始事件处理异常：{e.Message}");
            }
        }

        /// <summary>
        /// 暂停生产计划事件
        /// </summary>
        /// <param name="obj"></param>
        private void StopProdPlan(string obj)
        {
            try
            {
                _logger.LogInformation($"暂停执行{obj}计划");
                var info = planInfoDataGrid.Where(x => x.PlanCode == obj).First();
                if (info != null)
                {
                    info.PlanStatus = PlanStatusEnum.待执行;
                    //info.RealBeginTime = DateTime.Now;
                }

                PrintMessageToListBox($"暂停执行{obj}计划");

                _prodMgmtBusiness.UpdateProdPlan(info);

                this.RefreshPlanExec(null);
            }
            catch (Exception e)
            {
                _logger.LogError($"暂停事件处理异常：{e.Message}");
            }
        }

        /// <summary>
        /// 校验失败人工确认事件
        /// </summary>
        /// <param name="validType"></param>
        /// <param name="productPlan"></param>
        /// <param name="materialName"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        private bool MatPutInValidHandleEvent(int validType, MesProductPlan productPlan, string materialName, string msg)
        {
            var result = false;

            Application.Current.Dispatcher.Invoke(() =>
            {
                var alarmWindow = new SystemAlarmWindow();
                var viewModel = new SystemAlarmViewModel();
                viewModel.AlarmMsg = msg;
                viewModel.AlarmConfirmed += (sender, isConfirmed) =>
                {
                    result = isConfirmed;
                    alarmWindow.Close();
                };

                alarmWindow.DataContext = viewModel;

                alarmWindow.ShowDialog();
            });

            return result;
        }

        /// <summary>
        /// 系统运行日志输出
        /// </summary>
        /// <param name="message"></param>
        private async void PrintMessageToListBox(string message)
        {
            await Task.Run(() =>
            {
                try
                {
                    string formattedMessage = $"{DateTime.Now.ToString("HH:mm:ss.ss")} ==> {message}";

                    lock (listItems)
                    {
                        listItems.Add(formattedMessage);

                        while (listItems.Count > 120)
                        {
                            listItems.RemoveAt(0);
                        }

                        var orderedList = listItems.OrderByDescending(x => x).ToList();  // 排序后转为 List
                        Application.Current.Dispatcher.Invoke(() =>
                        {
                            LogInfoListBox = orderedList;  // 更新 UI
                        });
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError($"日志数据绑定异常:{ex.Message}");
                }
            });
        }


        /// <summary>
        /// 刷新产量统计图表
        /// </summary>
        private async void RefreChart()
        {
            try
            {
                await Task.Run(() =>
                {
                    ProductionHourList = new List<string>() { "8:00", "9:00", "10:00", "11:00", "12:00", "13:00", "14:00", "15:00", "16:00", "17:00", "18:00", "19:00" };
                    List<MesBaseBarcodeInfo> list = _mesBaseBarcodeInfoService.Query(x => x.bindTime != null && x.bindTime >= DateTime.Now.Date && x.bindTime <= DateTime.Now.AddDays(1)).ToList();
                    if (list != null && list.Count > 0)
                    {
                        
                        Dictionary<string, int> hourProductionCount = new Dictionary<string, int>();
                        // 初始化字典，每个小时的产量初始为0
                        foreach (var hour in ProductionHourList)
                        {
                            hourProductionCount[hour] = 0;
                        }

                        // 遍历查询结果，统计每个小时的产量
                        foreach (var item in list)
                        {
                            // 获取 bindTime 的小时部分
                            string hour = item.bindTime.Value.ToString("H:00");

                            // 如果小时在 ProductionHourList 中，则统计该小时的产量
                            if (hourProductionCount.ContainsKey(hour))
                            {
                                hourProductionCount[hour]++;
                            }
                        }
                        Application.Current.Dispatcher.Invoke(() =>
                        {
                            Achievement.Clear();
                            ChartValues<ObservablePoint> achievement = new ChartValues<ObservablePoint>();
                            int i = 0;
                            foreach (var kvp in hourProductionCount)
                            {
                                achievement.Add(new ObservablePoint(i++, kvp.Value));
                            }
                            //加一个汇总柱状图
                            ProductionHourList.Add("合计");
                            achievement.Add(new ObservablePoint(i, list.Count));

                            var column = new ColumnSeries();
                            column.DataLabels = true;
                            column.Title = "小时产量";
                            column.Values = achievement;
                            column.Foreground = Brushes.White;
                            Achievement.Add(column);

                        });
                    }
                    else
                    {
                        // ProductionHourList.Clear();
                        Achievement.Clear();
                    }
                });
              
            }catch(Exception ex)
            {
                _logger.LogError($"产量统计图表异常:{ex.Message}");
                
            }
        }
    }
}
