using CommunityToolkit.Mvvm.ComponentModel;
using System;
using System.Collections.ObjectModel;
using log4net;
using Aucma.Core.CodeBinding.Common;
using LiveCharts;
using Admin.Core.Model;
using Admin.Core.Service;
using LiveCharts.Wpf;
using Admin.Core.IService;
using Microsoft.Extensions.DependencyInjection;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Collections;
using Aucma.Core.CodeBinding.Models;
using System.Reflection.Emit;
using NPOI.SS.Formula.Functions;
using System.Threading;
using System.Windows.Threading;
using static Admin.Core.Service.CodeBindingRecordServices;
using System.Windows.Data;
using System.Windows;
using System.Linq;
using Aucma.Core.Scanner;
using System.Collections.Generic;
using NPOI.HSSF.Record;
using SqlSugar;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Admin.Core.Model.ViewModels;
using System.Windows.Media;
using System.Drawing;
using Brushes = System.Windows.Media.Brushes;
using Admin.Core.Model.Model_New;
using Microsoft.IdentityModel.Logging;
using static Npgsql.Replication.PgOutput.Messages.RelationMessage;
using Aucma.Core.HwPLc;
using System.Windows.Documents;
/*
* 首页信息
*/
namespace Aucma.Core.CodeBinding.ViewModels
{
    public partial class IndexPageViewModel : ObservableObject
    {
        private static readonly log4net.ILog log = LogManager.GetLogger(typeof(IndexPageViewModel));
        private readonly ICodeBindingRecordServices? _codeBindingRecordServices;
        private readonly IBaseMaterialInfoServices? _baseMaterialInfoServices;
        private readonly IBaseBomInfoServices? _baseBomInfoServices;
        
        private readonly IPrintBarCodeServices? _printBarCodeServices;
        // 过点数据表,物料完成记录MaterialCompletion
        private readonly IMaterialCompletionServices? _iMaterialCompletionServices;
        // 静态变量存code1
        private static string code1Str = string.Empty;

        // 静态变量存code2
        private static string code2Str = string.Empty;

    
        public IndexPageViewModel()
        {
            try
            {
                _codeBindingRecordServices = App.ServiceProvider.GetService<ICodeBindingRecordServices>();
                _baseBomInfoServices = App.ServiceProvider.GetService<IBaseBomInfoServices>();
                _baseMaterialInfoServices = App.ServiceProvider.GetService<IBaseMaterialInfoServices>();
               
                _printBarCodeServices = App.ServiceProvider.GetService<IPrintBarCodeServices>();
                _iMaterialCompletionServices = App.ServiceProvider.GetService<IMaterialCompletionServices>();
                MvCodeHelper.ReceiveCode1Event += receiveCode1;
                MvCodeHelper.ReceiveCode2Event += receiveCode2;
                LoadData();
                add();
                //实时绑定条码和实时下发plc放行信号
                realBindingAndSendPlc();

                Task.Run(() =>
                {
                    Thread.Sleep(3000);
                    receiveCode1("B24010181060282920002");
                    Thread.Sleep(2000);
                    receiveCode2("16160030000000910780");

                });

            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        /// <summary>
        /// 实时绑定条码和实时下发plc放行信号
        /// </summary>
        public void realBindingAndSendPlc()
        {
            string tempCode1 ;
            string tempCode2;
            // 实时绑定条码
            Task.Run(() =>
            {
                while(true)
                {
                    try
                    {
                        if (!string.IsNullOrEmpty(code1Str) && !string.IsNullOrEmpty(code2Str))
                        {
                            tempCode1 = code1Str;
                            tempCode2 = code2Str;
                            code1Str = string.Empty;
                            code2Str = string.Empty;
                            BindingCode(tempCode1, tempCode2);
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.ToString());
                    }
                    Thread.Sleep(500);
                }
            });
         
            // 实时下发plc放行信号
            Task.Run(() =>
            {
                try
                {
                    while (true)
                    {
                        Thread.Sleep(3000);
                        var obj = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("条码绑定Plc"));
                        if (obj != null && obj.plc.IsConnected)
                        {
                            CodeBindingRecord record = _codeBindingRecordServices.FirstAsync(x => x.isPlcPass == 1 && x.RecordTime2 >= System.DateTime.Now.AddDays(-1)).Result;
                            if (record != null)
                            {
                                // 下发plc放行信号
                                RefreshAndWriteLog($"条码[{record.BoxCode}]下发plc放行信号,等待plc反馈...");
                                if (SendPlcPass(obj))
                                {
                                    RefreshAndWriteLog($"条码[{record.BoxCode}]放行成功");
                                    record.isPlcPass = 2;
                                   _ = _codeBindingRecordServices.UpdateAsync(record).Result;
                                    LoadData();
                                }
                                else
                                {
                                    RefreshAndWriteLog("等待Plc反馈信号5秒超时!");
                                }
                            }
                        }
                        Thread.Sleep(1000);
                    }
                }
                catch (Exception ex)
                {
                    log.Error(ex.ToString());
                }
            });

        }
    
     
        #region 加载DataGrid数据
        private async void LoadData()
        {
            try
            {
                ListItems.Clear();
                //// 赋值
                //Code1 = "B236000007811023002";
                ////  Code1Time = "2023-10-23 16:05:23";
                //Code2 = "B236000007811023002";
                ////  Code2Time = "2023-10-23 16:05:23";
                //BindingInfo = "条码[B236000007811023002]和SN条码[B236000007811023002]绑定成功!";
                LoadCharts();
               
                List<CodeBindingRecord> records = null;
                records = await _codeBindingRecordServices.QueryAsync(x => x.BoxCode != null && x.RecordTime2 >= System.DateTime.Now.AddDays(-1), "RECORD_TIME2 desc");
                if (records != null)
                {
                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        foreach (CodeBindingRecord record in records)
                        {
                            ListItems.Add(new ReaderInfo() { No = ListItems.Count + 1, BoxCode = record.BoxCode, ProductCode = record.ProductCode, BoxName = record.BoxName, BindingResult = record.BindingResult, IsPlcPass = record.isPlcPass == 2 ? "plc放行成功" : "待放行", RecordTime = record.RecordTime2.ToString() });
                        }
                    });
                }
            }
            catch (Exception)
            {
            }
        }
        // 修改为统计近一天白班或夜班
        private async void LoadCharts()
        {
            try
            {
                App.Current.Dispatcher.Invoke( () =>
                   {
                       ProductionHourList = new List<string>();
                       List<CodeBindCharts> list =  _codeBindingRecordServices.QueryCharts().Result;
                       // 图表赋值
                       ChartValues<double> achievement = new ChartValues<double>();
                       List<string> chartList = new List<string>();
                       if (list == null) return;

                       foreach (CodeBindCharts item in list)
                       {
                           achievement.Add(item.Amount);

                           ProductionHourList.Add(item.BoxName.Substring(0, Math.Min(7, item.BoxName.Length)));
                      
                       }
                       var column = new ColumnSeries();
                       column.DataLabels = true;
                       column.Title = "型号";
                       column.Values = achievement;
                       column.Foreground = Brushes.White;


                       if (ModelStatistics.Count>0 && ModelStatistics.FirstOrDefault().Values.Count == achievement.Count)
                       {
                           for (int i = 0; i < achievement.Count(); i++)
                           {
                               ModelStatistics.FirstOrDefault().Values[i] = achievement.ElementAt(i);
                           }
                       }
                       else
                       {
                           ModelStatistics.Clear();
                           ModelStatistics.Add(column);
                       }


                   });
            }
            catch (Exception)
            {

                throw;
            }
           
           
        }
        // 测试方法
        private async void add()
        {
            //DateTime startTime = DateTime.Now;
            //Thread.Sleep(5000);

            //TimeSpan elapsedTime = DateTime.Now - startTime;
            //Console.WriteLine(elapsedTime.TotalSeconds);
           

       
        }

        #endregion

        #region 参数定义
        /// <summary>
        /// 条码1
        /// </summary>
        private string code1 = string.Empty;
        public string Code1
        {
            get { return code1; }
            set
            {
                code1 = value;
                OnPropertyChanged(nameof(Code1));
            }
        }

        /// <summary>
        /// 条码1扫描时间
        /// </summary>
        private string code1Time = string.Empty;
        public string Code1Time
        {
            get { return code1Time; }

            set
            {
                code1Time = value;
                OnPropertyChanged(nameof(Code1Time));
            }
        }
        /// <summary>
        /// 条码2
        /// </summary>
        private string code2 = string.Empty;
        public string Code2
        {
            get { return code2; }
            set
            {
                code2 = value;
                OnPropertyChanged(nameof(Code2));
            }
        }
        ///// <summary>
        ///// 条码2扫描时间
        ///// </summary>
        private string code2Time = string.Empty;
        public string Code2Time
        {
            get { return code2Time; }
            set
            {
                code2Time = value;
                OnPropertyChanged(nameof(Code2Time));
            }
        }

        /// <summary>
        /// 绑定提示信息
        /// </summary>
        private string bindingInfo = string.Empty;
        public string BindingInfo
        {
            get { return bindingInfo; }
            set
            {
                bindingInfo = value;
                OnPropertyChanged(nameof(BindingInfo));
            }
        } 

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

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

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

        public SeriesCollection ModelStatistics
        {
            get { return modelStatistics; }
            set { modelStatistics = value; }
        }
        #endregion

        #endregion

        #region 初始化datagrid
        private ObservableCollection<ReaderInfo> listItems = new ObservableCollection<ReaderInfo>() { };
        public ObservableCollection<ReaderInfo> ListItems
        {
            get { return listItems; }
            set
            {
                listItems = value;
                OnPropertyChanged();//属性通知
            }
        }
        #endregion

     
       

        
        private async void receiveCode1(string code1)
        {
            log.Info("扫描到MES条码:" + code1);
            // 全局变量赋值,SN码扫描后使用
            code1Str = code1;
            RefreshCode1(code1);
            #region
            // 2.创建任务更新数据库条码1
            //  CodeBindingRecord codeRecord = new CodeBindingRecord();
            //   codeRecord.BoxCode = code1;
            //    codeRecord.BoxName = "去别的数据库查询";
            //List<BaseBomInfo> bomInfo = await _baseBomInfoServices.QueryAsync(x => x.MaterialCode == code);
            //string aa = bomInfo.FirstOrDefault().MaterialName; 

            //   codeRecord.RecordTime1 = time;
            // int a = await _codeBindingRecordServices.AddAsync(codeRecord);
            // 页面刷新ListItems
            //await Application.Current.Dispatcher.InvokeAsync(() =>
            //{
            //    // 在 UI 线程上操作列表
            //    ListItems.Insert(0, new ReaderInfo() { No = codeRecord.ObjId, BoxCode = codeRecord.BoxCode,  RecordTime = codeRecord.RecordTime1.ToString() });
            //});
            //log.Info("条码1记录更新");
            #endregion
        } 
       
        private async void receiveCode2(string code2)
        {
            log.Info("扫描到成品条码:" + code1);
            // 1.刷新界面条码信息
            // 全局变量赋值,SN码扫描后使用
            code2Str = code2;
            RefreshCode2(code2);  
        }


        private void RefreshCode1(string code1)
        {
            DateTime time = System.DateTime.Now;
            Code1 = code1;
            Code1Time = time.ToString();
        }


        private void RefreshCode2(string code2)
        {
            DateTime time = System.DateTime.Now;
            Code2 = code2;
            Code2Time = time.ToString();
            //    Code2 = record.ProductCode;
            ////    Code2Time = record.RecordTime2.ToString();
            //    if (record.isPlcPass==2)
            //    {
            //        BindingInfo = "条码【" + record.BoxCode + "】与SN码【" + record.ProductCode + "】绑定成功,下发Plc放行成功";
            //    }
            //    else
            //    {
            //        BindingInfo = "条码【" + record.BoxCode + "】与SN码【" + record.ProductCode + "】下发Plc放行失败";     
            //    }

            //    Application.Current.Dispatcher.Invoke(() =>
            //    {
            //       // ReaderInfo readerToUpdate = (ReaderInfo)ListItems.Select(item => item.No == 2);
            //        ListItems.Add(new ReaderInfo() { No = ListItems.Count+1, BoxCode = record.BoxCode, ProductCode = record.ProductCode, BoxName = record.BoxName,BindingResult = record.BindingResult, IsPlcPass = record.isPlcPass==2?"plc放行成功":"",RecordTime = record.RecordTime2.ToString() });
            //    });

        }

        /// <summary>
        ///  提示信息刷新并且存日志
        /// </summary>
        /// <param name="logStr"></param>
        private void RefreshAndWriteLog(string logStr)
        {
            TimeSpan currentTime = DateTime.Now.TimeOfDay;
          //  DateTime time = System.DateTime.Now;
            string timeString = currentTime.ToString(@"hh\:mm\:ss");
            BindingInfo = timeString + ":" + logStr;
            log.Info(BindingInfo);
        }


        public void BindingCode(string code1,string code2)
        {
            try
            {
                RefreshAndWriteLog("开始绑定MES条码:" + code1 + "  SN条码:" + code2);
                // 1.数据库查询各个工序质检结果,不合格报警


                // 2.查询条码绑定记录表(内胆箱壳绑定处就应该插入记录),绑定SN码
                CodeBindingRecord record = _codeBindingRecordServices.FirstAsync(x => x.BoxCode == code1).Result;
                if (record == null)
                {
                    RefreshAndWriteLog("未查询到MES条码记录,集存库未绑定箱壳内胆");
                    return;
                }

                BaseMaterialInfo materialInfo = _baseMaterialInfoServices.FirstAsync(x => x.MaterialCode == code1.Substring(7, 10)).Result;
                record.BoxName = materialInfo.MaterialName;
                record.ProductCode = code2;
                record.RecordTime1 = System.DateTime.Now;
                record.RecordTime2 = System.DateTime.Now;
                record.isPlcPass = 1;
                record.BindingResult = "成功";
                bool result = _codeBindingRecordServices.UpdateAsync(record).Result;
                if (result)
                {
                    RefreshAndWriteLog("条码【" + record.BoxCode + "】与SN码【" + record.ProductCode + "】绑定成功");
                    #region 更新过点数据,插入记录到MATERIAL_COMPLETION表
                    //PrintBarCode print =  _printBarCodeServices.FirstAsync(x => x.MaterialBarcode == code1).Result;
                    //if (print != null) return;
                    //MaterialCompletion completion = new MaterialCompletion();
                    //completion.OrderCode = print.OrderCode;
                    //completion.MaterialBarcode = code1;
                    //completion.MaterialCode = print.MaterialCode;
                    //completion.MaterialName = print.MaterialName;
                    //completion.StationName = "1007";
                    //completion.CompleteDate = DateTime.Now;
                    //completion.isDownLine = 0;
                    //completion.ProductLineCode = "CX_02";
                    //_= _iMaterialCompletionServices.AddAsync(completion).Result;

                    #endregion

                }

            }
            catch (Exception ex)
            {
                RefreshAndWriteLog(ex.Message.ToString());
            }
            finally
            {
                code1Str = string.Empty;
                code2Str = string.Empty;
            }
        }

        #region plc交互
 
        /// <summary>
        /// 下发plc放行信号
        /// </summary>
        /// <param name="materialType"></param>
        private bool SendPlcPass(PlcModel obj)
        {
            bool result = false;
            try
            {    
                
                 log.Info("D7100写1");
                 // 往plc写入放行信号
                 obj.plc.WriteInt16("D7100", "1");
                // 等待plc反馈信号
                result = waitPlcSignal(obj);
            }
            catch (Exception ex)
            {
                log.Error("下发plc放行信号方法SendPlcPass()出现异常,ex:" + ex);
            }
            return result;
        }
        /// <summary>
        /// 读取plc放行反馈
        /// </summary>
        /// <param name="materialType"></param>
        private bool waitPlcSignal(PlcModel obj)
        {
            bool result = false;
            try
            {
                DateTime startTime = DateTime.Now;
                bool isFlag = true;
               do
               {
                   if (obj.plc.ReadInt16("D7200") == 2)
                   {
                        log.Info("D7100读2");
                        
                       isFlag = false;
                       result = true;
                   }
                    TimeSpan elapsedTime = DateTime.Now - startTime;
                    if (elapsedTime.TotalSeconds >= 5)
                    {
                        isFlag = false;
                    }
                    Thread.Sleep(500);
               } while (isFlag);
            }
            catch (Exception ex)
            {
                log.Error("读取plc放行反馈方法waitPlcSignal()出现异常,ex:" + ex);
            }
            return result;
        }

        #endregion

    }
}