using FluentValidation.TestHelper;
using SatelliteProvider.Api.Validators;
using SatelliteProvider.Common.DTO;

namespace SatelliteProvider.Tests.Validators;

// AZ-809: unit tests for RoutePointValidator. Lat/lon range checks live on
// `RoutePoint.Latitude` / `RoutePoint.Longitude` (C# names); the validator's
// OverridePropertyName aligns FluentValidation error keys with the wire
// format (`lat` / `lon`) so callers see what they posted.
public class RoutePointValidatorTests
{
    private readonly RoutePointValidator _validator;

    public RoutePointValidatorTests()
    {
        GlobalValidatorConfig.ApplyOnce();
        _validator = new RoutePointValidator();
    }

    [Theory]
    [InlineData(-90.001)]
    [InlineData(90.001)]
    [InlineData(180.0)]
    public void Validate_LatOutOfRange_FailsRangeRule(double lat)
    {
        // Arrange
        var point = new RoutePoint { Latitude = lat, Longitude = 37.647063 };

        // Act
        var result = _validator.TestValidate(point);

        // Assert
        result.ShouldHaveValidationErrorFor("lat");
    }

    [Theory]
    [InlineData(-90.0)]
    [InlineData(0.0)]
    [InlineData(47.461747)]
    [InlineData(90.0)]
    public void Validate_LatAtOrInsideBounds_Passes(double lat)
    {
        // Arrange
        var point = new RoutePoint { Latitude = lat, Longitude = 37.647063 };

        // Act
        var result = _validator.TestValidate(point);

        // Assert
        result.ShouldNotHaveValidationErrorFor("lat");
    }

    [Theory]
    [InlineData(-180.001)]
    [InlineData(180.001)]
    [InlineData(360.0)]
    public void Validate_LonOutOfRange_FailsRangeRule(double lon)
    {
        // Arrange
        var point = new RoutePoint { Latitude = 47.461747, Longitude = lon };

        // Act
        var result = _validator.TestValidate(point);

        // Assert
        result.ShouldHaveValidationErrorFor("lon");
    }

    [Theory]
    [InlineData(-180.0)]
    [InlineData(0.0)]
    [InlineData(37.647063)]
    [InlineData(180.0)]
    public void Validate_LonAtOrInsideBounds_Passes(double lon)
    {
        // Arrange
        var point = new RoutePoint { Latitude = 47.461747, Longitude = lon };

        // Act
        var result = _validator.TestValidate(point);

        // Assert
        result.ShouldNotHaveValidationErrorFor("lon");
    }
}
