using System;
using System.Collections.Generic;

namespace AsbCloudInfrastructure.Services.Subsystems.Utils
{
#nullable enable
    internal class DepthInterpolation
    {
        private readonly TimeSpan maxDeltaDate = TimeSpan.FromHours(12);
        private readonly IEnumerator<(DateTimeOffset x, float y)> enumerator;
        private (DateTimeOffset x, float y) p0;
        private bool canMoveNext;

        public DepthInterpolation(IEnumerable<(DateTimeOffset x, float y)> collection)
        {
            enumerator = collection.GetEnumerator();
            canMoveNext = enumerator.MoveNext();
            p0 = enumerator.Current;
        }

        ~DepthInterpolation()
        {
            enumerator.Dispose();
        }

        public float GetDepth(DateTimeOffset date)
        {
            // ошибка в телеметрии см. прим.: idTelemetry = 93 && date between '2021-11-16 17:18:40.000 +0500' and '2021-11-16 17:19:37.000 +0500'
            while (canMoveNext && enumerator.Current.x < date)
            {
                p0 = enumerator.Current;
                canMoveNext = enumerator.MoveNext();
            }
            return CalcValue(date);
        }
        
        private float CalcValue(DateTimeOffset date)
        {
            var p1 = enumerator.Current;
            if (canMoveNext || p1 == default || p0.y == p1.y || p0.x > date)
                return p0.y;

            if (p1.x < date)
                return p1.y;

            if (p1.x - p0.x > maxDeltaDate && Math.Abs(p1.y - p0.y) > 0.2d)
            {
                if (date - p0.x < p1.x - date)
                    return p0.y;
                else
                    return p1.y;
            }

            var a = (p1.y - p0.y) / (p1.x - p0.x).TotalSeconds;
            var b = p0.y;
            var x = (date - p0.x).TotalSeconds;
            var y = a * x + b;
            return (float)y;
        }
    }
#nullable disable
}