using Aitex.Core.RT.DataCenter;
using Aitex.Core.RT.DBCore;
using Aitex.Core.RT.Event;
using MECF.Framework.Common.DBCore;
using System;
using System.Data;

namespace MECF.Framework.Common.Aitex.Core.RT.EMS
{
    /// <summary>
    /// 监控膜生长厚度，超出阈值后报警提示
    /// </summary>
    public class CoatingMaintainer:Maintainer
    {
        #region Variables

        #endregion

        #region Constructors
        public CoatingMaintainer()
        {

        }

        public CoatingMaintainer(MaintainerItemCollection item, 
            string name, 
            string module, 
            int index, 
            string description, 
            bool enabled, 
            DateTime startdate, 
            double threshold, 
            TimeUnit timedisplayunit):base(item, name, module, index, description, enabled, startdate, threshold, timedisplayunit)
        {
            _info.Type = nameof(CoatingMaintainer);
            if (_info.Module == "PM1" || _info.Module == "PM2")
            {
                _getProcessing = new Func<bool>(() => {
                    var r = DATA.Poll(_info.Module + ".IsProcessing");
                    if (r != null)
                    {
                        return (bool)r;
                    }
                    return false;
                }
                );
            }
        }

        public CoatingMaintainer(MaintainerItemCollection item, MaintainerInfo info, DateTime startdate, double threshold)
            : base(item, info, startdate, threshold)
        {
            _info.Type = nameof(CoatingMaintainer);
            if (_info.Module == "PM1" || _info.Module == "PM2")
            {
                _getProcessing = new Func<bool>(() => {
                    var r = DATA.Poll(_info.Module + ".IsProcessing");
                    if (r != null)
                    {
                        return (bool)r;
                    }
                    return false;
                }
                );
            }
        }
        #endregion

        #region Methods

        /// <summary>
        /// 检查膜厚度
        /// </summary>
        public override void Monitor()
        {
            DateTime now = DateTime.Now;
            _isProcessing = _getProcessing();

            ////①确认未使能;没有维护项也不进行计算
            if (!_info.Enable || _itemCollection.Count == 0)
            {
                _isTimeOut = false;
                _timeExceed = 0;
                _value = 0;
            }
            else
            {
                UpdateValue();

                _itemCollection.CheckAllItemMaintained(_startDate);
                if (_unMaintainedCount == 0)
                {
                    Reset(); //所有项都维护，翻转沙漏
                }

                _valueExceed = _value - _threshold;
                if (_valueExceed <= 0)
                {
                    _valueExceed = 0;
                }
                if (_valueExceed > 0)
                {
                    if (!_isTimeOut && !_trigDate.HasValue)
                    {
                        _trigDate = now;
                    }
                    _isTimeOut = true;
                    if (_unMaintainedCount != 0)
                    {
                        if (_trigDate.HasValue)
                        {
                            _timeExceed = DateTimeHelper.DateTimeSubtraction(_trigDate.Value, now, TimeUnit.Seconds);
                        }
                        _valueElapsed = 0;
                    }
                }
                else
                {
                    _timeExceed = 0;
                    _valueElapsed = _threshold - _value;
                }
            }

            UpdateInfo();
            base.Monitor();

        }

        private void UpdateValue()
        {
            string sql = $"Select \"thickness\" from \"pm_thickness_data2\" where \"startdate\"='{_startDate.ToString()}' and \"pm_name\"='{_info.Module}';";
            DataSet dataSet = DB.ExecuteDataSet(sql);
            if (dataSet != null && dataSet.Tables != null && dataSet.Tables.Count == 1)
            {
                if (dataSet.Tables[0].Rows.Count == 1)
                {
                    _value = Convert.ToDouble(dataSet.Tables[0].Rows[0]["thickness"].ToString());
                }
                else if (dataSet.Tables[0].Rows.Count == 0)
                {
                    ThinknessDataRecorder.InsertPMThinkness(_startDate.ToString(), _info.Module, 0);
                }
            }
        }

        /// <summary>
        /// 重新开始计时，未使能时或不满足条件无法复位
        /// </summary>
        /// <returns></returns>
        public override bool Reset()
        {
            if (!_info.Enable)
            {
                EV.PostWarningLog("Maintenance", $"Plan {_info.Name} is disable,can not be reset");
                return false;
            }
            if (!CanReset())
            {
                return false;
            }

            _isTimeOut = false;
            DateTime now = DateTime.Now;
            _startDate = now;
            _trigDate = null;

            _value = 0;

            ThinknessDataRecorder.InsertPMThinkness(_startDate.ToString(),_info.Module,0);

            _timeExceed = 0;
            _valueExceed = 0;
            _valueElapsed = _threshold;
            _itemCollection.CheckAllItemMaintained(_startDate);

            UpdateInfo();
            return base.Reset();

        }

        public override void UpdateInfo()
        {
            _info.Value = _value;
            _info.Threshold = _threshold;
            _info.ValueExceed = _valueExceed;
            _info.ValueElapsed = _valueElapsed;

            base.UpdateInfo();
        }

        public override bool SetStartDate(DateTime t)
        {
            if (!base.SetStartDate(t))
            {
                return false;
            }
            _startDate = t;
            return true;
        }

        /// <summary>
        /// 阈值设置
        /// </summary>
        /// <param name="threshold"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public override bool SetThreshold(double threshold, params object[] args)
        {
            if (!base.SetThreshold(threshold))
            {
                return false;
            }
            _threshold = threshold;
            return true;
        }

        #endregion
    }
}
