using FluentAssertions;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using SatelliteProvider.Common.Configs;
using SatelliteProvider.DataAccess.Models;
using SatelliteProvider.Services.RouteManagement;

namespace SatelliteProvider.Tests;

// AZ-364 / C11: route summary writer carries forward the StringBuilder
// content verbatim; tests pin the expected lines so a future drift in
// the summary format is caught.
public class RouteSummaryWriterTests : IDisposable
{
    private readonly string _tempDir;

    public RouteSummaryWriterTests()
    {
        _tempDir = Path.Combine(Path.GetTempPath(), "az364_routesum_" + Guid.NewGuid().ToString("N"));
        Directory.CreateDirectory(_tempDir);
    }

    public void Dispose()
    {
        if (Directory.Exists(_tempDir))
        {
            Directory.Delete(_tempDir, recursive: true);
        }
        GC.SuppressFinalize(this);
    }

    [Fact]
    public async Task WriteAsync_IncludesExpectedLinesAndReturnsPath_AZ364_AC1()
    {
        // Arrange
        var storageOptions = Options.Create(new StorageConfig { ReadyDirectory = _tempDir });
        var sut = new RouteSummaryWriter(storageOptions, NullLogger<RouteSummaryWriter>.Instance);

        var route = new RouteEntity
        {
            Id = Guid.NewGuid(),
            Name = "demo route",
            Description = "test description",
            TotalPoints = 4,
            TotalDistanceMeters = 1234.5,
            RegionSizeMeters = 200,
            ZoomLevel = 18,
            RequestMaps = true,
        };

        // Act
        var path = await sut.WriteAsync(route, uniqueTiles: 10, totalTilesFromRegions: 12, duplicateTiles: 2, tilesZipPath: "/ready/zip.zip");

        // Assert
        path.Should().Be(Path.Combine(_tempDir, $"route_{route.Id}_summary.txt"));
        var content = await File.ReadAllTextAsync(path);
        content.Should().Contain("Route Maps Summary");
        content.Should().Contain($"Route ID: {route.Id}");
        content.Should().Contain("Route Name: demo route");
        content.Should().Contain("Description: test description");
        content.Should().Contain("Total Points: 4");
        content.Should().Contain("Total Distance: 1234.50 meters");
        content.Should().Contain("Region Size: 200 meters");
        content.Should().Contain("Zoom Level: 18");
        content.Should().Contain("- Unique Tiles: 10");
        content.Should().Contain("- Total Tiles from Regions: 12");
        content.Should().Contain("- Duplicate Tiles (overlap): 2");
        content.Should().Contain($"- Stitched Map: route_{route.Id}_stitched.jpg");
        content.Should().Contain($"- Tiles ZIP: route_{route.Id}_tiles.zip");
    }

    [Fact]
    public async Task WriteAsync_OmitsZipLineWhenNoZipPathSupplied_AZ364_AC1()
    {
        // Arrange
        var storageOptions = Options.Create(new StorageConfig { ReadyDirectory = _tempDir });
        var sut = new RouteSummaryWriter(storageOptions, NullLogger<RouteSummaryWriter>.Instance);
        var route = new RouteEntity { Id = Guid.NewGuid(), Name = "no zip", TotalPoints = 2, RequestMaps = false };

        // Act
        var path = await sut.WriteAsync(route, uniqueTiles: 1, totalTilesFromRegions: 1, duplicateTiles: 0, tilesZipPath: null);

        // Assert
        var content = await File.ReadAllTextAsync(path);
        content.Should().NotContain("Tiles ZIP");
        content.Should().NotContain("Stitched Map");
    }
}
