using Aitex.Core.RT.DataCenter;
using Aitex.Core.RT.Device.PmDevices;
using Aitex.Core.RT.Device;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.IOCore;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using System;
using System.Xml;
using Aitex.Core.RT.Log;

namespace MECF.Framework.RT.EquipmentLibrary.Devices
{
    public class PryoTempCheck : BaseDevice, IDevice
    {
        private double _pyroDiffWarning;

        private double _pyroDiffAlarm;

        private double _pyroDiffCheckDelay;

        private double _pyroDiffFilterTime;

        private float _middleTemp;

        private string _pmStatus;

        private double _recipeStepElapseTime;

        private R_TRIG _diffWarningTrig = new R_TRIG();

        private R_TRIG _diffAlarmTrig = new R_TRIG();

        private DeviceTimer _timerAlarm = new DeviceTimer();

        private DeviceTimer _timerWarning = new DeviceTimer();

        private readonly AOAccessor _aoPSUMiddleLoopMode = null;

        private readonly AOAccessor _aoPSUMiddleTargetSP = null;

        public PryoTempCheck(string module, XmlElement node, string ioModule = "")
        {
            base.Module = module;
            base.Name = node.GetAttribute("id");
            base.Display = node.GetAttribute("display");
            base.DeviceID = node.GetAttribute("schematicId");

            var scBasePath = node.GetAttribute("scBasePath");
            scBasePath = string.IsNullOrEmpty(scBasePath) ?
                $"{Module}.{Name}"
                : scBasePath.Replace("{module}", Module);

            ScBasePath = scBasePath;

            _pyroDiffWarning = SC.GetValue<double>(ScBasePath + "." + "PyroDiffWarning");
            _pyroDiffAlarm = SC.GetValue<double>(ScBasePath + "." + "PyroDiffAlarm");
            _pyroDiffCheckDelay = SC.GetValue<double>(ScBasePath + "." + "PyroDiffCheckDelay");
            _pyroDiffFilterTime = SC.GetValue<double>(ScBasePath + "." + "PyroDiffFilterTime");

            _aoPSUMiddleLoopMode = ParseAoNode("aoPSUMiddleLoopMode", node, ioModule);
            _aoPSUMiddleTargetSP = ParseAoNode("aoPSUMiddleTargetSP", node, ioModule);
        }

        public bool Initialize()
        {
            return true;
        }

        protected override void HandleMonitor()
        {
            try
            {
                _middleTemp = (float)DATA.Poll($"{Module}.Temp.Middle");
                _pmStatus = DATA.Poll($"{Module}.Status").ToString();
                _recipeStepElapseTime = (double)DATA.Poll($"{Module}.RecipeStepElapseTime");

                //PM腔在工艺中,PSUMiddle在Pyro模式且当前步已运行时间大于设定Delay时间
                if (_pmStatus == "Process" && _aoPSUMiddleLoopMode.Value == (float)TCModes.Auto
                    && _recipeStepElapseTime > _pyroDiffCheckDelay)
                {
                    double diffValue = Math.Abs(_middleTemp - _aoPSUMiddleTargetSP.Value);

                    //Alarm检测
                    if (diffValue >= _pyroDiffAlarm)
                    {
                        if (_timerAlarm.IsIdle())
                        {
                            _timerAlarm.Start(_pyroDiffFilterTime);
                        }
                    }
                    else
                    {
                        _timerAlarm.Stop();
                    }

                    _diffAlarmTrig.CLK = _timerAlarm.IsTimeout();
                    if (_diffAlarmTrig.Q)
                    {
                        EV.PostAlarmLog(Module, $"Detected PSU Middle Temperature difference alarm.Set Temperature is {_aoPSUMiddleTargetSP.Value},Measure Temperature is {_middleTemp}");
                    }

                    //Warning检测
                    if (diffValue >= _pyroDiffWarning)
                    {
                        if (_timerWarning.IsIdle())
                        {
                            _timerWarning.Start(_pyroDiffFilterTime);
                        }
                    }
                    else
                    {
                        _timerWarning.Stop();
                    }

                    _diffWarningTrig.CLK = _timerWarning.IsTimeout();
                    if (_diffWarningTrig.Q)
                    {
                        EV.PostWarningLog(Module, $"Detected PSU Middle Temperature difference warning.Set Temperature is {_aoPSUMiddleTargetSP.Value},Measure Temperature is {_middleTemp}");
                    }
                }
            }
            catch (Exception ex)
            {
                LOG.Write(ex);
            }
        }

        public void Terminate()
        {

        }

        public void Reset()
        {
            _diffAlarmTrig.RST = true;
            _diffWarningTrig.RST = true;

            _timerAlarm.Stop();
            _timerWarning.Stop();
        }
    }
}
