using Aitex.Core.RT.Device;
using Aitex.Core.RT.Log;
using CyberX8_Core;
using CyberX8_RT.Devices.Reservoir;
using CyberX8_RT.Modules.Reservoir;
using MECF.Framework.Common.Persistent.Reservoirs;
using MECF.Framework.Common.Persistent.Temperature;
using MECF.Framework.Common.RecipeCenter;
using System;
using System.Collections.Generic;
using System.Reflection;
using static CyberX8_RT.Devices.Reservoir.DosingSystemHelper;
namespace CyberX8_RT.Devices.Dose
{
    public class DosingCommonHelper
    {
        public enum DoseState
        {
            Init,
            Idle,
            Error,
            Initializing
        }
        #region 内部变量
        /// 
        /// ModuleName
        /// 
        private string _moduleName;
        /// 
        /// ReplenID
        /// 
        private int _replenNum;
        /// 
        /// StandardHotReservoirDevice 
        /// 
        private StandardHotReservoirDevice _shReservoirDevice;
        /// 
        /// 当前操作
        /// 
        private List _currentDosingOperation;
        /// 
        /// Replen Persistent Value
        /// 
        private Dictionary _persistentValue = new Dictionary();
        /// 
        /// DosingSystem初始化状态
        /// 
        private RState _initializeRState;
        /// 
        /// DosingSystemState
        /// 
        private string _dosingSystemState;
        /// 
        /// DosingSystemInitializeRoutine
        /// 
        private DosingSystemInitializeRoutine _dosingSystemInitializeRoutine;
        /// 
        /// DosingSystem是否已初始化
        /// 
        private bool _isDosingSystemInitialized;
        #endregion
        #region 属性
        /// 
        /// DosingSystem是否已经Initialized
        /// 
        public bool IsDosingSystemInitialized { get { return _isDosingSystemInitialized; } }
        /// 
        /// DosingSystem State
        /// 
        public string DosingSystemState { get { return _dosingSystemState; } }
        /// 
        /// DosingSystem Initialize State
        /// 
        public RState InitializeState { get { return _initializeRState; } }
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        public DosingCommonHelper(string moduleName, int replenNum)
        {
            _moduleName = moduleName;
            _replenNum = replenNum;
            _shReservoirDevice = DEVICE.GetDevice($"{_moduleName}");
            _currentDosingOperation = new List();
            for (int i = 0; i < _replenNum; i++)
            {
                string replenName = "Replen" + (i + 1).ToString();
                _currentDosingOperation.Add(DosingOperation.None);
                _persistentValue[replenName] = ReplenPersistentManager.Instance.GetReplenPersistentValue(_moduleName, replenName);
            }
            _dosingSystemInitializeRoutine = new DosingSystemInitializeRoutine(_moduleName);
            _dosingSystemState = DoseState.Init.ToString();
        }
        /// 
        /// AutoDose监控
        /// 
        public void AutoDoseSystemMonitor()
        {
            for (int i = 0; i < _replenNum; i++)
            {
                string replenName = "Replen" + (i + 1).ToString();
                if (_shReservoirDevice.ReplenDatas[i].IsAutoDosingError)
                {
                    //LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"{replenName} is in Error State");
                    continue;
                }
                //AutoDoing条件(1.自动模式 2.当前Recipe非空 3.Recipe未更换)
                RdsRecipe recipe = _shReservoirDevice.RdsRecipe[i];
                if (recipe != null && _shReservoirDevice.DosingSystemHelpers[i].CheckandLoadRecipe(recipe))
                {
                    //非AutoDosing模式下进入AutoDosing模式,并记录开始数据
                    if (_currentDosingOperation[i] != DosingOperation.AutoDosing)
                    {
                        LOG.WriteLog(eEvent.INFO_RESERVOIR, _moduleName, $"Timing of {replenName} AutoDosing has started now");
                        _shReservoirDevice.DosingSystemHelpers[i].RecordStartData();
                        _currentDosingOperation[i] = DosingOperation.AutoDosing;
                    }
                    else
                    {
                        //AutoDosing模式下,若上一次Dosing完成则再次记录数据
                        if (_persistentValue[replenName].AutoDosingStartTime == DateTime.MinValue
                            && _persistentValue[replenName].AutoDosingStartAmpHour == 0)
                        {
                            LOG.WriteLog(eEvent.INFO_RESERVOIR, _moduleName, $"Timing of {replenName} AutoDosing has started again now");
                            _shReservoirDevice.DosingSystemHelpers[i].RecordStartData();
                        }
                    }
                }
                else
                {
                    _currentDosingOperation[i] = DosingOperation.None;
                }
                //AutoDosing监控
                if (!_persistentValue[replenName].IsDosingRunning && _currentDosingOperation[i] == DosingOperation.AutoDosing
                    && _shReservoirDevice.DosingSystemHelpers[i].AutoDosingMonitor())
                {
                    _shReservoirDevice.DosingSystemHelpers[i].StartDosing(_shReservoirDevice.DosingSystemHelpers[i].AutoDosingVolume, true);
                }
            }
        }
        /// 
        /// ManualDose监控
        /// 
        public void ManualDoseSystemMonitor()
        {
            for (int i = 0; i < _replenNum; i++)
            {
                string replenName = "Replen" + (i + 1).ToString();
                if (_currentDosingOperation[i] == DosingOperation.ManualDosing && !_persistentValue[replenName].IsDosingRunning)
                {
                    _currentDosingOperation[i] = DosingOperation.None;
                }
                else if (_currentDosingOperation[i] == DosingOperation.ManualDosing && _persistentValue[replenName].IsDosingRunning)
                {
                    continue;
                }
            }
        }
        public void CheckDoseOperation()
        {
            for (int i = 0; i < _replenNum; i++)
            {
                if (_currentDosingOperation[i] == DosingOperation.AutoDosing)
                {
                    _currentDosingOperation[i] = DosingOperation.None;
                }
            }
        }
        /// 
        /// Dose状态监控
        /// 
        public void DoseStatusMonitor()
        {
            //DosingSystem Initialize监控
            if (_initializeRState == RState.Running)
            {
                DosingInitializingMonitor();
            }
            for (int i = 0; i < _replenNum; i++)
            {
                string replenName = "Replen" + (i + 1).ToString();
                RState state = _shReservoirDevice.DosingSystemHelpers[i].DosingState;
                if (state == RState.Running)
                {
                    _shReservoirDevice.DosingSystemHelpers[i].DosingTimeOutMonitor();
                }
                else if(state == RState.Failed || state == RState.Timeout)
                {
                    if (_shReservoirDevice.ReplenDatas[i].ReplenPumpEnable)
                    {
                        Object[] args = new object[1];
                        args[0] = replenName;
                        bool result = _shReservoirDevice.ReplenPumpOffOperation("", args);
                        if (result)
                        {
                            LOG.WriteLog(eEvent.INFO_RESERVOIR, _moduleName, "Replen Pump Off");
                        }
                    }
                }
                //BottleLevel监控
                if (_shReservoirDevice.ReplenDatas[i].BottleLevel != BottleLevelState.Warning.ToString())
                {
                    _shReservoirDevice.CheckandUpdateBottleLevel(replenName, -1, false);
                }
            }
        }
        /// 
        /// 监控DosingSystem初始化
        /// 
        /// 
        public void DosingInitializingMonitor()
        {
            _initializeRState = _dosingSystemInitializeRoutine.Monitor();
            if (_initializeRState == RState.Failed || _initializeRState == RState.Timeout)
            {
                _dosingSystemState = DoseState.Error.ToString();
            }
            if (_initializeRState == RState.End)
            {
                _isDosingSystemInitialized = true;
                _dosingSystemState = DoseState.Idle.ToString();
            }
        }
        /// 
        /// DosingSystem初始化
        /// 
        /// 
        /// 
        /// 
        public bool DosingInitialize()
        {
            _dosingSystemState = DoseState.Initializing.ToString();
            _isDosingSystemInitialized = false;
            _initializeRState = _dosingSystemInitializeRoutine.Start();
            if (_initializeRState == RState.Running) return true;
            return false;
        }
        /// 
        /// Enetr Init State
        /// 
        /// 
        /// 
        /// 
        public bool DosingEnterInit()
        {
            if (_dosingSystemState == DoseState.Idle.ToString())
            {
                _dosingSystemState = DoseState.Init.ToString();
            }
            _isDosingSystemInitialized = false;
            return true;
        }
    }
}