using Admin.Core.Common.Helper;
using Admin.Core.IRepository;
using Admin.Core.IService;
using Admin.Core.Model;
using Admin.Core.Model.Model_New;

using Aucma.Core.HwPLc;
using Newtonsoft.Json;
using StackExchange.Profiling.Internal;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Aucma.Core.Tasks.Business
{
    /// <summary>
    /// 采集灌注数据
    /// </summary>
    public class PerfusionCollection
    {
        Semaphore semaphore = new Semaphore(1, 1);
        protected readonly IPerfusionRecordServices? _perfusionRecordServices;
        protected readonly IPerfusionAlarmServices? _perfusionAlarmServices;
        protected readonly IPerfusionDeviceStatusServices? _perfusionDeviceStatusServices;


        private static System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
        private Perfusion_Record record;
        private Perfusion_Record temprRecord;

        private Perfusion_DeviceStatus perfusion_DeviceStatus = new Perfusion_DeviceStatus();
        private Perfusion_Alarm perfusion_Alarm = new Perfusion_Alarm();
        public PerfusionCollection(IPerfusionRecordServices perfusionRecordServices, IPerfusionAlarmServices perfusionAlarmServices, IPerfusionDeviceStatusServices perfusionDeviceStatusServices)
        {
            _perfusionRecordServices = perfusionRecordServices;
            _perfusionAlarmServices = perfusionAlarmServices;
            _perfusionDeviceStatusServices = perfusionDeviceStatusServices;
            startCollect();
        }


        public void startCollect()
        {
            Task.Run(() =>
            {
                Thread.Sleep(3000);
                Console.WriteLine("灌注数据采集服务开启");
                var obj = PlcHelper.siemensList.FirstOrDefault(d => d.EquipName.Equals("PerfusionPlc"));
                if (obj != null)
                {  
                    while (true)
                    {
                        try
                        {
                            //采集数据
                            record = ReadEquipSystem(obj, record, perfusion_DeviceStatus, perfusion_Alarm);
                            Console.WriteLine($"【{DateTime.Now}】获取灌注数据条码:{record.PerfusionBoxCode},灌注结果:{record.PerfusionResult}");
                            if (string.IsNullOrEmpty(record.PerfusionBoxCode)) continue;
                            if (temprRecord == null)
                            {
                                temprRecord = _perfusionRecordServices.Query(d => d.PerfusionBoxCode.Equals(record.PerfusionBoxCode) && d.PerfusionResult == record.PerfusionResult).FirstOrDefault();
                            }
                            
                            if (temprRecord != null)
                            {
                                Console.WriteLine($"【{DateTime.Now}】灌注数据条码:{record.PerfusionBoxCode},已存在系统中");
                                return;
                            }
                            #region 更新设备状态
                            Perfusion_DeviceStatus device = _perfusionDeviceStatusServices.FirstAsync().Result;
                            if (device == null)
                            {
                                _ = _perfusionDeviceStatusServices.AddAsync(perfusion_DeviceStatus).Result;
                            }
                            else
                            {
                                device.PerfusionStatus = perfusion_DeviceStatus.PerfusionStatus;
                                var rsult = _perfusionDeviceStatusServices.UpdateAsync(device).Result;
                            }
                            #endregion

                            #region 更新报警信息
                            if (perfusion_Alarm.PerfusionStatus > 0)
                            {
                               int a = _perfusionAlarmServices.AddAsync(perfusion_Alarm).Result;
                            }
                            #endregion
                         

                            //充注结束
                            if (record.PerfusionFinishStatus == "1")
                            {
                                // 箱体码和上次不一样,或者箱体码一样但是充铸结果不一样
                                 if (temprRecord == null || temprRecord.PerfusionBoxCode != record.PerfusionBoxCode || (temprRecord.PerfusionBoxCode == record.PerfusionBoxCode && temprRecord.PerfusionResult != record.PerfusionResult))
                                {
                                    int result = _perfusionRecordServices.AddAsync(record).Result;
                                    if (result > 0)
                                    {
                                        Console.WriteLine(record.ToJson());
                                        temprRecord = record;
                                       
                                    }
                                }
                            }


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

                        Thread.Sleep(2000);
                    }

                }

            });
        }

        /// <summary>
        /// 采集灌注参数
        /// </summary>
        /// <returns></returns>
        static Perfusion_Record ReadEquipSystem(Aucma.Core.HwPLc.PlcModel obj, Perfusion_Record record, Perfusion_DeviceStatus deviceStatus, Perfusion_Alarm alarmInfo)
        {
            record = new Perfusion_Record();
            byte[] info = obj.plc.Read("DB55.0", 84);
            byte[] codeInfo = obj.plc.Read("DB60.0", 46);
            if (info == null) return null;
            #region 灌注记录赋值
            record.PerfusionActualVolume = byteToDouble(info.Skip(0).Take(8).ToArray()).ToString().Replace("\0", "");
            record.PerfusionR = byteToFloat(info.Skip(8).Take(4).ToArray()).ToString().ToString().Replace("\0", "");
            record.PerfusionL = byteToFloat(info.Skip(54).Take(4).ToArray()).ToString().Replace("\0", "");
            record.PerfusionDuration = int.Parse(StringChange.bytesToHexStr(info.Skip(12).Take(4).ToArray(), 4), System.Globalization.NumberStyles.HexNumber).ToString().Replace("\0", "");
            record.Yield = int.Parse(StringChange.bytesToHexStr(info.Skip(16).Take(4).ToArray(), 4), System.Globalization.NumberStyles.HexNumber).ToString().Replace("\0", "");
            record.PerfusionBoxCode = asciiEncoding.GetString(codeInfo.Skip(2).Take(22).ToArray()).Trim('\n').Replace("\0", "");
            record.PerfusionRefrigerantTypeLeft = asciiEncoding.GetString(codeInfo.Skip(28).Take(7).ToArray()).Trim('\n').Replace("\0", "");
            record.PerfusionRefrigerantTypeRight = asciiEncoding.GetString(codeInfo.Skip(38).Take(7).ToArray()).Trim('\n').Replace("\0", "");
            record.PerfusionSetVolume = byteToFloat(info.Skip(78).Take(4).ToArray()).ToString().Replace("\0", "");
            record.PerfusionSystem = short.Parse(StringChange.bytesToHexStr(info.Skip(82).Take(2).ToArray(), 2), System.Globalization.NumberStyles.HexNumber).ToString().Replace("\0", "");
            ///灌注完成状态字
            record.PerfusionFinishStatus = short.Parse(StringChange.bytesToHexStr(info.Skip(46).Take(2).ToArray(), 2), System.Globalization.NumberStyles.HexNumber).ToString().Replace("\0", "");
            record.PerfusionResult = short.Parse(StringChange.bytesToHexStr(info.Skip(48).Take(2).ToArray(), 2), System.Globalization.NumberStyles.HexNumber);
            record.CreatedBy = "equip";
            record.CreatedTime = DateTime.Now;
            record.UpdatedBy = "equip";
            record.UpdatedTime = DateTime.Now;
            #endregion
            //  Console.WriteLine("灌注记录:" + record.ToJson());
            #region  设备状态赋值
            deviceStatus.PerfusionDevicetype = "灌注";
            deviceStatus.PerfusionStatus = short.Parse(StringChange.bytesToHexStr(info.Skip(50).Take(2).ToArray(), 2), System.Globalization.NumberStyles.HexNumber);
            deviceStatus.CreatedBy = "equip";
            deviceStatus.CreatedTime = DateTime.Now;
            deviceStatus.UpdatedBy = "equip";
            deviceStatus.UpdatedTime = DateTime.Now;
            #endregion
            //  Console.WriteLine("设备状态:" + deviceStatus.ToJson());
            #region 设备报警赋值
            alarmInfo.PerfusionBoxcode = record.PerfusionBoxCode;
            alarmInfo.PerfusionStatus = short.Parse(StringChange.bytesToHexStr(info.Skip(52).Take(2).ToArray(), 2), System.Globalization.NumberStyles.HexNumber);
            alarmInfo.PerfusionAlarm = AlarmTrans(alarmInfo.PerfusionStatus);
            alarmInfo.PerfusionCompleted = "1";
            alarmInfo.CreatedBy = "equip";
            alarmInfo.CreatedTime = DateTime.Now;
            alarmInfo.UpdatedBy = "equip";
            alarmInfo.UpdatedTime = DateTime.Now;
            #endregion
            //   Console.WriteLine("报警信息:" + alarmInfo.ToJson());
            //    Console.WriteLine("\n");
            return record;
        }
        static string AlarmTrans(short code)
        {
            string result = "";
            switch (code)
            {
               
                case 2: result = "充注枪真空不合格"; break;
                case 4: result = "充注故障"; break;
                case 8: result = "充注时真空度超限定"; break;
                case 16: result = "回升检测不合格"; break;
                case 32: result = "工件真空不合格"; break;
                case 64: result = "平衡缸接近开关异常"; break;
                case 128: result = "增压超时"; break;
                case 256: result = "风压不足"; break;
            }
            return result;
        }


        #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);
            // 只保留两位小数
            //  string str = result.ToString("0.00");

            return result;

        }

        /// <summary>
        /// byte数组转换为double
        /// </summary>
        static double byteToDouble(byte[] list)
        {
            double result = 0;
            Array.Reverse(list);
            result = BitConverter.ToDouble(list, 0);
            return result;

        }

        #endregion
    }
}