using SlnMesnac.Business.@base;
using SlnMesnac.Config;
using SlnMesnac.Model.dto;
using SlnMesnac.Plc;
using SlnMesnac.Repository;
using SlnMesnac.Repository.service;
using SlnMesnac.Serilog;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

#region << 版 本 注 释 >>
/*--------------------------------------------------------------------
* 版权所有 (c) 2024 WenJY 保留所有权利。
* CLR版本：4.0.30319.42000
* 机器名称：T14-GEN3-7895
* 命名空间：SlnMesnac.Business
* 唯一标识：73cd3d99-8387-4ff6-9276-8eeb424e2aa2
*
* 创建者：WenJY
* 电子邮箱：
* 创建时间：2024-11-07 9:51:55
* 版本：V1.0.0
* 描述：
*
*--------------------------------------------------------------------
* 修改人：
* 时间：
* 修改说明：
*
* 版本：V1.0.0
*--------------------------------------------------------------------*/
#endregion << 版 本 注 释 >>
namespace SlnMesnac.Business
{
    /// <summary>
    /// Inspection mode 巡检模式
    /// </summary>
    public class InspModeBusiness : BaseBusiness
    {
        private readonly Irecord_busbar_tempServices _record_busbar_TempServices;
        private readonly Irecord_inspection_cabinetServices _service;

        public delegate void CaptureAlarmPicture(string sJpegPicFileName);
        public event CaptureAlarmPicture CaptureAlarmPictureEvent;

        public delegate void GimbaRotationControl(string wPanPos, string wTiltPos, string wZoomPos);
        public event GimbaRotationControl GimbaRotationControlEvent;

        private readonly AppConfig _appConfig;

        public InspModeBusiness( Irecord_inspection_cabinetServices service, 
            Irecord_busbar_tempServices irecord_Busbar_TempServices,IServiceProvider serviceProvider,AppConfig appConfig) : base(serviceProvider)
        {
            _record_busbar_TempServices = irecord_Busbar_TempServices;
            _service = service;
            _appConfig = appConfig;
        }

        public void Start(string taskCode,string filePath)
        {
            //if (isFlag)
            //{
            //    _log.Info($"自动模式运行中，请勿重复开启");
            //    return;
            //}

            //InspModeEvent();

            try
            {

                if (isFlag)
                {
                    _log.Info($"巡检模式运行中，请勿重复开启");
                    return;
                }

                Task.Run(() =>
                {
                    lock (string.Empty)
                    {
                        isFlag = true;
                        while (isFlag)
                        {
                            _log.Info($"巡检模式初始化成功");
                            this.InspModeEvent();

                            if (isFlag)
                            {
                                Task.Delay(1000 * 60 * _appConfig.checkCycle).Wait();
                            }
                        }
                    }

                });


            }
            catch (Exception ex)
            {
                _log.Info($"巡检模式初始化异常:{ex.Message}");
            }
        }

        public void Stop()
        {
            isFlag = false;
            _log.Info($"巡检模式关闭成功");
        }

        private void InspModeEvent()
        {
            try
            {
                Task.Run(() =>
                {
                    Task.Delay(1000).Wait();

                    isFlag = true;

                    base.InitEquip(2); //判断PLC状态，下发工作模式

                    int address = _plc.readInt32ByAddress("VD1100");    //读取轨道电机当前位置，判断原点及起始位置

                    if (!isFlag)
                    {
                        _log.Info($"快速巡检取消");
                        return;
                    }

                    //获取电柜信息
                    List<base_cabinet_info> cabinet_Infos = new List<base_cabinet_info>();
                    base.GetCabinetInfos(address, out cabinet_Infos);

                    foreach (var item in cabinet_Infos)
                    {

                        this.SendTrackMotorAddress(item);

                        if (!_plc.writeInt32ByAddress("VD1512", 1)) //母排检测完成下发检测完成信号，升降电机可以回到原位等待
                        {
                            throw new ArgumentException($"快速巡检下发检测完成信号写入失败；VD1512写1");
                        }
                        Task.Delay(1000).Wait();

                        if (!isFlag)
                        {
                            _log.Info($"快速巡检取消");
                            break;
                        }
                    }

                    _log.Info($"快速巡检结束");
                });
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException($"自动巡检逻辑处理异常:{ex.Message}");
            }
        }

        /// <summary>
        /// 下发轨道电机位置编号
        /// </summary>
        /// <param name="item"></param>
        /// <exception cref="ArgumentException"></exception>
        private void SendTrackMotorAddress(base_cabinet_info item)
        {
            if (!_plc.writeInt32ByAddress("VD1520", item.cabinetCode)) //下发电柜编号，通知轨道电机前往指定电柜位置
            {
                throw new ArgumentException($"快速巡检下发轨道电机前往指定位置编号写入失败；VD1520写{item.cabinetCode}");
            }
            _log.Info($"快速巡检下发轨道电机前往指定位置成功；VD1520写{item.cabinetCode}");

            this.AwaitArriveSignal("VD1528"); //等待轨道相机到位信号

            if (!isFlag)
            {
                return;
            }

            this.SendLiftMotorDict(item.cabinetCode);


        }

        /// <summary>
        /// 下发升降电机升降距离
        /// </summary>
        /// <param name="cabinetCode"></param>
        /// <exception cref="ArgumentException"></exception>
        private void SendLiftMotorDict(int cabinetCode)
        {

            List<base_busbar_info> busbar_Infos = new List<base_busbar_info>();
            base.GetBusbarInfos(cabinetCode, out busbar_Infos,1);
            foreach (var busbar in busbar_Infos)
            {
                if (!_plc.writeFloatByAddress("VD1524", ((float)busbar.busbarDist))) //下发母排距离，升降电机升降的距离
                {
                    throw new ArgumentException($"快速巡检下发母排升降距离写入失败；VD1524写{busbar.cabinetCode}");
                }
                _log.Info($"快速巡检下发母排升降距离成功；VD1524写{busbar.busbarDist}");

                this.AwaitArriveSignal("VD1504");  //等待升降电机到位信号

                if (!isFlag)
                {
                    return;
                }

                //控制云台旋转
                if (busbar.isRotate == 1)
                {
                    GimbaRotationControlEvent?.Invoke(busbar.wPanPos, busbar.wTiltPos, busbar.wZoomPos);
                }

                //这里采集数据
                _log.Info($"2S后开始测温");
                Task.Delay(2000).Wait();
                _log.Info($"温度测量完成，最高温度:{_realTemperatureInfo.fMaxTemperature};最低温度:{_realTemperatureInfo.fMinTemperature};平均温度:{_realTemperatureInfo.fAverageTemperature};温差:{_realTemperatureInfo.fTemperatureDiff}");
                this.SaveBusbarTemp(busbar.busbarCode, busbar.cabinetCode, _realTemperatureInfo, busbar.isPictures);

                if (busbar.isRotate == 1)
                {
                    GimbaRotationControlEvent?.Invoke("20", "4", "10");
                }
            }

        }

        /// <summary>
        /// 等待PLC到位信号
        /// </summary>
        /// <param name="signal"></param>
        /// <exception cref="InvalidOperationException"></exception>
        private void AwaitArriveSignal(string signal)
        {
            try
            {
                bool is_arrive = true;
                while (is_arrive)
                {

                    if (!isFlag)
                    {
                        break;
                    }

                    int rewrite = _plc.readInt32ByAddress("VD1554");
                    if (rewrite == 1)
                    {
                        _plc.writeInt32ByAddress("VD1554", 0);
                        if (!_plc.writeInt32ByAddress("VD1536", 2)) //工作模式:1-自动；2-巡检；3-手动
                        {
                            throw new ArgumentException($"VD1554为1重新写入工作模式:自动模式；写入PLC失败；VD1536写2");
                        }

                        _log.Info($"VD1554为1重新写入工作模式:自动模式；写入PLC成功；VD1536写2");
                    }

                    int is_arrive_flag = _plc.readInt32ByAddress(signal); //读取PLC轨道电机到位信号
                    if (is_arrive_flag == 1)
                    {
                        _log.Info($"PLC已到达指定位置；{signal}值为{is_arrive_flag}");
                        if (!_plc.writeInt32ByAddress(signal, 0))
                        {
                            throw new ArgumentException($"PLC到位信号复位失败；{signal}写0");
                        }

                        is_arrive = false;

                        continue;
                    }

                    _log.Info($"等待PLC前往指定位置；{signal}值为{is_arrive_flag}");

                    Task.Delay(1000).Wait();
                }
            }
            catch (Exception e)
            {
                throw new InvalidOperationException($"等待到位信号处理异常:{e.Message}");
            }
        }

        /// <summary>
        /// 保存母排测温数据
        /// </summary>
        /// <param name="busbarCode"></param>
        /// <param name="cabinetCode"></param>
        /// <param name="realTemperatureInfo"></param>
        private void SaveBusbarTemp(int? busbarCode, int? cabinetCode, RealTemperatureInfo realTemperatureInfo, int isPictures)
        {
            try
            {

                var record = new record_busbar_temp()
                {
                    busbarCode = busbarCode,
                    cabinetCode = cabinetCode,
                    tempMax = (decimal)realTemperatureInfo.fMaxTemperature,
                    tempMin = (decimal)realTemperatureInfo.fMinTemperature,
                    tempAvg = (decimal)realTemperatureInfo.fAverageTemperature,
                    tempDiff = (decimal)realTemperatureInfo.fTemperatureDiff,
                    routModel = 2,
                    recordTime = DateTime.Now,
                };

                //if (realTemperatureInfo.fMaxTemperature > 65)
                //{
                //    record.isAlarm = 1;
                //    string sJpegPicFileName = $"{cabinetCode}_{busbarCode}_{DateTime.Now.ToString("yyyyMMddHHmmssffff")}.jpg";
                //    record.filePath = sJpegPicFileName;
                //    CaptureAlarmPictureEvent?.Invoke(sJpegPicFileName);
                //}
                //else
                //{
                //    if (isPictures == 1)
                //    {
                //        string sJpegPicFileName = $"{cabinetCode}_{busbarCode}_{DateTime.Now.ToString("yyyyMMddHHmmssffff")}.jpg";
                //        record.filePath = sJpegPicFileName;
                //        CaptureAlarmPictureEvent?.Invoke(sJpegPicFileName);
                //    }
                //}

                string sJpegPicFileName = $"{cabinetCode}_{busbarCode}_{DateTime.Now.ToString("yyyyMMddHHmmssffff")}.jpg";
                record.filePath = sJpegPicFileName;
                CaptureAlarmPictureEvent?.Invoke(sJpegPicFileName);

                base.JudgBusbarIsAlarm((int)busbarCode, ref record);

                var res = _record_busbar_TempServices.Insert(record);

                if (res)
                {
                    _log.Info($"{cabinetCode}号电柜{busbarCode}排数据保存成功");
                }
                else
                {
                    _log.Info($"{cabinetCode}号电柜{busbarCode}排数据保存失败");
                }
            }
            catch (Exception e)
            {
                _log.Info($"{cabinetCode}号电柜{busbarCode}排数据保存异常:{e.Message}");
            }
        }
    }
}
