using SatelliteProvider.Common.DTO;
using SatelliteProvider.Common.Utils;
using SatelliteProvider.DataAccess.Models;

namespace SatelliteProvider.Services.RouteManagement;

// AZ-364 / C11: extracted from RouteProcessingService.MatchRegionsToRoutePoints.
// Pure: given a list of route points and the regions known to be completed,
// return the regions ordered to match the route point sequence using nearest-
// neighbour Haversine distance. Each region is consumed at most once.
public class RouteRegionMatcher
{
    public List<RegionEntity> Match(
        IReadOnlyList<RoutePointEntity> routePoints,
        IReadOnlyList<RegionEntity> regions)
    {
        ArgumentNullException.ThrowIfNull(routePoints);
        ArgumentNullException.ThrowIfNull(regions);

        var orderedRegions = new List<RegionEntity>(routePoints.Count);
        var availableRegions = new List<RegionEntity>(regions);

        foreach (var point in routePoints)
        {
            var pointGeo = new GeoPoint(point.Latitude, point.Longitude);
            var matchedRegion = availableRegions
                .OrderBy(r => GeoUtils.CalculateDistance(pointGeo, new GeoPoint(r.Latitude, r.Longitude)))
                .FirstOrDefault();

            if (matchedRegion != null)
            {
                orderedRegions.Add(matchedRegion);
                availableRegions.Remove(matchedRegion);
            }
        }

        return orderedRegions;
    }
}
