using Aitex.Core.RT.Event;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using System;
using System.Collections.Generic;

namespace MECF.Framework.Common.Aitex.Core.RT.EMS
{
    public class Maintainer : IMaintainer
    {
        #region Variables

        /// <summary>
        /// 触发保养等级是否为Warning
        /// </summary>
        protected bool _isWarning = false;
        /// <summary>
        /// 确认监控部件消耗中
        /// </summary>
        protected Func<bool> _getProcessing = ()=> true;
        /// <summary>
        /// 保养触发器相关信息
        /// </summary>
        protected MaintainerInfo _info = new();
        /// <summary>
        /// 开始时间
        /// </summary>
        protected DateTime _startDate = DateTime.Now;
        /// <summary>
        /// 阈值到达时间
        /// </summary>
        protected DateTime? _trigDate = null;
        /// <summary>
        /// 记录值
        /// </summary>
        protected double _value = 0;
        /// <summary>
        /// 记录剩余值
        /// </summary>
        protected double _valueElapsed = 0;
        /// <summary>
        /// 记录超出值
        /// </summary>
        protected double _valueExceed = 0;
        /// <summary>
        /// 触发标志
        /// </summary>
        protected bool _isTimeOut = false;
        /// <summary>
        /// 触发后超出时间
        /// </summary>
        protected double _timeExceed = 0;
        /// <summary>
        /// 触发器上升沿
        /// </summary>
        protected readonly R_TRIG _trigTimeOut = new();
        /// <summary>
        /// 记录值门槛
        /// </summary>
        protected double _threshold = 1000000;
        /// <summary>
        /// 保养项集合
        /// </summary>
        protected MaintainerItemCollection _itemCollection = new();

        /// <summary>
        /// 未点检保养项个数
        /// </summary>
        protected int _unMaintainedCount => _itemCollection.UnMaintainCount;

        protected int _totalCount => _itemCollection.Count;

        protected bool _isProcessing = false;
        #endregion

        public delegate bool Save();

        public event Save OnSave;

        #region Constructors

        public Maintainer()
        {
            SC.RegisterValueChangedCallback("System.IgnoreMaintainTimeOutWarning", (newValue) =>
            {
                bool.TryParse(newValue.ToString(), out _isWarning);
            });

            _itemCollection = new MaintainerItemCollection();
        }

        public Maintainer(MaintainerItemCollection item, string name, string module, int index, string description, bool enabled, DateTime startdate, double threshold, TimeUnit timedisplayunit)
        {
            SC.RegisterValueChangedCallback("System.IgnoreMaintainTimeOutWarning", (newValue) =>
            {
                bool.TryParse(newValue.ToString(), out _isWarning);
            });

            _itemCollection = item;

            _threshold = threshold;
            _startDate = startdate;

            _info = new MaintainerInfo(_itemCollection.GetAllItemInfos(), name, module, index, description, enabled, startdate, threshold, timedisplayunit);
        }

        public Maintainer(MaintainerItemCollection item, MaintainerInfo info, DateTime startdate, double threshold)
        {
            SC.RegisterValueChangedCallback("System.IgnoreMaintainTimeOutWarning", (newValue) =>
            {
                bool.TryParse(newValue.ToString(), out _isWarning);
            });

            _itemCollection = item;

            _threshold = threshold;
            _startDate = startdate;

            _info = new MaintainerInfo(_itemCollection.GetAllItemInfos(), info, startdate, threshold);
        }

        #endregion

        #region Function

        /// <summary>
        /// 触发OnSave委托
        /// </summary>
        /// <returns></returns>
        public virtual bool Reset()
        {
            OnSave?.Invoke();
            return true;

        }

        /// <summary>
        /// 阈值设置
        /// </summary>
        /// <param name="threshold"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public virtual bool SetThreshold(double threshold ,params object[] args)
        {
            if (threshold <= 0)
            {
                EV.PostWarningLog("Maintenance", $"threshold must be greater than zero");
                return false;
            }
            return true;
        }

        /// <summary>
        /// 计算剩余时间和超时时间，不同类算法不同，需要重载
        /// </summary>
        public virtual void Monitor()
        {
            _isProcessing = _getProcessing?.Invoke() ?? false;

            _trigTimeOut.CLK = _isTimeOut;

            if (_trigTimeOut.Q)
            {
                if (_isWarning)
                    EV.PostWarningLog("Maintenance", $"Plan {_info.Name} reach the deadline, please check as soon as possible.");
                else
                    EV.PostInfoLog("Maintenance", $"Plan {_info.Name} reach the deadline, please check as soon as possible.");
            }

        }

        /// <summary>
        /// 更新Info的数据
        /// </summary>
        public virtual void UpdateInfo()
        {
            _info.StartDate = _startDate;
            _info.IsTrigger = _isTimeOut;
            _info.IsProcessing = _isProcessing;
            _info.TrigDate = _trigDate;
            _info.UnMaintainedCount = _unMaintainedCount;
            _info.TotalCount = _totalCount;
            _info.TimeExceed = DateTimeHelper.SecondsTransform(_timeExceed, _info.TimeDisplayUnit);

        }

        /// <summary>
        /// 更新Info的数据
        /// </summary>
        public void SortItemInfo()
        {
            _itemCollection.SortInfo();
            _info.ReShapeItemHandShake = DateTime.Now;

        }

        public virtual bool SetStartDate(DateTime t)
        {
            return true;
        }

        public virtual bool CanReset()
        {
            return _unMaintainedCount == 0;
        }

        public List<MaintainerItem> GetAllMaintainerItems()
        {
            return _itemCollection.GetAllItems();
        }

        public bool SetMaintain(string itemuid, DateTime date)
        {
            if (_itemCollection.SetMaintain(itemuid, date))
            {
                return true;
            }
            return false;
        }

        public bool SetMaintainerItemEnable(string itemuid, bool enable)
        {
            if (_itemCollection.SetMaintainerItemEnable(itemuid, enable))
            {
                _info.ReShapeItemHandShake = DateTime.Now;
                return true;
            }
            return false;
        }

        public void AddMaintainerItem(MaintainerItem item)
        {
            _itemCollection.AddMaintainerItem(item);
        }

        public void RemoveMaintainerItem(string uid)
        {
            if (_itemCollection.RemoveMaintainerItem(uid))
            {
                _info.ReShapeItemHandShake = DateTime.Now;
            }
            
        }

        public MaintainerInfo GetInfo()
        {
            return _info;
        }

        public bool EqualsNameModule(string type, string name,string module)
        {
            return _info.EqualsTypeNameModule(type, name, module);
        }
        #endregion

    }
}
