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 UnitsProcess1Entity Vacuum1PlcDataGet()
        {
            try
            {
                // 读取PLC数据
                var res = _plc.ReadBytes(_plc.DeltaInstance1, "D188", 21);


                UnitsProcess1Entity entity = new UnitsProcess1Entity()
                {
                    // Float（单精度浮点数）占4字节，先截取4字节再反转
                    PumpAPressureActValue1 = BitConverter.ToSingle(SingleReverseBytesForValue(res.Content, (188 - 188) * 2, 4), 0),
                    PumpBPressureActValue1 = BitConverter.ToSingle(SingleReverseBytesForValue(res.Content, (190 - 188) * 2, 4), 0),
                    GluePushSpeedSetValue1 = BitConverter.ToSingle(SingleReverseBytesForValue(res.Content, (192 - 188) * 2, 4), 0),
                    GlueAmountSetValue1 = BitConverter.ToSingle(SingleReverseBytesForValue(res.Content, (194 - 188) * 2, 4), 0),
                    VacuumDegreeActValue1 = BitConverter.ToSingle(SingleReverseBytesForValue(res.Content, (196 - 188) * 2, 4), 0),

                    // Int16（短整型）占2字节，先截取2字节再反转
                    PressureHoldTimeSetValue1 = BitConverter.ToInt16(Int16ReverseBytesForValue(res.Content, (198 - 188) * 2, 2), 0),
                    BarrelA1TempActValue1 = BitConverter.ToInt16(Int16ReverseBytesForValue(res.Content, (200 - 188) * 2, 2), 0),
                    BarrelA2TempActValue1 = BitConverter.ToInt16(Int16ReverseBytesForValue(res.Content, (202 - 188) * 2, 2), 0),
                    BarrelB1TempActValue1 = BitConverter.ToInt16(Int16ReverseBytesForValue(res.Content, (206 - 188) * 2, 2), 0),
                    BarrelB2TempActValue1 = BitConverter.ToInt16(Int16ReverseBytesForValue(res.Content, (208 - 188) * 2, 2), 0),
                };

                return entity;
            }
            catch (Exception ex)
            {
                _log.Error("PLC读取真空箱1信息失败");
                return new UnitsProcess1Entity();
            }
        }

        /// <summary>
        /// 真空箱PLC数据获取
        /// </summary>
        /// <returns></returns>
        public UnitsProcess1Entity Vacuum2PlcDataGet()
        {
            try
            {
                var res = _plc.ReadBytes(_plc.DeltaInstance2, "D188", 21);
                var result = res.Content.Reverse().ToArray();
                UnitsProcess1Entity entity = new UnitsProcess1Entity()
                {
                    // Float（单精度浮点数）占4字节，先截取4字节再反转
                    PumpAPressureActValue2 = BitConverter.ToSingle(SingleReverseBytesForValue(res.Content, (188 - 188) * 2, 4), 0),
                    PumpBPressureActValue2 = BitConverter.ToSingle(SingleReverseBytesForValue(res.Content, (190 - 188) * 2, 4), 0),
                    GluePushSpeedSetValue2 = BitConverter.ToSingle(SingleReverseBytesForValue(res.Content, (192 - 188) * 2, 4), 0),
                    GlueAmountSetValue2 = BitConverter.ToSingle(SingleReverseBytesForValue(res.Content, (194 - 188) * 2, 4), 0),
                    VacuumDegreeActValue2 = BitConverter.ToSingle(SingleReverseBytesForValue(res.Content, (196 - 188) * 2, 4), 0),

                    // Int16（短整型）占2字节，先截取2字节再反转
                    PressureHoldTimeSetValue2 = BitConverter.ToInt16(Int16ReverseBytesForValue(res.Content, (198 - 188) * 2, 2), 0),
                    BarrelA1TempActValue2 = BitConverter.ToInt16(Int16ReverseBytesForValue(res.Content, (200 - 188) * 2, 2), 0),
                    BarrelA2TempActValue2 = BitConverter.ToInt16(Int16ReverseBytesForValue(res.Content, (202 - 188) * 2, 2), 0),
                    BarrelB1TempActValue2 = BitConverter.ToInt16(Int16ReverseBytesForValue(res.Content, (206 - 188) * 2, 2), 0),
                    BarrelB2TempActValue2 = BitConverter.ToInt16(Int16ReverseBytesForValue(res.Content, (208 - 188) * 2, 2), 0),
                };

                return entity;
            }
            catch (Exception ex)
            {
                _log.Error("PLC读取真空箱2信息失败");
                return new UnitsProcess1Entity();
            }
        }

        /// <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;
        }

        /// <summary>
        /// 预热炉数据获取
        /// </summary>
        /// <returns></returns>
        public int PreHeatOvenPlcDataGet()
        {
            try
            {
                var res = _plc.ReadInt16(_plc.DeltaInstance0, "D200");

                if (res.IsSuccess)
                {
                    return res.Content;
                }

                return 0;
            }
            catch (Exception ex)
            {
                _log.Error("PLC读取预热炉信息失败");
                return 0;
            }
        }

        /// <summary>
        /// 预固炉数据获取
        /// </summary>
        /// <returns></returns>
        public UnitsProcess3Entity PreCureOvenPlcDataGet()
        {
            try
            {
                var res = _plc.ReadBytes(_plc.DeltaInstance0, "D201", 4);
                var result = res.Content.Reverse().ToArray();
                UnitsProcess3Entity unitsProcess3Entity = new UnitsProcess3Entity()
                {
                    PreCureOven4TempActValue = BitConverter.ToInt16(result, 0),
                    PreCureOven3TempActValue = BitConverter.ToInt16(result, 2),
                    PreCureOven2TempActValue = BitConverter.ToInt16(result, 4),
                    PreCureOven1TempActValue = BitConverter.ToInt16(result, 6),
                };
                return unitsProcess3Entity;
            }
            catch (Exception ex)
            {
                _log.Error("PLC读取预固炉信息失败");
                return new UnitsProcess3Entity();
            }
        }

        /// <summary>
        /// 固化炉数据获取
        /// </summary>
        /// <returns></returns>
        public UnitsProcess3Entity CureOvenPlcDataGet()
        {
            try
            {
                var res = _plc.ReadBytes(_plc.DeltaInstance0, "D205", 4);
                var result = res.Content.Reverse().ToArray();
                UnitsProcess3Entity unitsProcess3Entity = new UnitsProcess3Entity()
                {
                    CureOven4TempActValue = BitConverter.ToInt16(result, 0),
                    CureOven3TempActValue = BitConverter.ToInt16(result, 2),
                    CureOven2TempActValue = BitConverter.ToInt16(result, 4),
                    CureOven1TempActValue = BitConverter.ToInt16(result, 6),
                };

                return unitsProcess3Entity;
            }
            catch (Exception ex)
            {
                _log.Error("PLC读取固化炉信息失败");
                return new UnitsProcess3Entity();
            }
        }
    }
}
