using Aitex.Core.RT.Device;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.SCCore;
using CyberX8_RT.Devices.Facilities;
using MECF.Framework.Common.Alarm;
using MECF.Framework.Common.Persistent.Reservoirs;
using MECF.Framework.Common.RecipeCenter;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace CyberX8_RT.Devices.Reservoir
{
    public class ReservoirDiReplenHelper
    {
        #region 内部变量
        /// 
        /// 模块名称
        /// 
        private string _module;
        /// 
        /// 持久化对象
        /// 
        private ReservoirsPersistentValue _persistentValue;
        /// 
        /// 锁
        /// 
        private object _locker = new object();
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        /// 
        /// 
        public ReservoirDiReplenHelper(string module, ReservoirsPersistentValue persistentValue)
        {
            _module = module;
            _persistentValue = persistentValue;
        }
        /// 
        /// 监控
        /// 
        public void MonitorPeriodTime(Action timeOutAction)
        {
            double levelHysteresis = SC.GetValue("Reservoir.LevelHysteresis");
            double diValveMaxOnTimePeriod = SC.GetValue($"Reservoir.{_module}.DIValveMaxOnTimePeriod");
            //没有在注水
            if (_persistentValue != null && !_persistentValue.IsDiReplenOn)
            {
                //超过时间
                if (DateTime.Now.Subtract(_persistentValue.PeriodStartTime).TotalMinutes >= diValveMaxOnTimePeriod * 60)
                {
                    LOG.WriteLog(eEvent.INFO_RESERVOIR, _module, $"Time is over config DIValveMaxOnTimePeriod:{diValveMaxOnTimePeriod} hour. Restart timer");
                    timeOutAction(false);
                    _persistentValue.PeriodStartTime = DateTime.Now;
                    _persistentValue.TotalReplen = 0;
                    _persistentValue.LastTotalReplen = 0;
                    ReservoirsPersistentManager.Instance.UpdatePersistentValue(_module);
                }
            }
        }
        /// 
        /// 监控手动注水
        /// 
        public bool MonitorManualDiReplenComplete(int replenSecond, Func direplenOffAction, Action timeOutAction)
        {
            lock (_locker)
            {
                _persistentValue.TotalReplen = _persistentValue.LastTotalReplen + (int)DateTime.Now.Subtract(_persistentValue.DiReplenTime).TotalSeconds;
            }
            //周期内累计补水超时
            double diValveMaxOnTime = SC.GetValue($"Reservoir.{_module}.DIValveMaxOnTime");
            if (_persistentValue.TotalReplen >= diValveMaxOnTime * 60)
            {
                bool result = direplenOffAction("", null);
                if (result)
                {
                    timeOutAction(true);
                    LOG.WriteLog(eEvent.WARN_RESERVOIR, _module, $"Direplen time over config DIValveMaxOnTime:{diValveMaxOnTime} min");
                    _persistentValue.LastTotalReplen = _persistentValue.TotalReplen;
                    _persistentValue.IsDiReplenOn = false;
                    ReservoirsPersistentManager.Instance.UpdatePersistentValue(_module);
                }
                return result;
            }
            if (DateTime.Now.Subtract(_persistentValue.DiReplenTime).TotalSeconds >= replenSecond)
            {
                bool result = direplenOffAction("", null);
                if (result)
                {
                    timeOutAction(true);
                    _persistentValue.LastTotalReplen = _persistentValue.TotalReplen;
                    _persistentValue.IsDiReplenOn = false;
                    ReservoirsPersistentManager.Instance.UpdatePersistentValue(_module);
                    LOG.WriteLog(eEvent.INFO_RESERVOIR, _module, "Manual Direplen complete");
                }
                return result;
            }
            return false;
        }
        /// 
        /// 自动注水超时
        /// 
        /// 
        public (bool, DIReplenFaultType) AutoDiReplenMonitorTimeOut(Func direplenOffAction, Action timeOutAction)
        {
            lock (_locker)
            {
                _persistentValue.TotalReplen = _persistentValue.LastTotalReplen + (int)DateTime.Now.Subtract(_persistentValue.DiReplenTime).TotalSeconds;
            }
            //单次自动补水超时
            double diValveMaxOnTimePerFill = SC.GetValue($"Reservoir.{_module}.DIValveMaxOnTimePerFill");
            if (DateTime.Now.Subtract(_persistentValue.DiReplenTime).TotalSeconds >= diValveMaxOnTimePerFill * 60)
            {
                bool result = direplenOffAction("", null);
                if (result)
                {
                    AlarmListManager.Instance.AddWarn(_module, $"", $"{_module} Direplen time over config DIValveMaxOnTimePerFill:{diValveMaxOnTimePerFill} min");
                    LOG.WriteLog(eEvent.WARN_RESERVOIR, _module, $"Direplen time over conifg DIValveMaxOnTimePerFill:{diValveMaxOnTimePerFill} min");
                    //补水超时关闭总的补水阀
                    SystemFacilities systemFacilities = DEVICE.GetDevice("System.Facilities");
                    if (systemFacilities != null)
                    {
                        if (systemFacilities.DIReplenEnable) systemFacilities.DiReplenDisableOperation("DiReplenDisableOperation", null);
                    }
                    _persistentValue.LastTotalReplen = _persistentValue.TotalReplen;
                    _persistentValue.IsDiReplenOn = false;
                    ReservoirsPersistentManager.Instance.UpdatePersistentValue(_module);
                }
                return (result, DIReplenFaultType.PerFillTimeOut);
            }
            //累计补水超时
            double diValveMaxOnTime = SC.GetValue($"Reservoir.{_module}.DIValveMaxOnTime");
            if (_persistentValue.TotalReplen >= diValveMaxOnTime * 60)
            {
                bool result = direplenOffAction("", null);
                if (result)
                {
                    timeOutAction(true);
                    AlarmListManager.Instance.AddWarn(_module, $"", $"{_module} Direplen time over config DIValveMaxOnTime:{diValveMaxOnTime} min");
                    LOG.WriteLog(eEvent.WARN_RESERVOIR, _module, $"Direplen time over conifg DIValveMaxOnTime:{diValveMaxOnTime} min");
                    _persistentValue.LastTotalReplen = _persistentValue.TotalReplen;
                    _persistentValue.IsDiReplenOn = false;
                    ReservoirsPersistentManager.Instance.UpdatePersistentValue(_module);
                }
                return (result, DIReplenFaultType.MaxTimeOut);
            }
            return (false, DIReplenFaultType.None);
        }
        /// 
        /// 自动注水是否结束
        /// 
        /// 
        /// 
        /// 
        /// 
        public bool AutoDiReplenMonitorComplete(double level, double recipeLevel, bool replenEnable,
            int direplenTimeRate, int direplenCurrentRate, Func direplenOffAction)
        {
            double levelHysteresis = SC.GetValue("Reservoir.LevelHysteresis");
            //按液位补水
            if (replenEnable && direplenTimeRate == 0 && direplenCurrentRate == 0 &&
                level >= recipeLevel)
            {
                LOG.WriteLog(eEvent.INFO_RESERVOIR, _module, "Auto replen complete");
                bool result = direplenOffAction("", null);
                if (result)
                {
                    _persistentValue.LastTotalReplen = _persistentValue.TotalReplen;
                    _persistentValue.IsDiReplenOn = false;
                    ReservoirsPersistentManager.Instance.UpdatePersistentValue(_module);
                    return result;
                }
            }
            return false;
        }
        public enum DIReplenFaultType
        {
            None,
            MaxTimeOut,
            PerFillTimeOut
        }
    }
}