using Aitex.Core.RT.DataCenter;
using Aitex.Core.RT.Device;
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.Prewet;
using MECF.Framework.Common.CommonData.Vpw;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.IOCore;
using MECF.Framework.Common.Persistent.SRD;
using MECF.Framework.Common.Persistent.Temperature;
using MECF.Framework.Common.Persistent.VpwCell;
using MECF.Framework.Common.Persistent.VpwMain;
using MECF.Framework.Common.ToolLayout;
using MECF.Framework.Common.Utilities;
using PunkHPX8_RT.Devices.AXIS;
using PunkHPX8_RT.Devices.Resistivity;
using PunkHPX8_RT.Devices.VpwMain;
using PunkHPX8_RT.Modules;
using PunkHPX8_RT.Modules.Reservoir;
using PunkHPX8_RT.Modules.VpwMain;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace PunkHPX8_RT.Devices.VpwCell
{
    public class VpwCellDevice : BaseDevice, IDevice
    {
        #region 常量 
        private const string COMMON_DATA = "CommonData";
        private const string DIW_FLOW = "DiwFlow";
        private const string VACUUM_PRESSURE = "VacuumPressure";
        private const string FLOW_DRIP = "FlowDrip";
        private const string FLOW_SMALL = "FlowSmall";
        private const string FLOW_LARGE = "FlowLarge";
        private const string VACUUM_VALVE = "VacuumValve";
        private const string VENT_VALVE = "VentValve";
        private const string DRAIN_VALVE = "DrainValve";
        private const string PERSISTENT_VALUE = "PersistentValue";
        private const string LOOPDO_VALUE = "LoopDoValue";
        #endregion
        #region 内部变量
        /// 
        /// 变量是否初始化字典
        /// 
        private Dictionary _variableInitializeDic = new Dictionary();
        /// 
        /// 数据
        /// 
        private VpwCellCommonData _commonData=new VpwCellCommonData();
        /// Vpw main数据
        /// 
        private VpwMainCommonData _mainCommonData = new VpwMainCommonData();
        /// 
        /// 持久性数值
        /// 
        private VpwCellPersistentValue _vpwCellPersistentValue;
        /// 
        /// 水平电机
        /// 
        private JetAxisBase _rotationAxis;
        /// 
        /// 水阻计控制器
        /// 
        private ResistivityController _resistivityController;
        /// 
        /// 水阻值
        /// 
        private double _resistivityValue;
        /// 
        /// main device
        /// 
        private VpwMainDevice _vpwMainDevice;
        /// 
        /// cell flow 初始设定值
        /// 
        private double _cellFlowSetValue;
        /// 
        /// total flow 初始设定值
        /// 
        private double _totalFlowSetValue;
        /// 
        /// total流量满足初始设定值自动打开排水阀的时间
        /// 
        private int _dripValveOpenIdlePeriod;
        /// 
        /// 检测到total flow 满足设定条件的时间
        /// 
        private DateTime _totalFlowOkDetectTime;
        /// 
        /// 是否在检测totalflow的周期中
        /// 
        private bool _isIntotalFlowCheck=false;
        #endregion
        #region 属性
        /// 
        /// 数据
        /// 
        public VpwCellCommonData CommonData { get { return _commonData; } }
        /// 
        /// vpw main数据
        /// 
        public VpwMainCommonData MainCommonData { get { return _mainCommonData; } }
        /// 
        /// 操作模式
        /// 
        public string OperationMode { get { return _vpwCellPersistentValue.OperatingMode; } }
        /// 
        /// 工程模式
        /// 
        public string EngineerMode { get { return _vpwCellPersistentValue.RecipeOperatingMode; } }
        /// 
        /// LoopDO数值
        /// 
        public double LoopDOValue { get { return GetLoopDOValue(); } }
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        public VpwCellDevice(string moduleName) : base(moduleName, moduleName, moduleName, moduleName)
        {
    
        }
        #region 初始化
        /// 
        /// 初始化
        /// 
        /// 
        public bool Initialize()
        {
            InitializeParameter();
            InitializeRoutine();
            SubscribeData();
            SubscribeValueAction();
            InitializeOperation();
            return true;
        }
        /// 
        /// 初始化参数
        /// 
        private void InitializeParameter()
        {
            _rotationAxis = DEVICE.GetDevice($"{Module}.Rotation");
            _vpwCellPersistentValue = VpwCellPersistentManager.Instance.GetPersistentValue(Module);     
            VpwCellItem vpwCellItem=VpwCellItemManager.Instance.GetVpwItem(Module);
            if (vpwCellItem != null)
            {
                _resistivityController = DEVICE.GetDevice(vpwCellItem.ResistivityID);
            }
            _vpwMainDevice = DEVICE.GetDevice($"VPWMain1");
            if(_vpwMainDevice != null)
            {
                _mainCommonData = _vpwMainDevice.CommonData;
            }
        }
        /// 
        /// 初始化Routine
        /// 
        private void InitializeRoutine()
        {
        }
        /// 
        /// 订阅
        /// 
        private void SubscribeData()
        {
            DATA.Subscribe($"{Module}.{COMMON_DATA}", () => CommonData, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.{PERSISTENT_VALUE}", () => _vpwCellPersistentValue, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.DiwCellFlow", () => CommonData.DiwFlow, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.VacuumValve", () => CommonData.VacuumValve, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.{LOOPDO_VALUE}", ()=> { return GetLoopDOValue(); }, SubscriptionAttribute.FLAG.IgnoreSaveDB);
        }
        /// 
        /// 获取Loop do数值
        /// 
        /// 
        private double GetLoopDOValue()
        {
            if (_resistivityController != null)
            {
                string value = _resistivityController.ResisitivityValue;
                if (double.TryParse(value, out _resistivityValue))
                {
                    return _resistivityValue;
                }
                else
                {
                    _resistivityValue = 0;
                    return 0;
                }
            }
            else
            {
                return 0;
            }
        }
        /// 
        /// 订阅数据
        /// 
        private void SubscribeValueAction()
        {
            IoSubscribeUpdateVariable(DIW_FLOW);
            IoSubscribeUpdateVariable(DRAIN_VALVE);
            IoSubscribeUpdateVariable(VACUUM_PRESSURE);
            IoSubscribeUpdateVariable(VACUUM_VALVE);
            IoSubscribeUpdateVariable(VENT_VALVE);
            IoSubscribeUpdateVariable(FLOW_DRIP);
            IoSubscribeUpdateVariable(FLOW_LARGE);
            IoSubscribeUpdateVariable(FLOW_SMALL);
        }
        /// 
        /// 初始化变量
        /// 
        /// 
        private void IoSubscribeUpdateVariable(string variable)
        {
            _variableInitializeDic[variable] = false;
            IOModuleManager.Instance.SubscribeModuleVariable(Module, variable, UpdateVariableValue);
        }
        /// 
        /// 更新变量数值
        /// 
        /// 
        /// 
        private void UpdateVariableValue(string variable, object value)
        {
            PropertyInfo property = _commonData.GetType().GetProperty(variable);
            if (property != null)
            {
                property.SetValue(_commonData, value);
                if (variable == VACUUM_PRESSURE)
                {
                    double torr = UnitUtil.ConvertToTorr((double)value);
                    property.SetValue(_commonData, torr);
                }
            }
            if (_variableInitializeDic.ContainsKey(variable) && !_variableInitializeDic[variable])
            {
                _variableInitializeDic[variable] = true;
            }
        }
        /// 
        /// 初始化OP
        /// 
        private void InitializeOperation()
        {
            OP.Subscribe($"{Module}.FlowDripOn", (cmd,para)=> { return FlowDripOn(); });
            OP.Subscribe($"{Module}.FlowDripOff", (cmd, para) => { return FlowDripOff(); });
            OP.Subscribe($"{Module}.FlowSmallOn", (cmd, para) => { return FlowSmallOn(); });
            OP.Subscribe($"{Module}.FlowSmallOff", (cmd, para) => { return FlowSmallOff(); });
            OP.Subscribe($"{Module}.FlowLargeOn", (cmd, para) => { return FlowLargeOn(); });
            OP.Subscribe($"{Module}.FlowLargeOff", (cmd, para) => { return FlowLargeOff(); });
            OP.Subscribe($"{Module}.VentValveOn", (cmd, para) => { return VentValveOn(); });
            OP.Subscribe($"{Module}.VentValveOff", (cmd, para) => { return VentValveOff(); });
            OP.Subscribe($"{Module}.DrainValveOn", (cmd, para) => { return DrainValveOn(); });
            OP.Subscribe($"{Module}.DrainValveOff", (cmd, para) => { return DrainValveOff(); });
            OP.Subscribe($"{Module}.VacuumValveOn", (cmd, para) => { return VacuumValveOn(); });
            OP.Subscribe($"{Module}.VacuumValveOff", (cmd, para) => { return VacuumValveOff(); });
            OP.Subscribe($"{Module}.DisabledAction", DisabledOperation);
            OP.Subscribe($"{Module}.ManualAction", ManualOperation);
            OP.Subscribe($"{Module}.AutoAction", AutoOperation);
            OP.Subscribe($"{Module}.EngineeringModeAction", EngineeringModeOperation);
            OP.Subscribe($"{Module}.ProductionModeAction", ProductionModeOperation);
            
            OP.Subscribe($"{Module}.StartRotation", StartRotationAction);
            OP.Subscribe($"{Module}.StopRotation", StopRotationAction);
        }
        #endregion
        #region Action
        private bool StartRotationAction(string cmd, object[] args)
        {
            if (args.Length < 2 && (int)args[0] < 0 && (int)args[1] < 0)
            {
                LOG.WriteLog(eEvent.ERR_VPW, Module, $"Start rotation paramater is wrong");
                return false;
            }
            double targetPostion = (int)args[0]  * 6 * (int)args[1];
            object[] param = new object[] { "",targetPostion };
            int degSpeed = (int)args[0] * 6;
            SetRotationSpeed(degSpeed);
            //return _rotationAxis.JogUpPosition("", param);
            double AfterChangetargetPostion = (int)args[0] * 6 * (int)args[1];
            return RotationProfilePosition(AfterChangetargetPostion);
        }
        private bool StopRotationAction(string cmd, object[] args)
        {
            return _rotationAxis.StopPositionOperation();
        }
        #region Flow
        /// 
        /// Flow Drip on
        /// 
        /// 
        public bool FlowDripOn()
        {
            return WriteVariableValue(FLOW_DRIP, true);
        }
        /// 
        /// Flow Drip Off
        /// 
        /// 
        public bool FlowDripOff()
        {
            return WriteVariableValue(FLOW_DRIP, false);
        }
        /// 
        /// Flow Small On
        /// 
        /// 
        public bool FlowSmallOn()
        {
            return WriteVariableValue(FLOW_SMALL, true);
        }
        /// 
        /// Flow Small Off
        /// 
        /// 
        public bool FlowSmallOff()
        {
            return WriteVariableValue(FLOW_SMALL, false);
        }
        /// 
        /// Flow Large On
        /// 
        /// 
        public bool FlowLargeOn()
        {
            return WriteVariableValue(FLOW_LARGE, true);
        }
        /// 
        /// Flow Large Off
        /// 
        /// 
        public bool FlowLargeOff()
        {
            return WriteVariableValue(FLOW_LARGE, false);
        }
        #endregion
        #region Mode Switch
        /// 
        /// DisabledAction
        /// 
        /// 
        /// 
        /// 
        private bool DisabledOperation(string cmd, object[] args)
        {
            string currentOperation = "Disabled";
            VpwCellEntity vpwCellEntity = Singleton.Instance.GetModule(Module);
            if (vpwCellEntity != null && _vpwCellPersistentValue != null && _vpwCellPersistentValue.OperatingMode != currentOperation)
            {
                string preOperation = _vpwCellPersistentValue.OperatingMode;
                if (vpwCellEntity.IsBusy)
                {
                    LOG.WriteLog(eEvent.ERR_VPWMAIN, Module, $"{Module} is Busy, can't switch to Disabled mode");
                    return false;
                }
                vpwCellEntity.EnterInit();
                _vpwCellPersistentValue.OperatingMode = currentOperation;
                LOG.WriteLog(eEvent.INFO_VPWMAIN, Module, $"Operating mode is switched from {preOperation} to {currentOperation}");
            }
            VpwCellPersistentManager.Instance.UpdatePersistentValue(Module);
            return true;
        }
        /// 
        /// ManualAction
        /// 
        /// 
        /// 
        /// 
        private bool ManualOperation(string cmd, object[] args)
        {
            string currentOperation = "Manual";
            VpwCellEntity vpwCellEntity = Singleton.Instance.GetModule(Module);
            if (vpwCellEntity != null && _vpwCellPersistentValue != null && _vpwCellPersistentValue.OperatingMode != currentOperation)
            {
                string preOperation = _vpwCellPersistentValue.OperatingMode;
                if (vpwCellEntity.IsBusy)
                {
                    LOG.WriteLog(eEvent.ERR_VPWMAIN, Module, $"{Module} is Busy, can't switch to Manual mode");
                    return false;
                }
                vpwCellEntity.EnterInit();
                _vpwCellPersistentValue.OperatingMode = currentOperation;
                LOG.WriteLog(eEvent.INFO_VPWMAIN, Module, $"Operating mode is switched from {preOperation} to {currentOperation}");
            }
            VpwCellPersistentManager.Instance.UpdatePersistentValue(Module);
            return true;
        }
        /// 
        /// AutoAction
        /// 
        /// 
        /// 
        /// 
        private bool AutoOperation(string cmd, object[] args)
        {
            string currentOperation = "Auto";
            VpwCellEntity vpwCellEntity = Singleton.Instance.GetModule(Module);
            if (vpwCellEntity != null && _vpwCellPersistentValue != null && _vpwCellPersistentValue.OperatingMode != currentOperation)
            {
                string preOperation = _vpwCellPersistentValue.OperatingMode;
                if (vpwCellEntity.IsBusy)
                {
                    LOG.WriteLog(eEvent.ERR_VPWMAIN, Module, $"{Module} is Busy, can't switch to Auto mode");
                    return false;
                }
                vpwCellEntity.EnterInit();
                _vpwCellPersistentValue.OperatingMode = currentOperation;
                LOG.WriteLog(eEvent.INFO_VPWMAIN, Module, $"Operating mode is switched from {preOperation} to {currentOperation}");
            }
            VpwCellPersistentManager.Instance.UpdatePersistentValue(Module);
            return true;
        }
        /// 
        /// EngineeringModeAction
        /// 
        /// 
        /// 
        /// 
        private bool EngineeringModeOperation(string cmd, object[] args)
        {
            string currentRecipeOperation = "Engineering";
            if (_vpwCellPersistentValue != null)
            {
                _vpwCellPersistentValue.RecipeOperatingMode = currentRecipeOperation;
            }
            VpwCellPersistentManager.Instance.UpdatePersistentValue(Module);
            return true;
        }
        /// 
        /// ProductionAction
        /// 
        /// 
        /// 
        /// 
        private bool ProductionModeOperation(string cmd, object[] args)
        {
            string currentRecipeOperation = "Production";
            if (_vpwCellPersistentValue != null)
            {
                _vpwCellPersistentValue.RecipeOperatingMode = currentRecipeOperation;
            }
            VpwCellPersistentManager.Instance.UpdatePersistentValue(Module);
            return true;
        }
        #endregion
        #region Vent Valve
        /// 
        /// Vent Valve On
        /// 
        /// 
        public bool VentValveOn()
        {
            return WriteVariableValue(VENT_VALVE, true);
        }
        /// 
        /// Vent Valve Off
        /// 
        /// 
        public bool VentValveOff()
        {
            return WriteVariableValue(VENT_VALVE, false);
        }
        #endregion
        #region Drain Valve
        /// 
        /// Drain Valve On
        /// 
        /// 
        public bool DrainValveOn()
        {
            return WriteVariableValue(DRAIN_VALVE, true);
        }
        /// 
        /// Drain Valve Off
        /// 
        /// 
        public bool DrainValveOff()
        {
            return WriteVariableValue(DRAIN_VALVE, false);
        }
        #endregion
        #region Vacuum
        /// 
        /// Vacuum valve on
        /// 
        /// 
        public bool VacuumValveOn()
        {
            return WriteVariableValue(VACUUM_VALVE, true);
        }
        /// 
        /// Vacuum valve off
        /// 
        /// 
        public bool VacuumValveOff()
        {
            return WriteVariableValue(VACUUM_VALVE, false);
        }
        #endregion
        /// 
        /// 写变量
        /// 
        /// 
        /// 
        /// 
        private bool WriteVariableValue(string variable, object value)
        {
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{variable}");
            return IOModuleManager.Instance.WriteIoValue(ioName, value);
        }
        #endregion
        #region Axis
        /// 
        /// 电机是否上电
        /// 
        /// 
        public bool CheckRotationSwitchOn()
        {
            return _rotationAxis.IsSwitchOn;
        }
        /// 
        /// Home rotation
        /// 
        /// 
        public bool HomeRotation()
        {
            return _rotationAxis.Home();
        }
        /// 
        /// 检验Rotation Home结果
        /// 
        /// 
        public bool CheckHomeEndStatus()
        {
            return CheckRotationEndStatus() && _rotationAxis.IsHomed;
        }
        /// 
        /// 检验Rotation结束状态
        /// 
        /// 
        public bool CheckRotationEndStatus()
        {
            return _rotationAxis.Status == PunkHPX8_Core.RState.End;
        }
        /// 
        /// 检验Rotation失败状态
        /// 
        /// 
        public bool CheckRotationStopStatus()
        {
            return _rotationAxis.Status == PunkHPX8_Core.RState.Failed;
        }
        /// 
        /// 设置速度
        /// 
        /// 
        /// 
        public bool SetRotationSpeed(int speed)
        {
            _rotationAxis.SetProfileSpeed(speed);
            return true;
        }
        /// 
        /// 改变速度
        /// 
        /// 
        /// 
        public bool ChangeRotationSpeed(int speed)
        {
            return _rotationAxis.ChangeSpeed(speed);
        }
        /// 
        /// 电机运动
        /// 
        /// 
        /// 
        public bool RotationProfilePosition(double position)
        {
            VpwMainDevice vpwMainDevice = DEVICE.GetDevice(ModuleName.VPWMain1.ToString());
            if (vpwMainDevice != null)
            {
                if (vpwMainDevice.CommonData.ChamberOpened && !vpwMainDevice.CommonData.ChamberClosed)
                {
                    LOG.WriteLog(eEvent.ERR_AXIS, $"{Module}.{Name}", "chamber is not closed, Cannot execute Rotation Profile Position");
                    return false;
                }
            }
            return _rotationAxis.ProfilePositionOperation(position);
        }
        /// 
        /// 停止运动 
        /// 
        /// 
        public bool StopProfilePosition()
        {
            return _rotationAxis.StopPositionOperation();
        }
        /// 
        /// 是否Rotation运动
        /// 
        /// 
        public bool CheckRotationRunning()
        {
            return _rotationAxis.IsRun;
        }
        #endregion
        /// 
        /// 定时器
        /// 
        /// 
        public bool OnTimer()
        {
            if (_rotationAxis != null)
            {
                _rotationAxis.OnTimer();
            }
            //cell flow满足条件过一段时间自动打开排水阀 (非run recipe期间)
            VpwCellEntity vpwcellEntity = Singleton.Instance.GetModule(Module);
            if(vpwcellEntity != null && vpwcellEntity.IsIdle)
            {
                CellFlowMonitor();
            }
            else
            {
                _isIntotalFlowCheck = false;
            }
            return true;
        }
        //cell flow满足条件过一段时间自动打开drip阀
        private void CellFlowMonitor()
        {
            _cellFlowSetValue = SC.GetValue("VPWMain.Plumbing.CellFlowStartLowLimit");
            _totalFlowSetValue = SC.GetValue("VPWMain.Plumbing.TotalFlowStartLowLimit");
            _dripValveOpenIdlePeriod = SC.GetValue($"{Module}.DripValveOpenIdlePeriod");
            if (MainCommonData.DiwTotalFlow > _totalFlowSetValue)
            {
                if (!_isIntotalFlowCheck)
                {
                    _totalFlowOkDetectTime = DateTime.Now;
                    _isIntotalFlowCheck = true;
                }
                else if((DateTime.Now - _totalFlowOkDetectTime).TotalSeconds > (_dripValveOpenIdlePeriod * 60) && !_commonData.FlowDrip)
                {
                    _isIntotalFlowCheck = false;//重置监控周期
                    LOG.WriteLog(eEvent.INFO_VPW, Module, $"total flow is large than start limit more than {_dripValveOpenIdlePeriod} min,Drip valve on!");
                    FlowDripOn();
                    if(_commonData.DiwFlow <= 0)
                    {
                        LOG.WriteLog(eEvent.WARN_VPW, Module, $"Drip valve open failed!");
                    }
                }
            }
            
        }
        /// 
        /// 监控
        /// 
        public void Monitor()
        {
        }
        public void Reset()
        {
        }
        public void Terminate()
        {
        }
    }
}