using FluentValidation;
using SatelliteProvider.Common.DTO;

namespace SatelliteProvider.Api.Validators;

// AZ-809: per-point validator invoked via RuleForEach on the parent
// CreateRouteRequest. Each route waypoint must declare a valid WGS84
// coordinate; the parent validator checks min/max count of the points
// collection separately.
//
// Error path: errors keys land at `points[i].lat` / `points[i].lon` per
// FluentValidation's default child-property naming + GlobalValidatorConfig
// camelCase normalization (matches the wire format set by
// [JsonPropertyName("lat"|"lon")] on RoutePoint).
public sealed class RoutePointValidator : AbstractValidator<RoutePoint>
{
    private const double MinLat = -90.0;
    private const double MaxLat = 90.0;
    private const double MinLon = -180.0;
    private const double MaxLon = 180.0;

    public RoutePointValidator()
    {
        // `RoutePoint.Latitude` is the C# property name but the wire name is
        // `lat` via [JsonPropertyName]. OverridePropertyName chains AFTER the
        // first concrete rule (which provides the `TProperty` for the generic
        // extension) and aligns the FluentValidation error key with the wire
        // format — callers see `errors["points[i].lat"]` matching what they
        // posted rather than the camelCased C# name `latitude`.
        RuleFor(p => p.Latitude)
            .InclusiveBetween(MinLat, MaxLat)
            .WithMessage($"`lat` must be between {MinLat} and {MaxLat}.")
            .OverridePropertyName("lat");

        RuleFor(p => p.Longitude)
            .InclusiveBetween(MinLon, MaxLon)
            .WithMessage($"`lon` must be between {MinLon} and {MaxLon}.")
            .OverridePropertyName("lon");
    }
}
