using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using GalaSoft.MvvmLight;
using Microsoft.Extensions.DependencyInjection;
using Serilog;
using SlnMesnac.Common;
using SlnMesnac.Config;
using SlnMesnac.Model.domain;
using SlnMesnac.Model.dto;
using SlnMesnac.Model.Enum;
using SlnMesnac.Repository;
using SlnMesnac.Repository.service;
using SlnMesnac.Rfid;
using SlnMesnac.Rfid.Enum;
using SlnMesnac.Serilog;
using SlnMesnac.WPF.Attribute;
using SlnMesnac.WPF.Model;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Windows.Forms;
using System.Windows.Threading;
using TouchSocket.Core;
using TouchSocket.Sockets;
using static Microsoft.WindowsAPICodePack.Shell.PropertySystem.SystemProperties.System;
using Task = System.Threading.Tasks.Task;


namespace SlnMesnac.WPF.ViewModel.IndexPage
{
    [RegisterAsSingletonAttribute]
    public class ProductionLineViewModel : ViewModelBase
    {
        private static StringChange _StringChange;
        private String SerialNo = "";
        private SerilogHelper _logger;
        //容器里面的读写器集合
        public List<RfidAbsractFactory> rfidList;
        private AppConfig appConfig;
        private DispatcherTimer _timer;
        private ObservableCollection<RFIDRecord> _rfidHistoryRecords = new ObservableCollection<RFIDRecord>();
        private RealReadDataService dataService = RealReadDataService.Instance;

        #region 关联属性

        private ObservableCollection<Real_DataInfo> _Deviceinfo = new ObservableCollection<Real_DataInfo>();
        public ObservableCollection<Real_DataInfo> Deviceinfo
        {
            get { return _Deviceinfo; }
            set
            {
                _Deviceinfo = value;
                RaisePropertyChanged(() => Deviceinfo);
            }
        }

        public ObservableCollection<RFIDRecord> RFIDHistoryRecords
        {
            get { return _rfidHistoryRecords; }
            set
            {
                _rfidHistoryRecords = value;
                RaisePropertyChanged(() => RFIDHistoryRecords);
            }
        }

        /// <summary>
        /// 日期时间
        /// </summary>
        private DateTime _currentDateTime;
        public DateTime CurrentDateTime
        {
            get => _currentDateTime;
            set
            {
                if (_currentDateTime != value)
                {
                    _currentDateTime = value;
                    RaisePropertyChanged(() => CurrentDateTime);
                }
            }
        }

        /// <summary>
        /// 上一次写入状态
        /// </summary>
        private string _lastWriteState;
        public string LastWriteState
        {
            get => _lastWriteState;
            set
            {
                if (_lastWriteState != value)
                {
                    _lastWriteState = value;
                    RaisePropertyChanged(() => LastWriteState);
                }
            }
        }

        /// <summary>
        /// RFID连接状态
        /// </summary>
        private string _rfidConnectState;
        public string RFIDConnectState
        {
            get => _rfidConnectState;
            set
            {
                if (_rfidConnectState != value)
                {
                    _rfidConnectState = value;
                    RaisePropertyChanged(() => RFIDConnectState);
                }
            }
        }

        public RelayCommand<object> GetOrderInfoCommand { get; set; }

        #endregion

        public ProductionLineViewModel()
        {
            GetOrderInfoCommand = new RelayCommand<object>(t => RefreshData(t));
            // 构造函数里注册
            WeakReferenceMessenger.Default.Register<Real_DataInfo>(this, RefreshOrderNo);
            _StringChange = App.ServiceProvider.GetService<StringChange>();
            _logger = App.ServiceProvider.GetService<SerilogHelper>();
            appConfig = App.ServiceProvider.GetService<AppConfig>();
            rfidList = App.ServiceProvider.GetRequiredService<List<RfidAbsractFactory>>();

            rfidList.ForEach(rfid =>
            {
                rfid._Action += RecvIdentifyData_Instance;
                //rfid._RefreshLogMessageAction += RefreshLogMessage;
            });
            LoadDeviceInfo();
            StartCheckStatus();
            //GetRFIDHistoryRecords();
            _currentDateTime = DateTime.Now;
            _timer = new DispatcherTimer
            {
                Interval = TimeSpan.FromSeconds(1) // 每秒更新一次
            };
            _timer.Tick += (s, e) =>
            {
                CurrentDateTime = DateTime.Now;
            };
            _timer.Start();
            Log.Information("RFID输送带系统启动");
        }

        private void RefreshData(object? t)
        {
            Random random = new Random();
            string ss = random.Next(10, 99).ToString();
            string EPCstring = "JSSD" + ss;
            List<TagInfo> tagInfos = new List<TagInfo>();
            TagInfo tagInfo = new TagInfo()
            {
                EPCstring = "JSSD" + ss,
                EPC = Encoding.ASCII.GetBytes(EPCstring),
            };
            tagInfos.Add(tagInfo);

            Deviceinfo.FirstOrDefault(x => x.Deviceid == "10001").RfidEPC = _StringChange.bytesToHexStr(tagInfos[0].EPC, tagInfos[0].EPC.Length);
            Deviceinfo.FirstOrDefault(x => x.Deviceid == "10001").RfidASCII = EPCstring;
            Deviceinfo.FirstOrDefault(x => x.Deviceid == "10001").WriteStatus = "成功";
            Deviceinfo.FirstOrDefault(x => x.Deviceid == "10001").ReadTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            Deviceinfo.FirstOrDefault(x => x.Deviceid == "10001").WriteTime = DateTime.Now.AddMinutes(1).ToString("yyyy-MM-dd HH:mm:ss");
            RecvIdentifyData_Instance("10001", tagInfos);
        }



        private void RefreshOrderNo(object recipient, Real_DataInfo real_Data)
        {
            //查询当前订单产线最大序列号
            List<real_readdata> real_Readdatas = dataService.Helper.Query(x => x.orderno == real_Data.OrderNo && x.lineno == real_Data.LineNo);
            string SNo = "";
            if (real_Readdatas.Count > 0)
            {
                SNo = real_Readdatas.Max(x => x.serialno);
                SNo = (Convert.ToInt32(SNo) + 1).ToString("D2");
            }
            else
            {
                SNo = "1";
            }
            Deviceinfo.FirstOrDefault(x => x.Deviceid == real_Data.Deviceid).SerialNo = Convert.ToInt32(SNo).ToString("D2");
            Deviceinfo.FirstOrDefault(x => x.Deviceid == real_Data.Deviceid).OrderNo = real_Data.OrderNo;
            Deviceinfo.FirstOrDefault(x => x.Deviceid == real_Data.Deviceid).ProductType = real_Data.ProductType;
            Deviceinfo.FirstOrDefault(x => x.Deviceid == real_Data.Deviceid).LineNo = real_Data.LineNo;
            Deviceinfo.FirstOrDefault(x => x.Deviceid == real_Data.Deviceid).RfidCount = real_Data.RfidCount;
            Deviceinfo.FirstOrDefault(x => x.Deviceid == real_Data.Deviceid).NextProductNo = real_Data.NextProductNo;

            rfidList.FirstOrDefault(x => x.deviceid == real_Data.Deviceid).Set_BeginIdentify().GetAwaiter().GetResult();
        }

        private void LoadDeviceInfo()
        {
            List<DeviceInfoConfig> DeviceInfos = appConfig.deviceInfoConfig.Where(x => x.Collectid == appConfig.StationCode && x.Deleteflag == 0).ToList();
            List<Real_DataInfo> real_DataInfos = new List<Real_DataInfo>();

            foreach (var item in DeviceInfos)
            {
                Real_DataInfo real_DataInfo = new Real_DataInfo()
                {
                    Name = item.Name,
                    Deviceid = item.Deviceid,
                    Connectstr = item.Connectstr,
                    LineName = item.Name,
                    LineNo = item.Addr,
                    OrderNo = "",
                    ProductType = "",
                    WriteCount = "",
                    RfidCount = "",
                    IsOnline = "未连接",
                    RfidASCII = "",
                    RfidEPC = "",
                    ReadTime = "",
                    WriteTime = "",
                    ProductStatus = "",
                    WriteStatus = "",
                };
                real_DataInfos.Add(real_DataInfo);

            }
            App.Current.Dispatcher.Invoke(() =>
            {
                Deviceinfo.Clear();

                foreach (var item in real_DataInfos)
                {
                    Real_DataInfo real_DataInfo = new Real_DataInfo()
                    {
                        Name = item.Name,
                        Deviceid = item.Deviceid,
                        Connectstr = item.Connectstr,
                        LineName = item.Name,
                        LineNo = item.LineNo,
                        OrderNo = item.OrderNo,
                        ProductType = item.ProductType,
                        WriteCount = item.WriteCount,
                        RfidCount = item.RfidCount,
                        IsOnline = item.IsOnline,
                        RfidASCII = item.RfidASCII,
                        ReadTime = item.ReadTime,
                        WriteTime = item.WriteTime,
                        ProductStatus = item.ProductStatus,
                        WriteStatus = item.WriteStatus,
                        RfidEPC = item.RfidEPC,
                    };
                    Deviceinfo.Add(real_DataInfo);
                }
            });
        }

        /// <summary>
        /// 接收到连续盘点标签返回
        /// </summary>
        /// <param name="iCombineId"></param>
        /// <param name="tagInfos"></param>
        private async void RecvIdentifyData_Instance(string iCombineId, List<TagInfo> tagInfos)
        {
            string info = "";
            try
            {
                if (string.IsNullOrEmpty(Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).OrderNo))
                {
                    MessageBox.Show("请先获取MES订单号！", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
                //读到停止连续盘点
                //bool stopflag = await rfidList.FirstOrDefault(x => x.deviceid == iCombineId).Set_StopIdentify();
                //查询数据库是否已存在记录
                bool iflag = false;
                string epcascii = Encoding.ASCII.GetString(tagInfos[0].EPC);
                epcascii = epcascii.Replace("\0", "");
                List<real_readdata> real_Readdatas = dataService.Helper.Query(x => x.rfidascii == epcascii);

                //如果不存在则写入
                if (real_Readdatas.Count <= 0)
                //if (true)
                {
                    if (string.IsNullOrEmpty(Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).SerialNo))
                    {
                        return;
                    }
                    Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).ReadTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                    //拼接订单号写入标签
                    string WriteData = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).OrderNo
                        + Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).LineNo
                        + DateTime.Now.ToString("yy")
                        + Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).NextProductNo
                        + Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).SerialNo;
                    //写入 三次重写
                    bool writeflag = await rfidList.FirstOrDefault(x => x.deviceid == iCombineId).Set_Write(tagInfos[0].EPC, WriteData);
                    if (!writeflag)
                    {
                        Log.Error($"第一次写入失败，重试中...");
                        writeflag = await rfidList.FirstOrDefault(x => x.deviceid == iCombineId).Set_Write(tagInfos[0].EPC, WriteData);
                        if (!writeflag)
                        {
                            Log.Error($"第二次写入失败，重试中...");
                            writeflag = await rfidList.FirstOrDefault(x => x.deviceid == iCombineId).Set_Write(tagInfos[0].EPC, WriteData);
                            if (!writeflag)
                            {
                                Log.Error($"第三次写入失败，立即开始重新盘点");
                                LastWriteState = "失败";
                                rfidList.FirstOrDefault(x => x.deviceid == iCombineId).Set_BeginIdentify().GetAwaiter().GetResult();
                                return;
                            }
                        }
                    }
                    Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).WriteTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                    Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).WriteStatus = "成功";
                    LastWriteState = "成功";
                    Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).RfidASCII = WriteData;
                    Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).RfidEPC = tagInfos[0].EPCstring;
                    Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).SerialNo = (Convert.ToInt32(Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).SerialNo) + 1).ToString("D2");
                    //保存写入记录
                    real_readdata real_Readdata = new real_readdata()
                    {
                        serialno = (Convert.ToInt32(Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).SerialNo) - 1).ToString("D2"),
                        orderno = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).OrderNo,
                        lineno = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).LineNo,
                        producttype = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).ProductType,
                        rfidepc = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).RfidEPC,
                        rfidascii = WriteData,
                        readtime = Convert.ToDateTime(Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).ReadTime),
                        writetime = Convert.ToDateTime(Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).WriteTime),
                        writestatus = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).WriteStatus
                    };

                    var a = dataService.Helper.Insert(real_Readdata);
                    //刷新界面
                    //Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).RfidASCII = Encoding.ASCII.GetString(tagInfos[0].EPC);
                    //Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).ReadTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                    //RefreshEventArgs(iCombineId, tagInfos);
                    AddRFIDData(iCombineId, tagInfos);
                }
                await Task.Run(async () =>
                {
                    await Task.Delay(1000);
                    await rfidList.FirstOrDefault(x => x.deviceid == iCombineId)!.Set_BeginIdentify();
                });
            }
            catch (Exception e)
            {
                Log.Error($"读结果准备写入时异常：{e.Message}");
            }
            finally
            {

            }
        }
        public void RefreshEventArgs(string iCombineId, List<TagInfo> tagInfos)
        {
            try
            {
                App.Current.Dispatcher.BeginInvoke((Action)(() =>
                {
                    Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).RfidEPC = tagInfos[0].EPCstring;
                    Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).RfidASCII = Encoding.ASCII.GetString(tagInfos[0].EPC);
                    Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).ReadTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                }));
            }
            catch (Exception ex)
            {
                Log.Information($"异常:{ex.Message}");
            }
        }
        // 添加数据的方法（核心：添加前/后判断行数）
        public void AddRFIDData(string iCombineId, List<TagInfo> tagInfos)
        {
            //// 1. 判断当前行数是否>10，是则清空
            //if (RFIDHistoryRecords.Count >= 10)
            //{
            //    RFIDHistoryRecords.Clear();
            //}

            App.Current.Dispatcher.Invoke(() =>
            {
                RFIDHistoryRecords.Insert(0, new RFIDRecord
                {
                    OrderNumber = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).OrderNo,
                    LineNumber = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).LineNo,
                    ProductType = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).ProductType,
                    OriginalEPC = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).RfidEPC,
                    RFIDCode = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).RfidASCII,
                    ReadTime = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).ReadTime,
                    WriteTime = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).ReadTime,
                    WriteStatus = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).WriteStatus // 模拟1条失败数据
                });
                //RFIDHistoryRecords.OrderByDescending(x => x.ReadTime).ToList();
            });
        }

        #region 心跳检测

        private void StartCheckStatus()
        {
            Task.Run(async () =>
            {
                while (true)
                {
                    try
                    {
                        #region RFID状态
                        //RefreshLogMessage("检测设备状态");
                        var batches = SplitListIntoBatches(rfidList, 10);
                        for (int i = 0; i < batches.Count; i++)
                        {
                            var currentBatch = batches[i];
                            // 显示当前批次信息（UI线程）
                            Console.WriteLine($"{DateTime.Now}开始检测第{i + 1}批（共{currentBatch.Count}个设备）\r\n");

                            // 异步检测当前批次的设备状态（不阻塞UI）
                            await DetectDeviceBatchAsync(currentBatch);

                            // 批次之间的间隔（最后一批无需等待）
                            if (i < batches.Count - 1)
                            {
                                Console.WriteLine($"{DateTime.Now}第{i + 1}批检测完成，共{batches.Count}批，等待{1000 / 1000}秒后检测下一批\r\n");
                                await Task.Delay(10);
                            }
                        }
                        #endregion RFID状态
                    }
                    catch (Exception ex)
                    {
                        Log.Information($"监听设备状态异常:{ex.Message}");
                    }
                    await Task.Delay(1000 * 20);
                }
            });
        }
        private List<List<RfidAbsractFactory>> SplitListIntoBatches(List<RfidAbsractFactory> sourceList, int batchSize)
        {
            var batches = new List<List<RfidAbsractFactory>>();
            for (int i = 0; i < sourceList.Count; i += batchSize)
            {
                // 截取每批的设备（最后一批可能不足10个）
                var batch = sourceList.Skip(i).Take(batchSize).ToList();
                batches.Add(batch);
            }
            return batches;
        }

        private async Task DetectDeviceBatchAsync(List<RfidAbsractFactory> batch)
        {
            // 并行检测当前批次的设备（可选，根据接口性能调整）
            var detectionTasks = batch.Select(device => DetectSingleDeviceAsync(device));
            // 等待当前批次所有设备检测完成
            await Task.WhenAll(detectionTasks);
        }
        private async Task DetectSingleDeviceAsync(RfidAbsractFactory device)
        {
            try
            {
                //基于心跳检测的断线重连机制
                if (GloalVar.HeartBeatRecoard.TryGetValue(device.deviceid, out var value))
                {
                    if (value.AddSeconds(15) < DateTime.Now)
                    {
                        await Reconnect(device);
                        RFIDConnectState = "已连接";
                    }
                }
                else
                {
                    await Reconnect(device);
                    RFIDConnectState = "已连接";
                    var res = false;
                    //无限获取心跳返回报文
                    Log.Information($"准备第一次获取心跳");
                    res = await device.Set_HeartBeat(5);
                }
            }
            catch (Exception ex)
            {
                Log.Information($"更新RFID状态异常:{ex.Message}", ex);
            }
        }

        /// <summary>
        /// 无限重连
        /// </summary>
        /// <param name="device"></param>
        /// <returns></returns>
        private async Task Reconnect(RfidAbsractFactory device)
        {
            var res = false;
            do
            {
                RFIDConnectState = "未连接";
                Log.Information($"[{device.deviceid}]:[{device.ip}:{device.port}]连接中...");
                res = await device.ConnectAsync(device.ip, device.port, device.deviceid);
            }
            while (!res);
        }

        #endregion
    }
}
