namespace View_by_Distance.Shared.Models.Stateless.Methods;

internal abstract class Sorting
{

    internal static Models.Sorting Get(int faceDistancePermyriad, double faceDistanceTolerance, Models.FaceDistance faceDistanceEncoding, Models.FaceDistance faceDistanceLength, bool anyLowerThanTolerance, List<(long lcl, long minimum, long maximum, long ucl)> personKeysRangesCollection)
    {
        Models.Sorting result;
        if (faceDistanceLength.Length is null)
            throw new NotSupportedException();
        if (faceDistanceLength.NormalizedPixelPercentage is null)
            throw new NotSupportedException();
        bool older;
        int daysDelta;
        int withinRange;
        int distancePermyriad;
        if (faceDistanceLength.Length.Value == 0 || (anyLowerThanTolerance && faceDistanceLength.Length.Value >= faceDistanceTolerance))
        {
            older = false;
            daysDelta = 0;
            withinRange = 0;
            distancePermyriad = 0;
        }
        else
        {
            if (faceDistanceEncoding.MinimumDateTime is null || faceDistanceLength.MinimumDateTime is null)
                throw new NotSupportedException();
            List<int> withinRanges = new();
            long ticks = faceDistanceEncoding.MinimumDateTime.Value.Ticks;
            TimeSpan timeSpan = new(faceDistanceLength.MinimumDateTime.Value.Ticks - ticks);
            older = timeSpan.TotalMilliseconds < 0;
            daysDelta = (int)Math.Round(Math.Abs(timeSpan.TotalDays), 0);
            distancePermyriad = (int)(faceDistanceLength.Length.Value / faceDistanceTolerance * faceDistancePermyriad);
            foreach ((long lcl, long minimum, long maximum, long ucl) in personKeysRangesCollection)
            {
                if (ticks > minimum && ticks < maximum)
                    withinRanges.Add(0);
                else if (ticks > lcl && ticks < ucl)
                    withinRanges.Add(1);
                else
                    withinRanges.Add(2);
            }
            withinRange = withinRanges.Max();
        }
        result = new(daysDelta, distancePermyriad, faceDistanceLength.Id, faceDistanceLength.NormalizedPixelPercentage.Value, older, withinRange);
        return result;
    }

}