using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PlantBox.Broker
{
    class HistoricManager
    {
        [JsonProperty(PropertyName = nameof(MinutesHistoric))]
        private List<CaptorsValue> _minutesHistoric;
        [JsonIgnore]
        public IReadOnlyList<CaptorsValue> MinutesHistoric => _minutesHistoric.AsReadOnly();

        [JsonProperty(PropertyName = nameof(HoursHistoric))]
        private List<CaptorsValue> _hoursHistoric;
        [JsonIgnore]
        public IReadOnlyList<CaptorsValue> HoursHistoric => _hoursHistoric.AsReadOnly();

        [JsonProperty(PropertyName = nameof(DaysHistoric))]
        private List<CaptorsValue> _daysHistoric;
        [JsonIgnore]
        public IReadOnlyList<CaptorsValue> DaysHistoric => _daysHistoric.AsReadOnly();

        [JsonProperty(PropertyName = nameof(WeeksHistoric))]
        private List<CaptorsValue> _weeksHistoric;
        [JsonIgnore]
        public IReadOnlyList<CaptorsValue> WeeksHistoric => _weeksHistoric.AsReadOnly();

        [JsonProperty(PropertyName = nameof(MonthsHistoric))]
        private List<CaptorsValue> _monthsHistoric;
        [JsonIgnore]
        public IReadOnlyList<CaptorsValue> MonthsHistoric => _monthsHistoric.AsReadOnly();

        public HistoricManager()
        {
            _minutesHistoric = new List<CaptorsValue>();
            _hoursHistoric = new List<CaptorsValue>();
            _daysHistoric = new List<CaptorsValue>();
            _weeksHistoric = new List<CaptorsValue>();
            _monthsHistoric = new List<CaptorsValue>();
        }
        public HistoricManager(List<CaptorsValue> minutesHistoric, List<CaptorsValue> hoursHistoric, List<CaptorsValue> daysHistoric, List<CaptorsValue> weeksHistoric, List<CaptorsValue> monthsHistoric)
        {
            _minutesHistoric = minutesHistoric;
            _hoursHistoric = hoursHistoric;
            _daysHistoric = daysHistoric;
            _weeksHistoric = weeksHistoric;
            _monthsHistoric = monthsHistoric;
        }

        public void Add(CaptorsValue captorsValue)
        {
            _minutesHistoric.Add(captorsValue);

            if (_minutesHistoric.Count % 12 == 0)
            {
                _hoursHistoric.Add(new CaptorsValue(GetAverage(_minutesHistoric.TakeFromEnd(12))));

                if (_hoursHistoric.Count % 24 == 0)
                {
                    _daysHistoric.Add(new CaptorsValue(GetAverage(_hoursHistoric.TakeFromEnd(24))));

                    if (_daysHistoric.Count % 7 == 0)
                    {
                        _weeksHistoric.Add(new CaptorsValue(GetAverage(_daysHistoric.TakeFromEnd(7))));

                        if (_daysHistoric.Count % 31 == 0)
                        {
                            _monthsHistoric.Add(new CaptorsValue(GetAverage(_daysHistoric.TakeFromEnd(31))));
                        }
                    }
                }
            }
        }

        public void Clear()
        {
            _minutesHistoric.Clear();
            _hoursHistoric.Clear();
            _daysHistoric.Clear();
            _weeksHistoric.Clear();
            _monthsHistoric.Clear();
        }

        private (double humidity, double luminosity, double temperature) GetAverage(IEnumerable<CaptorsValue> captorsValues)
        {
            return
            (
                captorsValues.Average(x => x.Humidity),
                captorsValues.Average(x => x.Luminosity),
                captorsValues.Average(x => x.Temperature)
            );
        }
    }
}
