using Aitex.Core.RT.Device;
using Aitex.Core.RT.Log;
using Aitex.Core.Util;
using CyberX8_RT.Modules;
using CyberX8_RT.Modules.Reservoir;
using MECF.Framework.Common.CommonData;
using MECF.Framework.Common.IOCore;
using MECF.Framework.Common.ToolLayout;
using MECF.Framework.Common.TwinCat;
using System.Collections.Generic;
using System.Reflection;
namespace CyberX8_RT.Devices.Reservoir
{
    public class TotalReservoirDevice : BaseDevice, IDevice
    {
        #region 常量 
        private const string DIREPLEN_FLOW = "DiReplenFlow";
        private const string COUNTER_VALUE = "CounterValue";
        private const string COUNTER_START = "Start";
        private const string COUNTER_STOP = "Stop";
        private const string COUNTER_RESET = "Reset";
        private const string EVAPORATOR_LEVEL = "EvaporatorLevel";
        private const string HIGH_LEVEL = "HighLevel";
        private const string STRATUS = "Stratus";
        #endregion
        #region 内部变量
        /// 
        /// Di Replen Flow
        /// 
        private CounterFlowData _diReplenFlow = new CounterFlowData();
        /// 
        /// High Level
        /// 
        private bool _highLevel;
        /// 
        /// Evaporator Level
        /// 
        private bool _evaporatorLevel;
        /// 
        /// Counter字典
        /// 
        private Dictionary _nameCounterFlowData = new Dictionary();
        /// 
        /// 定时器
        /// 
        private PeriodicJob _period;
        /// 
        /// DiReplen Warning Dictionary
        ///       
        private Dictionary _diReplenWarnDic = new Dictionary() {
            {"Reservoir1", false},
            {"Reservoir2", false},
            {"Reservoir3", false},
            {"Reservoir4", false},
        };
        #endregion
        #region 属性
        /// 
        /// Di Replen Flow
        /// 
        private CounterFlowData DiReplenFlow { get { return _diReplenFlow; } }
        /// 
        /// High Level
        /// 
        public bool HighLevel { get { return _highLevel; } }
        /// 
        /// Evaporator Level
        /// 
        public bool EvaporatorLevel { get { return _evaporatorLevel; } }
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        /// 
        public TotalReservoirDevice() : base("Reservoir", "Reservoir", "Reservoir", "Reservoir")
        {
            _period = new PeriodicJob(500, OnTimer, "Reservoir.OnTimer", true, true);
        }
        /// 
        /// 初始化
        /// 
        /// 
        public bool Initialize()
        {
            InitializeParameter();
            SubscribeValueAction();
            InitializeOperation();
            return true;
        }
        /// 
        /// 加载参数
        /// 
        private void InitializeParameter()
        {
        }
        /// 
        /// 初始化操作
        /// 
        private void InitializeOperation()
        {
        }
        /// 
        /// 订阅变量数值发生变化
        /// 
        private void SubscribeValueAction()
        {
            BeckhoffCounterSubscribeUpdateVariable(DIREPLEN_FLOW, DiReplenFlow);
            BeckhoffIoSubscribeUpdateVariable(EVAPORATOR_LEVEL);
            BeckhoffIoSubscribeUpdateVariable(HIGH_LEVEL);
        }
        /// 
        /// 订阅Counter变量
        /// 
        /// 
        private void BeckhoffCounterSubscribeUpdateVariable(string variable, CounterFlowData counterFlowData)
        {
            _nameCounterFlowData[$"{Module}.{variable}"] = counterFlowData;
            BeckhoffCounterManager.Instance.SubscribeModuleVariable($"{Module}.{variable}", COUNTER_VALUE, UpdateCounterVariableValue);
            BeckhoffCounterManager.Instance.SubscribeModuleVariable($"{Module}.{variable}", COUNTER_START, UpdateCounterVariableValue);
            BeckhoffCounterManager.Instance.SubscribeModuleVariable($"{Module}.{variable}", COUNTER_STOP, UpdateCounterVariableValue);
            BeckhoffCounterManager.Instance.SubscribeModuleVariable($"{Module}.{variable}", COUNTER_RESET, UpdateCounterVariableValue);
        }
        /// 
        /// 订阅IO变量
        /// 
        /// 
        private void BeckhoffIoSubscribeUpdateVariable(string variable)
        {
            IOModuleManager.Instance.SubscribeModuleVariable(Module, variable, UpdateIOVariableValue);
        }
        /// 
        /// 更新变量数值
        /// 
        /// 
        /// 
        private void UpdateIOVariableValue(string variable, object value)
        {
            if (variable == HIGH_LEVEL)
            {
                _highLevel = (bool)value;
            }
            else if (variable == EVAPORATOR_LEVEL)
            {
                _evaporatorLevel = (bool)value;
            }
        }
        /// 
        /// 更新变量数值
        /// 
        /// 
        /// 
        private void UpdateCounterVariableValue(string variable, object value)
        {
            string[] strAry = variable.Split('.');
            string lastVariable = strAry[strAry.Length - 1];
            PropertyInfo property = null;
            string key = variable.Replace($".{lastVariable}", "");
            if (_nameCounterFlowData.ContainsKey(key))
            {
                CounterFlowData counterFlowData = _nameCounterFlowData[key];
                property = counterFlowData.GetType().GetProperty(lastVariable);
                if (property != null)
                {
                    property.SetValue(counterFlowData, value);
                }
            }
        }
        /// 
        /// 定时器
        /// 
        /// 
        private bool OnTimer()
        {
            List reservoirs = ReservoirItemManager.Instance.InstalledModules;
            foreach (string module in reservoirs)
            {
                ReservoirItem reservoirItem = ReservoirItemManager.Instance.GetReservoirItem(module);
                ReservoirEntity reservoirEntity = Singleton.Instance.GetModule(module);
                if (reservoirEntity != null && !reservoirEntity.IsError)
                {
                    if (reservoirItem.SubType == STRATUS)
                    {
                        StandardHotReservoirDevice reservoirDevice = DEVICE.GetDevice(module);
                        if (!reservoirEntity.IsInitialized || reservoirDevice.DiReplenMaxTimeOut
                            || reservoirDevice.IsDireplenOn || reservoirDevice.IsDiReplenInFault)
                        {
                            continue;
                        }
                        if (reservoirDevice.NeedAutoDireplen)
                        {
                            if (!CheckFacilityDiReplenOn(reservoirDevice.TotalDIReplenOn, module))
                            {
                                continue;
                            }
                            reservoirDevice.AutoDireplen();
                        }
                    }
                }
                else
                {
                    continue;
                }
            }
            return true;
        }
        private bool CheckFacilityDiReplenOn(bool diReplenOn, string module)
        {
            if (!diReplenOn)
            {
                if (!_diReplenWarnDic[module])
                {
                    _diReplenWarnDic[module] = true;
                    LOG.WriteLog(eEvent.WARN_RESERVOIR, module, $"SystemFacility DIReplen is off, {module} can't do auto DIReplen");
                }
                return false;
            }
            else
            {
                _diReplenWarnDic[module] = false;
                return true;
            }
        }
        public void Monitor()
        {
        }
        public void Reset()
        {
        }
        public void Terminate()
        {
            _period.Stop(false);
        }
    }
}