using FluentAssertions;
using Microsoft.Extensions.Options;
using SatelliteProvider.Common.Configs;
using SatelliteProvider.Services.RouteManagement;
using SatelliteProvider.Services.RouteManagement.TileProvision;

namespace SatelliteProvider.Tests;

public class RouteTileExpanderTests
{
    private readonly RouteTileExpander _expander = new(
        new RoutePointGraphBuilder(Options.Create(new ProcessingConfig { MaxRoutePointSpacingMeters = 200 })),
        new GeofenceGridCalculator());

    [Fact]
    public void Expand_ShortRoute_ProducesTilesForEachWaypointCorridor()
    {
        var waypoints = new List<(double Lat, double Lon)>
        {
            (47.0, 37.0),
            (47.001, 37.001),
        };

        var tiles = _expander.Expand(waypoints, regionSizeMeters: 400, zoom: 18, [], includeGeofenceTiles: false);

        tiles.Should().NotBeEmpty();
        tiles.Select(t => (t.Z, t.X, t.Y)).Should().OnlyHaveUniqueItems();
        tiles.Should().OnlyContain(t => t.Z == 18);
    }

    [Fact]
    public void Expand_LongSegment_AddsIntermediateCorridors()
    {
        var waypoints = new List<(double Lat, double Lon)>
        {
            (47.0, 37.0),
            (47.01, 37.0),
        };

        var tiles = _expander.Expand(waypoints, regionSizeMeters: 400, zoom: 18, [], includeGeofenceTiles: false);

        tiles.Should().NotBeEmpty();
        tiles.Select(t => t.RoutePriority).Max().Should().BeGreaterThan(1u);
    }

    [Fact]
    public void Expand_WithGeofence_IncludesGeofenceTilesWhenRequested()
    {
        var waypoints = new List<(double Lat, double Lon)>
        {
            (47.0, 37.0),
            (47.001, 37.001),
        };

        var geofence = new List<(double Lat, double Lon)>
        {
            (47.002, 37.002),
            (47.003, 37.002),
            (47.003, 37.003),
            (47.002, 37.003),
        };

        var without = _expander.Expand(waypoints, 400, 18, [], false);
        var with = _expander.Expand(waypoints, 400, 18, [geofence], true);

        with.Count.Should().BeGreaterThan(without.Count);
    }
}
