using Aitex.Core.RT.Log;
using Aitex.Core.RT.OperationCenter;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using MECF.Framework.Common.Beckhoff.ModuleIO;
using MECF.Framework.Common.CommonData.Reservoir;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.Persistent.Reservoirs;
using MECF.Framework.Common.Persistent.Temperature;
using MECF.Framework.Common.TwinCat;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PunkHPX8_RT.Devices.Reservoir
{
    public class DMReservoirDevice : ReservoirDevice
    {
        #region 常量
        private const string AN_PUMP = "ANPump";
        #endregion
        #region 内部变量
        /// 
        /// 默认泵速
        /// 
        private double _anPumpSpeed = 5000;
        /// 
        /// an泵速Helper
        /// 
        private ReservoirANPumpSpeedHelper _anPumpSpeedHelper;
        #endregion
        #region 属性
        /// 
        /// 检验阳极是否highlevel
        /// 
        public bool IsANHighLevel { get { return _reservoirData.AnTowerHigh; } }
        /// 
        /// 检验阳极是否lowlevel
        /// 
        public bool IsANLowLevel { get { return _reservoirData.AnTowerLow; } }
        #endregion
        #region Trigger
        /// 
        /// low WaterLevel trigger
        /// 
        private R_TRIG _anWaterLevelLowerTrigger = new R_TRIG();
        /// 
        /// low WaterLevel trigger
        /// 
        private R_TRIG _anWaterLevelHighTrigger = new R_TRIG();
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        public DMReservoirDevice(string moduleName) : base(moduleName)
        {
            _anPumpSpeedHelper = new ReservoirANPumpSpeedHelper(Module, this);
        }
        /// 
        /// 订阅变量
        /// 
        protected override void SubscribeValueAction()
        {
            base.SubscribeValueAction();
            IoSubscribeUpdateVariable(AN_DI_REPLEN);
            IoSubscribeUpdateVariable(AN_FLOW);
            IoSubscribeUpdateVariable(AN_PUMP_ENABLE);
            IoSubscribeUpdateVariable(AN_PUMP_SPEED);
            IoSubscribeUpdateVariable(DEGAS_ENABLE);
        }
        /// 
        /// 订阅Operation
        /// 
        protected override void InitializeOperation()
        {
            base.InitializeOperation(); 
            OP.Subscribe($"{Module}.ANPumpEnable", AnPumpOnOperation);
            OP.Subscribe($"{Module}.ANPumpSpeed", ANPumpSpeedOperation);
            OP.Subscribe($"{Module}.ANPumpDisable", AnPumpOffOperation);
            OP.Subscribe($"{Module}.ANIsolationOn", (cmd, para) => { return ANIsolationOn(); });
            OP.Subscribe($"{Module}.ANIsolationOff", (cmd, para) => { return ANIsolationOff(); });
        }
        #region AnPump
        /// 
        /// AN Pump调速
        /// 
        /// 
        /// 
        /// 
        private bool ANPumpSpeedOperation(string cmd, object[] args)
        {
            double anMaxPumpSpeed = 0;
            if (SC.ContainsItem("Reservoir.ANMaxPumpSpeed"))
            {
                anMaxPumpSpeed = SC.GetValue("Reservoir.ANMaxPumpSpeed");
            }
            if (double.TryParse(args[0].ToString(), out double speed))
            {
                _anPumpSpeed = speed;
                if (_anPumpSpeed > anMaxPumpSpeed)
                {
                    LOG.WriteLog(eEvent.WARN_RESERVOIR, Module, $"AN pump speed:{_anPumpSpeed} is over AN max pump speed {anMaxPumpSpeed}!");
                    return false;
                }
                return AnPumpSpeed(_anPumpSpeed);
            }
            else
            {
                LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"{args[0]} is nor invalid speed");
                return false;
            }
        }
        /// 
        /// 设置AN泵速
        /// 
        /// 
        /// 
        public bool AnPumpSpeed(double anPumpSpeed)
        {
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{AN_PUMP_SPEED}");
            return BeckhoffIOManager.Instance.WriteIoValue(ioName, anPumpSpeed);
        }
        /// 
        /// 阳极Pump On
        /// 
        /// 
        /// 
        /// 
        public bool AnPumpOnOperation(string cmd, object[] args)
        {
            double caPumpSpeed = SC.GetValue("Reservoir.ANDefaultPumpSpeed");
            bool result = AnPumpSpeed(caPumpSpeed);
            if (result)
            {
                string enableIOName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{AN_PUMP_ENABLE}");
                return BeckhoffIOManager.Instance.WriteIoValue(enableIOName, true);
            }
            else
            {
                return false;
            }
        }
        /// 
        /// 阳极Pump Off
        /// 
        /// 
        /// 
        /// 
        private bool AnPumpOffOperation(string cmd, object[] args)
        {
            return AnPumpOff();
        }
        /// 
        /// 关闭阳极Pump
        /// 
        /// 
        public bool AnPumpOff()
        {
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{AN_PUMP_ENABLE}");
            return BeckhoffIOManager.Instance.WriteIoValue(ioName, false);
        }
        /// 
        /// ANIsolationOn
        /// 
        /// 
        public bool ANIsolationOn()
        {
            return WriteVariableValue(AN_ISOLATION, true);
        }
        /// 
        /// ANIsolationOff
        /// 
        /// 
        public bool ANIsolationOff()
        {
            return WriteVariableValue(AN_ISOLATION, false);
        }
        #endregion
        protected override void AutoMonitor()
        {
            base.AutoMonitor();
            if (_persistentValue.OperatingMode == AUTO)
            {
                _anPumpSpeedHelper.Monitor(_resRecipe);
            }
        }
        /// 
        /// 水位监控
        /// 
        protected override void WaterLevelMonitor()
        {
            base.WaterLevelMonitor();
            //增加AN tower监控逻辑
            _anWaterLevelLowerTrigger.CLK = _reservoirData.AnTowerLow;
            _anWaterLevelHighTrigger.CLK = _reservoirData.AnTowerHigh;
            if (_anWaterLevelLowerTrigger.Q  && !Recipe.ANDIReplenEnable)
            {
                LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"AN tower low is activate and recipe ANDIReplenEnable is false");
                //若recipe允许补水且res auto ,需要启动阳极自动补水
            }
            if (_anWaterLevelHighTrigger.Q && !Recipe.ANDIReplenEnable)
            {
                LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"AN tower high is activate and recipe ANDIReplenEnable is false");
            }
        }
        /// 
        /// 补水监控
        /// 
        protected override void AutoDireplenMonitor()
        {
            base.AutoDireplenMonitor();
        }
        /// 
        /// 阳极DI Replen On
        /// 
        /// 
        /// 
        /// 
        private bool ANDiReplenOnOperation(string cmd, object[] args)
        {
            return ANDiReplenOn();
        }
        /// 
        /// 阳极DI Replen On
        /// 
        /// 
        /// 
        private bool ANDiReplenOn()
        {
            bool preCondition = CheckPreDiReplenCondition();
            if (!preCondition)
            {
                return false;
            }
            if (IsANHighLevel)
            {
                LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"ANHighLevel is activate,Can't do AN_DIReple");
                return false;
            }
            if (IsANLowLevel)
            {
                LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"ANLowLevel is activate,Can't do AN_DIReple");
                return false;
            }
            if (ReservoirData.CaDiReplen)
            {
                LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "CADiReplen is on");
                return false;
            }
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{AN_DI_REPLEN}");
            return BeckhoffIOManager.Instance.WriteIoValue(ioName, true);
        }
        /// 
        /// 阳极DI Replen Off
        /// 
        /// 
        /// 
        /// 
        private bool ANDiReplenOff(string cmd, object[] args)
        {
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{AN_DI_REPLEN}");
            bool result = BeckhoffIOManager.Instance.WriteIoValue(ioName, false);
            if (result)
            {
                _persistentValue.IsDiReplenOn = false;
                if (_currentDireplenOperation == DiReplenOperation.ManualANDiReplen || _currentDireplenOperation == DiReplenOperation.AutoANDiReplen)
                {
                    _currentDireplenOperation = DiReplenOperation.None;
                    _persistentValue.LastTotalReplen = _persistentValue.TotalReplen;
                    ReservoirsPersistentManager.Instance.UpdatePersistentValue(Module);
                }
            }
            return result;
        }
        /// 
        /// 手动阳极注水
        /// 
        /// 
        /// 
        /// 
        private bool ManualANDiReplen(string cmd, object[] args)
        {
            return ManualDiReplen(ANDiReplenOnOperation, DiReplenOperation.ManualANDiReplen, args[0].ToString());
        }
    }
}