using System.Net.Http.Json;
using System.Text.Json;

namespace SatelliteProvider.IntegrationTests;

public static class TileTests
{
    private static readonly JsonSerializerOptions JsonOptions = new()
    {
        PropertyNameCaseInsensitive = true
    };

    public static async Task RunGetTileByLatLonTest(HttpClient httpClient)
    {
        Console.WriteLine("Test: Get Tile by Lat/Lon at Coordinates 47.461747, 37.647063");
        Console.WriteLine("------------------------------------------------------------------");

        const double latitude = 47.461747;
        const double longitude = 37.647063;
        const int zoomLevel = 18;

        Console.WriteLine($"Getting tile at coordinates ({latitude}, {longitude}) with zoom level {zoomLevel}");

        var response = await httpClient.GetAsync($"/api/satellite/tiles/latlon?lat={latitude}&lon={longitude}&zoom={zoomLevel}");

        if (!response.IsSuccessStatusCode)
        {
            var errorContent = await response.Content.ReadAsStringAsync();
            throw new Exception($"API returned error status {response.StatusCode}: {errorContent}");
        }

        var tile = await response.Content.ReadFromJsonAsync<DownloadTileResponse>(JsonOptions);

        if (tile == null)
        {
            throw new Exception("No tile data returned from API");
        }

        Console.WriteLine();
        Console.WriteLine("Tile Details:");
        Console.WriteLine($"  ID: {tile.Id}");
        Console.WriteLine($"  Zoom Level: {tile.ZoomLevel}");
        Console.WriteLine($"  Latitude: {tile.Latitude}");
        Console.WriteLine($"  Longitude: {tile.Longitude}");
        Console.WriteLine($"  Tile Size (meters): {tile.TileSizeMeters:F2}");
        Console.WriteLine($"  Tile Size (pixels): {tile.TileSizePixels}");
        Console.WriteLine($"  Image Type: {tile.ImageType}");
        Console.WriteLine($"  File Path: {tile.FilePath}");
        Console.WriteLine($"  Created At: {tile.CreatedAt:yyyy-MM-dd HH:mm:ss}");

        if (tile.ZoomLevel != zoomLevel)
        {
            throw new Exception($"Expected zoom level {zoomLevel}, got {tile.ZoomLevel}");
        }

        if (string.IsNullOrEmpty(tile.FilePath))
        {
            throw new Exception("File path is empty");
        }

        if (tile.TileSizePixels != 256)
        {
            throw new Exception($"Expected tile size 256 pixels, got {tile.TileSizePixels}");
        }

        if (tile.ImageType != "jpg")
        {
            throw new Exception($"Expected image type 'jpg', got '{tile.ImageType}'");
        }

        Console.WriteLine();
        Console.WriteLine("✓ Tile retrieved successfully");
        Console.WriteLine("✓ Tile metadata validated");
        Console.WriteLine();
        Console.WriteLine("Testing tile reuse (getting same tile again)...");

        var response2 = await httpClient.GetAsync($"/api/satellite/tiles/latlon?lat={latitude}&lon={longitude}&zoom={zoomLevel}");

        if (!response2.IsSuccessStatusCode)
        {
            var errorContent = await response2.Content.ReadAsStringAsync();
            throw new Exception($"Second request failed with status {response2.StatusCode}: {errorContent}");
        }

        var tile2 = await response2.Content.ReadFromJsonAsync<DownloadTileResponse>(JsonOptions);

        if (tile2 == null)
        {
            throw new Exception("No tile data returned from second request");
        }

        Console.WriteLine($"✓ Second request returned tile ID: {tile2.Id}");
        Console.WriteLine("✓ Tile reuse functionality working");
        Console.WriteLine();
        Console.WriteLine("Get Tile by Lat/Lon Test: PASSED");
    }
}

