using Aitex.Core.RT.Device;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.Routine;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using PunkHPX8_Core;
using PunkHPX8_RT.Devices.Dose;
using PunkHPX8_RT.Modules;
using PunkHPX8_RT.Modules.Reservoir;
using MECF.Framework.Common.Beckhoff.ModuleIO;
using MECF.Framework.Common.IOCore;
using MECF.Framework.Common.Persistent.Reservoirs;
using MECF.Framework.Common.ProcessCell;
using MECF.Framework.Common.RecipeCenter;
using MECF.Framework.Common.ToolLayout;
using MECF.Framework.Common.TwinCat;
using System;
using System.Reflection;
using System.Windows;
using static PunkHPX8_RT.Devices.Reservoir.DosingSystemHelper;
namespace PunkHPX8_RT.Devices.Reservoir
{
    public class CrossDoseHelper
    {
        #region 常量        
        public enum CrossDoseOperation
        {
            None,
            ManualDosing,
            AutoDosing,
        }
        /// 
        /// 补液体积(固定10mL)
        /// 
        private const double DOSING_VOLUME = 10;
        #endregion
        #region 内部变量
        /// 
        /// ModuleName
        /// 
        private string _moduleName;
        /// 
        /// CrossDoseResetRoutine
        /// 
        private CrossDoseResetRoutine _crossDoseResetRoutine;
        /// 
        /// ReservoirsPersistentValue
        /// 
        private ReservoirsPersistentValue _persistentValue;
        /// 
        /// CrossDoseVolume
        /// 
        private double _crossDoseVolume;
        /// 
        /// 当前CrossDose模式
        /// 
        private CrossDoseOperation _currentCrossDoseOperation;
        /// 
        /// Reservoir Usage
        /// 
        private ReservoirUsage _reservoirUsage;
        private bool _flag;
        #endregion
        #region 属性
        /// 
        /// 当前Dose模式
        /// 
        public CrossDoseOperation CurrentDoseOperation{ get {return _currentCrossDoseOperation; } }
        /// 
        /// ResetRoutine当前的RState
        /// 
        public RState ResetState { get { return _crossDoseResetRoutine.CurrentState; } }
        #endregion
        public CrossDoseHelper(string moduleName) 
        {
            _moduleName = moduleName;   
            _crossDoseResetRoutine = new CrossDoseResetRoutine(_moduleName);
            _persistentValue = ReservoirsPersistentManager.Instance.GetReservoirsPersistentValue(_moduleName);
            _currentCrossDoseOperation = CrossDoseOperation.None;
        }
        #region Operation
        /// 
        /// 开始Dosing
        /// 
        /// 
        public bool StartDosing(double crossDoseVolume)
        {
            return false;
        }
        /// 
        /// 停止Dosing
        /// 
        /// 
        public bool HaltDosing()
        {
            EnterError();
            return true;
        }
        /// 
        /// CrossDosing监控
        /// 
        public void CrossDoseStatusMonitor()
        {
            
        }
        /// 
        /// 自动CrossDose监控
        /// 
        public void AutoCrossDoseMonitor(bool isInitialized)
        {
            if (!isInitialized)
            {               
                if (!_flag)
                {
                    LOG.WriteLog(eEvent.WARN_RESERVOIR, _moduleName, "Please initialize Cross Dose");
                    _flag = true;
                }                
                return;
            }
            _flag = false;
        }
        /// 
        /// 自动补液触发时机判断
        /// 
        /// 
        private bool AutoDosingMonitor()
        {
            return true;
        }
        /// 
        /// 设置手动Dose模式
        /// 
        public void SetManualDoseOperation()
        {
            _currentCrossDoseOperation = CrossDoseOperation.ManualDosing;
        }
        /// 
        /// 设置自动Dose模式
        /// 
        public void SetAutoDoseOperation()
        {
            _currentCrossDoseOperation = CrossDoseOperation.AutoDosing;           
        }
        /// 
        /// 重置Dose模式
        /// 
        public void ResetDoseOperation()
        {
            _currentCrossDoseOperation = CrossDoseOperation.None;
        }
        /// 
        /// EnterError
        /// 
        private bool EnterError()
        {
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{_moduleName}.TransferPumpExecute");
            bool result = IOModuleManager.Instance.WriteIoValue(ioName, false);
            if (!result)
            {
                return false;
            }
            ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{_moduleName}.TransferPumpEnable");
            result = IOModuleManager.Instance.WriteIoValue(ioName, false);
            if (!result)
            {
                return false;
            }
            return true;
        }
        /// 
        /// 记录AutoCrossDose开始时的时间和电量
        /// 
        private void RecordStartData()
        {
            _reservoirUsage = ReservoirUsageManager.Instance.GetReservoirUsage(_moduleName);
            _persistentValue.AutoCrossDoseStartTime = DateTime.Now;
            if (_reservoirUsage != null) _persistentValue.AutoCrossDoseStartAmpHour = _reservoirUsage.TotalUsage;
            ReservoirsPersistentManager.Instance.UpdatePersistentValue(_moduleName);
        }
        /// 
        /// 设置PumpFactor
        /// 
        public void SetPumpfactor(double targetPumpFactor)
        {
            _persistentValue.CrossDosePumpFactor = targetPumpFactor;
            ReservoirsPersistentManager.Instance.UpdatePersistentValue(_moduleName);
        }
        /// 
        /// Reset Start
        /// 
        public bool ResetCrossDose()
        {                           
            return _crossDoseResetRoutine.Start() == RState.Running;
        }
        /// 
        /// Reset Start Monitor
        /// 
        /// 
        public bool ResetCrossDoseMonitor()
        {
            RState result = _crossDoseResetRoutine.Monitor();
            if (result == RState.Failed || result == RState.Timeout)
            {
                LOG.WriteLog(eEvent.WARN_RESERVOIR, _moduleName, "Reset Cross Dose failed");
                return false;
            }
            return result == RState.End;
        }
        #endregion
    }
}