using System.Collections.Generic;
using System.Linq;

namespace AsbCloudInfrastructure.Services
{
    public class InterpolationLine
    {
        private readonly decimal xSum;
        private readonly decimal ySum;
        private readonly decimal xySum;
        private readonly decimal x2Sum;
        private readonly IEnumerable<(double value, double timestamp)> rawData = new List<(double value, double timestamp)>();

        public InterpolationLine(IEnumerable<(double value, double timestamp)> rawData)
        {
            var data = rawData.Select((d) => new
            {
                X = d.timestamp,
                Y = d.value
            });
            xSum = (decimal)data.Sum(d => d.X);
            ySum = (decimal)data.Sum(d => d.Y);
            xySum = (decimal)data.Sum(d => d.X * d.Y);
            x2Sum = (decimal)data.Sum(d => d.X * d.X);

            this.rawData = rawData;
        }
        public double GetAForLinearFormula()
        {
            var result = (xSum * ySum - rawData.Count() * xySum) /
                   (xSum * xSum - rawData.Count() * x2Sum);

            return (double)result;
        }

        public double GetBForLinearFormula()
        {
            var result = (xSum * xySum - x2Sum * ySum) /
                   (xSum * xSum - rawData.Count() * x2Sum);

            return (double)result;
        }

        public static bool IsValueNotChanges(double value,
            (double upperBound, double lowerBound) bounds) =>
                value < bounds.upperBound && value > bounds.lowerBound;

        public static bool IsValueIncreases(double value, double bound) =>
            value > bound;

        public static bool IsValueDecreases(double value, double bound) =>
            value < bound;

        public static bool IsAverageLessThanBound(IEnumerable<(double Value, double TotalSeconds)> values,
            double bound) =>
                (values.Sum(s => s.Value) / values.Count()) < bound;

        public static bool IsAverageMoreThanBound(IEnumerable<(double Value, double TotalSeconds)> values,
            double bound) =>
                (values.Sum(s => s.Value) / values.Count()) >= bound;
    }
}