using System;
using Aitex.Core.RT.DataCenter;
using Aitex.Core.RT.Log;
using Aitex.Core.Util;
using Sicentury.Core;
using FunFilter = System.Func<double, double>;

namespace MECF.Framework.RT.Core.Managers.PDS
{
    /// <summary>
    /// 气体流量累加器。
    /// </summary>
    public class ProcessDataStatCounter : BindableBase
    {
        #region Variables

        private DateTime _lastPollingTime = DateTime.MinValue;
        private readonly R_TRIG _trigDataPollingError = new();
        private FunFilter _dataFilter;
        private readonly R_TRIG _rTrigPollDataFailed = new();

        #endregion

        #region Constructors

        public ProcessDataStatCounter(string name, string module, FunFilter filter = null)
        {
            Name = name;
            Module = module;
            _dataFilter = filter;

            DataPath = new[]
            {
                $"{module}.GasRealTimeFlow.{name}_Run.FeedBack",
                $"{module}.GasRealTimeFlow.{name}_Vent.FeedBack",
            };
        }

        public ProcessDataStatCounter(string name, string module, FunFilter filter = null, params string[] dataPath) 
            : this(name, module, filter)
        {
            DataPath = dataPath;
            Total = 0;
        }

        public ProcessDataStatCounter(string name, string module, double initValue, FunFilter filter = null) : this(name, module, filter)
        {
            Total = initValue;
        }

        public ProcessDataStatCounter(string name, string module, double initValue, FunFilter filter = null, params string[] dataPath) 
            : this(name, module, filter, dataPath)
        {
            Total = initValue;
        }


        #endregion

        #region Properties

        /// <summary>
        /// 返回当前统计数据的名称。
        /// </summary>
        public string Name { get; }

        /// <summary>
        /// 返回当前统计数据所属的模块。
        /// </summary>
        public string Module { get; }

        /// <summary>
        /// 返回当前数据统计时所使用的数据拉取路径。
        /// </summary>
        public string[] DataPath { get; }

        /// <summary>
        /// 返回当前统计数据的累加值。
        /// </summary>
        public double Total { get; internal set; }

        #endregion

        #region Methods

        /// <summary>
        /// 累加气体流量。
        /// </summary>
        public void Accumulate()
        {
            var ts = DateTime.Now - _lastPollingTime;
            if(_lastPollingTime ==  DateTime.MinValue)
                ts = TimeSpan.FromSeconds(1);

            var sum = 0.0d;
            foreach (var pdata in DataPath)
            {
                var polled = DATA.Poll(pdata);
                _rTrigPollDataFailed.CLK = polled == null;
                if(_trigDataPollingError.Q)
                    LOG.Error($"Failed to count {pdata}, unable to poll data from RT");
                
                if (polled == null)
                    continue;
                    
                var sFlow = polled.ToString();
                if (double.TryParse(sFlow, out var dFlow))
                {
                    sum += dFlow * ts.TotalSeconds;
                   _trigDataPollingError.RST = true;
                }
                else
                {
                    _trigDataPollingError.CLK = true;
                    if (_trigDataPollingError.Q)
                    {
                        LOG.Error($"Unable to polling data {DataPath} or the data({sFlow}) is not double value.");
                    }

                    break;
                }
            }

            Total += _dataFilter?.Invoke(sum) ?? sum;

            _lastPollingTime = DateTime.Now;
        }

        public override string ToString()
        {
            return $"{Name}: {Total:F1}";
        }

        #endregion
    }
}
