using Aitex.Core.RT.DataCenter;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.IOCore;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using MECF.Framework.Common.Aitex.Core.Common.DeviceData.IoDevice;
using System.Xml;

namespace Aitex.Core.RT.Device.Devices
{
    public class IoLineHeater : BaseDevice, IDevice
    {
        //配置中标记的AI名称

        protected readonly AIAccessor _aiTemp;

        protected readonly DOAccessor _doLineHeaterEnable;

        protected readonly string _scNameAlarmHigh;

        protected double _alarmHigh;

        protected readonly R_TRIG _trigIsAlarm = new R_TRIG();

        protected int _alarmCount;


        private readonly LineHeaterData _lineHeaterData = new();
        public LineHeaterData lineHeaterData
        {
            get 
            {
                _lineHeaterData.LineHeaterLaber = Display;
                _lineHeaterData.ScHighTemp = _alarmHigh;
                _lineHeaterData.TempValue = _aiTemp.Value;

                return _lineHeaterData;
            }
        }

        public IoLineHeater(string module, XmlElement node, string ioModule = "") : base(module, node, ioModule)
        {
            _aiTemp = ParseAiNode("aiHeatTMA", node, ioModule);

            _doLineHeaterEnable = ParseDoNode("doLineHeaterEnable", node, ioModule);

            _scNameAlarmHigh = $"{ScBasePath}.{node.GetAttribute("scAlarmHigh")}";
        }

        protected override void HandleMonitor()
        {
            if (_alarmHigh == 0)
                return;
            if (_aiTemp.Value >= _alarmHigh)
            {
                _trigIsAlarm.CLK = true;
                if (_trigIsAlarm.Q)
                {
                    if (_doLineHeaterEnable == null)
                    {
                        EV.PostWarningLog(Module,
                            $"{_aiTemp.Name}  {_aiTemp.Value} over temperature {_alarmHigh} but doLineHeaterEnable can not be off since it's not defined");
                    }
                    else
                    {
                        _doLineHeaterEnable.SetValue(false, out _);
                        EV.PostWarningLog(Module,
                            $"{_aiTemp.Name}  {_aiTemp.Value} over temperature {_alarmHigh}\r\n{Module}.{_doLineHeaterEnable.Name} force off");
                    }
                }
            }
            else
                _trigIsAlarm.RST = true;//降温自动复位上升沿信号
        }

        public bool Initialize()
        {
            DATA.Subscribe($"{Module}.LineHeater.{Display}", () => _aiTemp.Value);
            DATA.Subscribe($"{Module}.{Name}.LineHeaterData", () => lineHeaterData, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            _alarmHigh = SC.SafeGetValue(_scNameAlarmHigh, double.PositiveInfinity);
            SC.RegisterValueChangedCallback(_scNameAlarmHigh, v => _alarmHigh = (double)v);
            return true;
        }

        public void Reset()
        {
            _trigIsAlarm.RST = true;
        }

        public void Terminate()
        {
        }
    }
}