using Admin.Core.Common.Helper;
using Admin.Core.IService;
using Admin.Core.Model;
using Aucma.Core.BoxFoam.Models;
using Aucma.Core.BoxFoam.ViewModels;
using Aucma.Core.HwPLc;
using Microsoft.Extensions.DependencyInjection;
using NetTaste;
using NPOI.Util;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Documents;
using System.Windows.Forms;

namespace Aucma.Core.BoxFoam.Business
{
    /// <summary>
    /// 采集发泡机数据
    /// </summary>
    public class CollectionFoamMachine
    {
        /// <summary>
        /// 刷新最后一枪DATAGRID
        /// </summary>
        public delegate void RefreshLastShotDataDelegate(BoxLastShotRecord record);
        public static event RefreshLastShotDataDelegate RefreshLastShotDataDelegateEvent;

        /// <summary>
        /// 刷新每一枪数据
        /// </summary>
        public delegate void RefreshGunDataDelegate(Dictionary<string, BoxLastShotRecord> keys);
        public static event RefreshGunDataDelegate RefreshGunDataDelegateEvent;

        /// <summary>
        /// 刷新系统数据
        /// </summary>
        public delegate void RefreshSystemDataDelegate(Dictionary<string, FoamMachinesModel> keys);
        public static event RefreshSystemDataDelegate RefreshSystemDataDelegateEvent;

        private static System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
        List<FoamMachinesModel> foamMachinesList = new List<FoamMachinesModel>();

        Dictionary<string, BoxLastShotRecord> gunKeys = new Dictionary<string, BoxLastShotRecord>();
        Dictionary<string, BoxLastShotRecord> tempKeys = new Dictionary<string, BoxLastShotRecord>();
        // 系统参数
        Dictionary<string, FoamMachinesModel> systemKeys = new Dictionary<string, FoamMachinesModel>();
        Semaphore semaphore = new Semaphore(1, 1);

        private readonly IBoxLastShotRecordServices? _lastShotRecordServices = App.ServiceProvider.GetService<IBoxLastShotRecordServices>();


        public CollectionFoamMachine()
        {
            startCollect();
        }

        public void startCollect()
        {
            Task.Run(() =>
            {
                while (true)
                {
                    semaphore.WaitOne();
                    try
                    {
                        Thread.Sleep(3000);
                        var obj = PlcHelper.siemensList.FirstOrDefault(d => d.EquipName.Equals("foamMachinePlc"));
                        if (obj != null)
                        {
                            ReadEquipSystem(obj, "DB50.388", systemKeys, "1");  //采集1系统
                            ReadEquipSystem(obj, "DB50.642", systemKeys, "2"); //采集2系统

                            ReadGunData(obj, "DB50.896", gunKeys, "A1");  //A1枪数据
                            ReadGunData(obj, "DB50.1084", gunKeys, "B1");  //B1枪数据
                            ReadGunData(obj, "DB50.1272", gunKeys, "A2");  //A2枪数据
                            ReadGunData(obj, "DB50.1460", gunKeys, "B2");  //A2枪数据
                            RefreshSystemDataDelegateEvent?.Invoke(systemKeys);
                            RefreshGunDataDelegateEvent?.Invoke(gunKeys);

                            foreach (KeyValuePair<string, BoxLastShotRecord> kvPair in gunKeys)
                            {
                                //程序启动缓存没数据查数据库
                                if (!tempKeys.ContainsKey(kvPair.Key))
                                {
                                    BoxLastShotRecord record = _lastShotRecordServices.Query(x => x.System == kvPair.Value.System && x.ProductLineCode == kvPair.Value.ProductLineCode && x.GunCode == kvPair.Value.GunCode).OrderByDescending(x => x.CreateTime).FirstOrDefault();
                                    if (record == null)
                                    {
                                        kvPair.Value.ProductLineCode = "CX_02";
                                        kvPair.Value.StationNumber = "1005";
                                        // 数据库也没数据
                                        int a = _lastShotRecordServices.AddAsync(kvPair.Value).Result;
                                        RefreshLastShotDataDelegateEvent?.Invoke(kvPair.Value);
                                        continue;
                                    }
                                    tempKeys.Add(kvPair.Key, record);
                                }
                                if (!kvPair.Value.MixpistOff.Equals(tempKeys[kvPair.Key].MixpistOff))
                                {
                                    kvPair.Value.ProductLineCode = "CX_02";
                                    kvPair.Value.StationNumber = "1005";

                                    int b = _lastShotRecordServices.AddAsync(kvPair.Value).Result;
                                    RefreshLastShotDataDelegateEvent?.Invoke(kvPair.Value);
                                }


                            }
                        }

                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex);
                    }
                    finally
                    {

                        foreach (KeyValuePair<string, BoxLastShotRecord> kvp in gunKeys)
                        {
                            if (tempKeys.ContainsKey(kvp.Key))
                            {
                                // 键已存在,更新值
                                tempKeys[kvp.Key] = kvp.Value;
                            }
                            else
                            {
                                // 键不存在,添加键值对
                                tempKeys.Add(kvp.Key, kvp.Value);
                            }
                        }
                        //  tempKeys = gunKeys;
                        semaphore.Release();
                    }
                }

            });
        }

        /// <summary>
        /// 采集设备系统参数
        /// </summary>
        /// <returns></returns>
        static void ReadEquipSystem(HwPLc.PlcModel obj, string startStr, Dictionary<string, FoamMachinesModel> keys, string systemId)
        {
            if (obj == null || !obj.plc.IsConnected) return;
            if (obj.plc.IsConnected)
            {

                byte[] info = obj.plc.Read(startStr, 170);
                if (info == null) return;
                FoamMachinesModel model = new FoamMachinesModel();
                model.systemId = systemId;
               
                model.Machine_Status_0 = judgeStatus(ByteArrayToBinary(info.Skip(0).Take(1).ToArray())).ToString();
                model.Machine_Status_1 = judgeStatus(ByteArrayToBinary(info.Skip(1).Take(1).ToArray())).ToString();
                model.POL_Level = byteToFloat(info.Skip(2).Take(4).ToArray()).ToString("0.00") ; 

                model.POL_Temp = byteToFloat(info.Skip(14).Take(4).ToArray()).ToString("0.00");
                model.POL_LP = byteToFloat(info.Skip(18).Take(4).ToArray()).ToString("0.00");
                model.POL_HP = byteToFloat(info.Skip(22).Take(4).ToArray()).ToString("0.00");

                model.POL_Vol = byteToFloat(info.Skip(34).Take(4).ToArray()).ToString("0.00");
                model.POL_Usage = byteToFloat(info.Skip(38).Take(4).ToArray()).ToString("0.00");
                model.POL_Freq_Speed = byteToFloat(info.Skip(42).Take(4).ToArray()).ToString("0.00");

                model.ISO_Level = byteToFloat(info.Skip(82).Take(4).ToArray()).ToString("0.00");

                model.ISO_Temp = byteToFloat(info.Skip(94).Take(4).ToArray()).ToString("0.00");
                model.ISO_LP = byteToFloat(info.Skip(98).Take(4).ToArray()).ToString("0.00");
                model.ISO_HP = byteToFloat(info.Skip(102).Take(4).ToArray()).ToString("0.00");

                model.ISO_Vol = byteToFloat(info.Skip(114).Take(4).ToArray()).ToString("0.00");
                model.ISO_Usage = byteToFloat(info.Skip(118).Take(4).ToArray()).ToString("0.00");
                model.ISO_Freq_Speed = byteToFloat(info.Skip(122).Take(4).ToArray()).ToString("0.00");

                model.Hydr_Press = byteToFloat(info.Skip(162).Take(4).ToArray()).ToString("0.00");
                model.Hydr_Temp = byteToFloat(info.Skip(166).Take(4).ToArray()).ToString("0.00");

                model.collectTime = DateTime.Now;

                if (keys.ContainsKey(systemId))
                {
                    // 键已存在,更新值
                    keys[systemId] = model;
                }
                else
                {
                    // 键不存在,添加键值对
                    keys.Add(systemId, model);
                }
            }
        }

        /// <summary>
        /// 每一枪数据 ---A1,B1,A2,B2
        /// </summary>
        /// <returns></returns>
        static void ReadGunData(HwPLc.PlcModel obj, string startStr, Dictionary<string, BoxLastShotRecord> keys, string gunCode)
        {
            if (obj == null || !obj.plc.IsConnected) return;
            if (obj.plc.IsConnected)
            {
                byte[] info = obj.plc.Read(startStr, 88);
                if (info == null) return;
                BoxLastShotRecord lastShotRecord = new BoxLastShotRecord();
                lastShotRecord.System = gunCode.Substring(1, 1);
                lastShotRecord.GunCode = gunCode;
                if(lastShotRecord.System == "1")
                {
                    if(obj.plc.ReadBool("DB50.388.0"))
                    {
                        lastShotRecord.SystemStatus = 1;
                    }
                    else
                    {
                        lastShotRecord.SystemStatus = 0;
                    }
                }
                else
                {
                    if (obj.plc.ReadBool("DB50.642.0"))
                    {
                        lastShotRecord.SystemStatus = 1;
                    }
                    else
                    {
                        lastShotRecord.SystemStatus = 0;
                    }
                }
                lastShotRecord.ProductLineCode = "CX_02";

                lastShotRecord.PolTemp = byteToFloat(info.Skip(0).Take(4).ToArray()).ToString("0.00");
                lastShotRecord.PolHp = byteToFloat(info.Skip(4).Take(4).ToArray()).ToString("0.00");
                lastShotRecord.PolVol = byteToFloat(info.Skip(8).Take(4).ToArray()).ToString("0.00");
                lastShotRecord.PolUsage = byteToFloat(info.Skip(12).Take(4).ToArray()).ToString("0.00");
                lastShotRecord.IsoTemp = byteToFloat(info.Skip(16).Take(4).ToArray()).ToString("0.00");
                lastShotRecord.IsoHp = byteToFloat(info.Skip(20).Take(4).ToArray()).ToString("0.00");
                lastShotRecord.IsoVol = byteToFloat(info.Skip(24).Take(4).ToArray()).ToString("0.00");
                lastShotRecord.IsoUsage = byteToFloat(info.Skip(28).Take(4).ToArray()).ToString("0.00");

                lastShotRecord.PourNu = short.Parse(StringChange.bytesToHexStr(info.Skip(36).Take(2).ToArray(), 2), System.Globalization.NumberStyles.HexNumber).ToString();
                lastShotRecord.SetTime = int.Parse(StringChange.bytesToHexStr(info.Skip(38).Take(4).ToArray(), 4), System.Globalization.NumberStyles.HexNumber).ToString();
                lastShotRecord.SetWeight = byteToFloat(info.Skip(42).Take(4).ToArray()).ToString("0.00");
                lastShotRecord.SetRatio = byteToFloat(info.Skip(46).Take(4).ToArray()).ToString("0.00"); ;
                lastShotRecord.PourWeight = byteToFloat(info.Skip(50).Take(4).ToArray()).ToString("0.00");
                lastShotRecord.PourRatio = byteToFloat(info.Skip(54).Take(4).ToArray()).ToString("0.00");
                lastShotRecord.MpTime = int.Parse(StringChange.bytesToHexStr(info.Skip(58).Take(4).ToArray(), 4), System.Globalization.NumberStyles.HexNumber).ToString();
                lastShotRecord.HpTime = int.Parse(StringChange.bytesToHexStr(info.Skip(62).Take(4).ToArray(), 4), System.Globalization.NumberStyles.HexNumber).ToString();
                lastShotRecord.HydrPress = byteToFloat(info.Skip(66).Take(4).ToArray()).ToString("0.00");
                lastShotRecord.HydrTemp = byteToFloat(info.Skip(70).Take(4).ToArray()).ToString("0.00");
                lastShotRecord.MixpistOn = int.Parse(StringChange.bytesToHexStr(info.Skip(74).Take(4).ToArray(), 4), System.Globalization.NumberStyles.HexNumber).ToString();
                lastShotRecord.MixpistOff = int.Parse(StringChange.bytesToHexStr(info.Skip(78).Take(4).ToArray(), 4), System.Globalization.NumberStyles.HexNumber).ToString(); ;
                lastShotRecord.TotalYield = int.Parse(StringChange.bytesToHexStr(info.Skip(82).Take(4).ToArray(), 4), System.Globalization.NumberStyles.HexNumber).ToString(); ;
                lastShotRecord.PourEnd = judgeStatus(ByteArrayToBinary(info.Skip(87).Take(1).ToArray())).ToString();

                lastShotRecord.CreateTime = DateTime.Now;

                if (keys.ContainsKey(gunCode))
                {
                    // 键已存在,更新值
                    keys[gunCode] = lastShotRecord;
                }
                else
                {
                    // 键不存在,添加键值对
                    keys.Add(gunCode, lastShotRecord);
                }
            }
        }


        #region 字符工具转换方法
        /// byte[]转十进制ascii码
        /// </summary>
        /// <param name="bytes"></param>
        static string ByteArrayToString(byte[] bytes)
        {
            string result = string.Empty;
            foreach (byte b in bytes)
            {
                int decimalValue = Convert.ToInt32(b); // 将字节转换为十进制值
                result += decimalValue;
            }
            return result;
        }
        /// <summary>
        /// byte[]转二进制
        /// </summary>
        /// <param name="bytes"></param>
        static string ByteArrayToBinary(byte[] bytes)
        {
            StringBuilder binaryString = new StringBuilder();

            foreach (byte b in bytes)
            {
                binaryString.Append(Convert.ToString(b, 2).PadLeft(8, '0'));
            }

            // Console.WriteLine(binaryString);

            string reversedStr = new string(binaryString.ToString().Reverse().ToArray());
            // Console.WriteLine(reversedStr);

            return reversedStr;
        }

        /// <summary>
        /// 根据二进制字符串确定夹具状态  1正常生产 2暂停生产
        /// </summary>
        static int judgeStatus(string str1)
        {
            int item1 = 0;
            if (str1.Substring(0, 1) == "1")
            {
                item1 = 1;  //
            }
            else if (str1.Substring(1, 1) == "1")
            {
                item1 = 2; //
            }
            return item1;
        }


        /// <summary>
        /// byte数组转换为float
        /// </summary>
        static float byteToFloat(byte[] list)
        {
            float result = 0.00f;
            Array.Reverse(list);
            result = BitConverter.ToSingle(list, 0);
            return result;

        }

        #endregion
    }


}