using Sln.Iot.CFX.CFXBusiness;
using Sln.Iot.Model.Entity;
using Sln.Iot.PLC;
using Sln.Iot.Serilog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Sln.Iot.Business
{
    public class UnitsProcessPLCDataGetBusiness
    {
        private static readonly Lazy<UnitsProcessPLCDataGetBusiness> lazy = new Lazy<UnitsProcessPLCDataGetBusiness>(() => new UnitsProcessPLCDataGetBusiness());

        public static UnitsProcessPLCDataGetBusiness Instance
        {
            get
            {
                return lazy.Value;
            }
        }


        private readonly PLCConnect _plc = PLCConnect.Instance;
        private readonly SerilogHelper _log = SerilogHelper.Instance;

        /// <summary>
        /// 真空灌胶机PLC数据获取
        /// </summary>
        /// <returns></returns>
        public UnitsProcessVacuumEntity VacuumPlcDataGet()
        {
            try
            {
                var entity = new UnitsProcessVacuumEntity();

                // 一次性读取 D12600-D12637（38个字），包含配方数据、配方参数、总胶量
                var recipeRes = _plc.ReadBytes(_plc.PLC21, "D12600", 38);
                if (recipeRes.IsSuccess)
                {
                    // 配方数据 D12600（10个字字符串）
                    entity.FormulaData = Encoding.ASCII.GetString(recipeRes.Content, 0, 20).TrimEnd('\0');

                    // Float（单精度浮点数）占4字节
                    entity.GluePushSpeedSetValue = BitConverter.ToSingle(SingleReverseBytesForValue(recipeRes.Content, (12610 - 12600) * 2, 4), 0);
                    entity.GlueAmountSetValue1 = BitConverter.ToSingle(SingleReverseBytesForValue(recipeRes.Content, (12612 - 12600) * 2, 4), 0);
                    entity.GlueAmountSetValue2 = BitConverter.ToSingle(SingleReverseBytesForValue(recipeRes.Content, (12614 - 12600) * 2, 4), 0);
                    entity.GlueAmountSetValue3 = BitConverter.ToSingle(SingleReverseBytesForValue(recipeRes.Content, (12616 - 12600) * 2, 4), 0);
                    entity.GlueAmountSetValue4 = BitConverter.ToSingle(SingleReverseBytesForValue(recipeRes.Content, (12618 - 12600) * 2, 4), 0);
                    entity.GlueAmountSetValue5 = BitConverter.ToSingle(SingleReverseBytesForValue(recipeRes.Content, (12620 - 12600) * 2, 4), 0);
                    entity.GlueAmountSetValue6 = BitConverter.ToSingle(SingleReverseBytesForValue(recipeRes.Content, (12622 - 12600) * 2, 4), 0);
                    entity.GlueAmountSetValue7 = BitConverter.ToSingle(SingleReverseBytesForValue(recipeRes.Content, (12624 - 12600) * 2, 4), 0);
                    entity.GlueAmountSetValue8 = BitConverter.ToSingle(SingleReverseBytesForValue(recipeRes.Content, (12626 - 12600) * 2, 4), 0);
                    entity.GlueAmountSetValue9 = BitConverter.ToSingle(SingleReverseBytesForValue(recipeRes.Content, (12628 - 12600) * 2, 4), 0);
                    entity.GlueAmountSetValue10 = BitConverter.ToSingle(SingleReverseBytesForValue(recipeRes.Content, (12630 - 12600) * 2, 4), 0);
                    entity.VacuumDegreeSetValue = BitConverter.ToSingle(SingleReverseBytesForValue(recipeRes.Content, (12632 - 12600) * 2, 4), 0);
                    entity.TotalGlueAmountSetValue = BitConverter.ToSingle(SingleReverseBytesForValue(recipeRes.Content, (12636 - 12600) * 2, 4), 0);

                    // Int16（短整型）占2字节
                    entity.PressureHoldTimeSetValue = BitConverter.ToInt16(Int16ReverseBytesForValue(recipeRes.Content, (12634 - 12600) * 2, 2), 0);
                    entity.VacuumIsUseSetValue = BitConverter.ToInt16(Int16ReverseBytesForValue(recipeRes.Content, (12635 - 12600) * 2, 2), 0);
                }

                // 读取实际值 D850-D855（6个字）
                var actRes = _plc.ReadBytes(_plc.PLC21, "D850", 6);
                if (actRes.IsSuccess)
                {
                    entity.PumpAPressureActValue = BitConverter.ToSingle(SingleReverseBytesForValue(actRes.Content, (850 - 850) * 2, 4), 0);
                    entity.PumpBPressureActValue = BitConverter.ToSingle(SingleReverseBytesForValue(actRes.Content, (852 - 850) * 2, 4), 0);
                    entity.VacuumDegreeActValue = BitConverter.ToSingle(SingleReverseBytesForValue(actRes.Content, (854 - 850) * 2, 4), 0);
                }

                return entity;
            }
            catch (Exception ex)
            {
                _log.Error("PLC读取真空灌胶机信息失败");
                return new UnitsProcessVacuumEntity();
            }
        }


        /// <summary>
        /// 固化炉（隧道炉）PLC数据获取
        /// </summary>
        /// <returns></returns>
        public UnitsProcessOvenEntity OvenPlcDataGet()
        {
            try
            {
                var entity = new UnitsProcessOvenEntity();

                // 读取固化温度实际值 D200-D201（2个字）
                var actRes = _plc.ReadBytes(_plc.PLC20, "D200", 2);
                if (actRes.IsSuccess)
                {
                    entity.CureOven1ActValue = BitConverter.ToInt16(Int16ReverseBytesForValue(actRes.Content, (200 - 200) * 2, 2), 0);
                    entity.CureOven2ActValue = BitConverter.ToInt16(Int16ReverseBytesForValue(actRes.Content, (201 - 200) * 2, 2), 0);
                }

                // 读取固化温度设定值 D20000-D20001（2个字）
                var setRes = _plc.ReadBytes(_plc.PLC20, "D20010", 2);
                if (setRes.IsSuccess)
                {
                    entity.CureOven1SetValue = BitConverter.ToInt16(Int16ReverseBytesForValue(setRes.Content, (20010 - 20010) * 2, 2), 0);
                    entity.CureOven2SetValue = BitConverter.ToInt16(Int16ReverseBytesForValue(setRes.Content, (20011 - 20010) * 2, 2), 0);
                }

                return entity;
            }
            catch (Exception ex)
            {
                _log.Error("PLC读取固化炉（隧道炉）信息失败");
                return new UnitsProcessOvenEntity();
            }
        }

        /// <summary>
        /// 定义字节序转换的辅助方法（核心）
        /// </summary>
        /// <param name="source"></param>
        /// <param name="startIndex"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        byte[] Int16ReverseBytesForValue(byte[] source, int startIndex, int length)
        {
            // 截取对应位置的字节片段（避免修改原数组）
            byte[] temp = new byte[length];
            Array.Copy(source, startIndex, temp, 0, length);
            // 反转字节序（大端转小端）
            Array.Reverse(temp);
            return temp;
        }

        // 定义字节序转换的辅助方法（核心）
        byte[] SingleReverseBytesForValue(byte[] source, int startIndex, int length)
        {
            // 截取对应位置的字节片段（避免修改原数组）
            byte[] temp = new byte[length];
            Array.Copy(source, startIndex, temp, 0, length);

            var t = temp[0];
            temp[0] = temp[2];
            temp[2] = t;
            t = temp[1];
            temp[1] = temp[3];
            temp[3] = t;

            // 反转字节序（大端转小端）
            Array.Reverse(temp);
            return temp;
        }

    }
}
