using System.Net.Http.Json;

namespace SatelliteProvider.IntegrationTests;

public static class BasicRouteTests
{
    public static async Task RunSimpleRouteTest(HttpClient httpClient)
    {
        RouteTestHelpers.PrintSectionHeader("Test: Create Simple Route with Two Points");

        var routeId = Guid.NewGuid();
        var request = new CreateRouteRequest
        {
            Id = routeId,
            Name = "Simple Test Route",
            Description = "Test route with 2 points",
            RegionSizeMeters = 500.0,
            ZoomLevel = 18,
            Points = new List<RoutePointInput>
            {
                new() { Lat = 48.276067180586544, Lon = 37.38445758819581 },
                new() { Lat = 48.27074009522731, Lon = 37.374029159545906 }
            }
        };

        Console.WriteLine($"Creating route with 2 points:");
        Console.WriteLine($"  Start: ({request.Points[0].Lat}, {request.Points[0].Lon})");
        Console.WriteLine($"  End: ({request.Points[1].Lat}, {request.Points[1].Lon})");
        Console.WriteLine($"  Region Size: {request.RegionSizeMeters}m");
        Console.WriteLine($"  Zoom Level: {request.ZoomLevel}");
        Console.WriteLine();

        var route = await RouteTestHelpers.CreateRoute(httpClient, request);

        Console.WriteLine("Route Details:");
        Console.WriteLine($"  ID: {route.Id}");
        Console.WriteLine($"  Name: {route.Name}");
        Console.WriteLine($"  Total Points: {route.TotalPoints}");
        Console.WriteLine($"  Total Distance: {route.TotalDistanceMeters:F2}m");
        Console.WriteLine();

        RouteTestHelpers.PrintPointTypeDistribution(route);

        RouteTestHelpers.ValidatePointTypes(route, 1, 1, 0);

        Console.WriteLine("Point spacing validation:");
        for (int i = 1; i < route.Points.Count; i++)
        {
            var point = route.Points[i];
            if (point.DistanceFromPrevious.HasValue)
            {
                if (point.DistanceFromPrevious.Value > 200.0)
                {
                    throw new Exception($"Point {i} is {point.DistanceFromPrevious.Value:F2}m from previous, exceeds 200m limit");
                }
                Console.WriteLine($"  Point {i} ({point.PointType}): {point.DistanceFromPrevious.Value:F2}m from previous");
            }
        }
        Console.WriteLine();

        Console.WriteLine("Retrieving route by ID...");
        var getResponse = await httpClient.GetAsync($"/api/satellite/route/{routeId}");

        if (!getResponse.IsSuccessStatusCode)
        {
            throw new Exception($"Failed to retrieve route: {getResponse.StatusCode}");
        }

        var retrievedRoute = await getResponse.Content.ReadFromJsonAsync<RouteResponseModel>(new System.Text.Json.JsonSerializerOptions
        {
            PropertyNameCaseInsensitive = true
        });

        if (retrievedRoute == null || retrievedRoute.Id != routeId)
        {
            throw new Exception("Retrieved route does not match created route");
        }

        Console.WriteLine($"✓ Route retrieved successfully");
        Console.WriteLine($"✓ Retrieved {retrievedRoute.Points.Count} points");
        Console.WriteLine();
        Console.WriteLine("✓ Route created successfully");
        Console.WriteLine("✓ All point spacing validated (≤ 200m)");
        Console.WriteLine();
        Console.WriteLine("Simple Route Test: PASSED");
    }

    public static async Task RunRouteWithRegionProcessingAndStitching(HttpClient httpClient)
    {
        RouteTestHelpers.PrintTestHeader("Test: Route with Region Processing and Full Map Stitching (Service-Level)");

        var routeId = Guid.NewGuid();
        var request = new CreateRouteRequest
        {
            Id = routeId,
            Name = "Route with Region Processing",
            Description = "Test route that processes regions for all points and stitches a full map",
            RegionSizeMeters = 300.0,
            ZoomLevel = 18,
            RequestMaps = true,
            Points = new List<RoutePointInput>
            {
                new() { Lat = 48.276067180586544, Lon = 37.38445758819581 },
                new() { Lat = 48.27074009522731, Lon = 37.374029159545906 }
            }
        };

        Console.WriteLine("Step 1: Creating route with RequestMaps=true");
        Console.WriteLine($"  Start: ({request.Points[0].Lat}, {request.Points[0].Lon})");
        Console.WriteLine($"  End: ({request.Points[1].Lat}, {request.Points[1].Lon})");
        Console.WriteLine($"  Region Size: {request.RegionSizeMeters}m");
        Console.WriteLine($"  Zoom Level: {request.ZoomLevel}");
        Console.WriteLine($"  Request Maps: {request.RequestMaps}");
        Console.WriteLine();

        var route = await RouteTestHelpers.CreateRoute(httpClient, request);

        RouteTestHelpers.PrintRouteResponse(route);
        RouteTestHelpers.ValidateRequestMaps(route, false);

        Console.WriteLine("Step 2: Waiting for route maps to be ready");
        Console.WriteLine("  (Service is processing regions SEQUENTIALLY to avoid API throttling)");
        Console.WriteLine();

        var finalRoute = await RouteTestHelpers.WaitForRouteReady(httpClient, routeId, 180, 3000);

        Console.WriteLine();
        Console.WriteLine("Step 3: Verifying generated files");

        RouteTestHelpers.ValidateFiles(finalRoute);

        var uniqueTileCount = await RouteTestHelpers.GetUniqueTileCount(finalRoute.CsvFilePath!);

        RouteTestHelpers.PrintGeneratedFiles(finalRoute, uniqueTileCount);
        RouteTestHelpers.PrintRouteSummary(finalRoute, uniqueTileCount);

        Console.WriteLine("✓ Route with Region Processing and Stitching Test: PASSED");
    }
}

