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 Aucma.Core.PLc;
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;
/*
* 首页信息
*/
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;
        // 静态变量存code1
        private static string code1Str = string.Empty;
        // 定时检测数据库有没有pad绑定未放行的数据
        System.Timers.Timer timer = new System.Timers.Timer(1000);
        public IndexPageViewModel()
        {
            _codeBindingRecordServices = App.ServiceProvider.GetService<ICodeBindingRecordServices>();
            _baseBomInfoServices = App.ServiceProvider.GetService<IBaseBomInfoServices>();
            _baseMaterialInfoServices = App.ServiceProvider.GetService<IBaseMaterialInfoServices>();
            MvCodeHelper.ReceiveCode1Event += receiveCode1;
            MvCodeHelper.ReceiveCode2Event += receiveCode2;
       //     pda手持检测plc放行定时器
       //     StartPlcTimer();
            LoadData();
            //receiveCode2("B23000000824");
        }

        /// <summary>
        /// 开启定时器定时读取数据库并下发plc放行信号
        /// </summary>
        private void StartPlcTimer()
        {
            if (!timer.Enabled)
            {
                timer.Elapsed += new System.Timers.ElapsedEventHandler(readDataSendPlc);
                timer.AutoReset = true;
                timer.Enabled = false;
                timer.Start();
            }

        }
        /// <summary>
        /// 定时读取plc扫码信号,放行完成反馈信号
        /// </summary>
        private async void readDataSendPlc(object source, System.Timers.ElapsedEventArgs e)
        {
            List<CodeBindingRecord> records =await  _codeBindingRecordServices.QueryAsync(x => x.isPlcPass == 1 && x.RecordTime2 >= System.DateTime.Now.AddDays(-1), "RECORD_TIME2 desc");
            if (records != null && records.Count>0)
            {
                CodeBindingRecord record = records[0];
                // 下发plc放行信号
                if (SendPlcPass())
                {
                    record.isPlcPass = 2;
                   await _codeBindingRecordServices.UpdateAsync(record);
                }

            }

        }

        #region 加载DataGrid数据
        private async void LoadData()
        {
            // 赋值
            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() });     
                }
                });
            }         
        }
        // 修改为统计近一天
        private async void LoadCharts()
        {
           List<CodeBindCharts>  list = await _codeBindingRecordServices.QueryCharts();
            // 图表赋值
            ChartValues<double> achievement = new ChartValues<double>();
            List<string> chartList = new List<string>();
          
            foreach(CodeBindCharts item in list)
            {
                achievement.Add(item.Amount);
                chartList.Add(item.BoxName);
            }
            var column = new ColumnSeries();
            column.DataLabels = true;
            column.Title = "型号";
            column.Values = achievement;
            column.Foreground = Brushes.White;
            ModelStatistics.Add(column);
            ProductionHourList = chartList;
            
           
        }
        // 测试方法
        private async  void add()
        {
            //String code = "9002006859";
            //List<BaseBomInfo> bomInfo = await _baseBomInfoServices.QueryAsync(x => x.MaterialCode == code);
            //string aa = bomInfo.FirstOrDefault().MaterialName;
            //Console.WriteLine(aa);
        }

        #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

        /// <summary>
        ///  code1扫码信息刷新
        /// </summary>
        /// <param name="materialType"></param>
        private void RefreshCode1(string code1, string time)
        {
            Code1 = code1;
       //     Code1Time = time;
        }

        /// <summary>
        ///  code2扫码信息及表格记录刷新
        /// </summary>
        /// <param name="materialType"></param>
        private void RefreshCode2(CodeBindingRecord record)
        {
            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>
        /// 条码绑定,条码1处理
        /// </summary>
        /// <param name="materialType"></param>
        private async void receiveCode1(string code1)
        {
            log.Info("进入条码1处理函数receiveCode1,code1:" + code1);
            DateTime time = System.DateTime.Now;
            string strTime = time.ToString();
            // 1.刷新界面条码信息
            // 全局变量赋值,SN码扫描后使用
            code1Str = code1;
            RefreshCode1(code1, strTime);
            #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
        }
        /// <summary>
        /// 条码绑定,条码2处理
        /// </summary>
        /// <param name="materialType"></param>
        private async void receiveCode2(string code2)
        {
            log.Info("进入条码2处理函数receiveCode1,code2:" + code2);
            // 取之前读出来的code1
            string code1 = code1Str;

            if (string.IsNullOrEmpty(code1))
            {
                // 刷新页面提示信息
                BindingInfo = "箱体码还未扫码";
                return;
            }

            // 1.数据库查询各个工序质检结果,不合格报警


            // 2.查询条码绑定记录表(内胆箱壳绑定处就应该插入记录),绑定SN码
            List<CodeBindingRecord> list = await _codeBindingRecordServices.QueryAsync(x=> x.BoxCode==code1);
            CodeBindingRecord record = list.FirstOrDefault();
             List<BaseMaterialInfo> materialInfoList = await _baseMaterialInfoServices.QueryAsync(x => x.MaterialCode == code2.Substring(2, 10));
             record.BoxName = materialInfoList.FirstOrDefault().MaterialName;
             record.ProductCode = code2;
             record.RecordTime1 = System.DateTime.Now;
             record.RecordTime2 = System.DateTime.Now;
             record.BindingResult = "成功";
            // 3.下发plc放行信号
            if (SendPlcPass())
            {
             record.isPlcPass = 2;
            }
            await _codeBindingRecordServices.UpdateAsync(record);
            // 2.刷新界面信息
            RefreshCode2(record);

            code1Str = string.Empty;

        }

        #region plc交互
 
        /// <summary>
        /// 下发plc放行信号
        /// </summary>
        /// <param name="materialType"></param>
        private bool SendPlcPass()
        {
            bool result = false;
            try
            {
                var obj = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("条码绑定Plc"));
                if (obj != null)
                {
                    if (obj.plc.IsConnected)
                    {
                        // 往plc写入放行信号
                        obj.plc.WriteInt32("D100", 1);
                        // 等待plc反馈信号
                        waitPlcSignal();
                        result = true;
                    }
                    else
                    {
                        log.Info("条码绑定plc连接失败,请检查plc连接");
                    }
                }
                else
                {
                    log.Info("获取plc连接对象信息为空");
                }
            }
            catch (Exception ex)
            {
                log.Error("下发plc放行信号方法SendPlcPass()出现异常,ex:" + ex);
            }
            return result;
        }
        /// <summary>
        /// 读取plc放行反馈
        /// </summary>
        /// <param name="materialType"></param>
        private void waitPlcSignal()
        {
            try
            {
                lock (string.Empty)
                {
                    bool isFlag = true;
                    var obj = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("条码绑定Plc"));
                        if (obj != null)
                        {
                            if (obj.plc.IsConnected)
                            {
                                do
                                {
                                    if (obj.plc.ReadInt32("D100") == 2)
                                    {
                                        Console.WriteLine("收到plc放行成功");
                                        obj.plc.WriteInt32("D100", 0);
                                        isFlag = false;
                                    }
                                    Thread.Sleep(1000);
                                } while (isFlag);
                            }
                            else
                            {
                                log.Info("条码绑定plc连接失败,请检查plc连接");
                            }
                        }
                        else
                        {
                            log.Info("获取plc连接对象信息为空");
                        }
                }
            }
            catch (Exception ex)
            {
                log.Error("读取plc放行反馈方法waitPlcSignal()出现异常,ex:" + ex);
            }
        }

        #endregion

    }
}