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: cleaner deletes the per-region CSV, summary, and
// stitched-image files. Missing files are skipped without throwing;
// other regions are still processed even if one delete fails.
public class RegionFileCleanerTests : IDisposable
{
    private readonly string _readyDir;

    public RegionFileCleanerTests()
    {
        _readyDir = Path.Combine(Path.GetTempPath(), "az364_cleaner_" + Guid.NewGuid().ToString("N"));
        Directory.CreateDirectory(_readyDir);
    }

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

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

        var regionId = Guid.NewGuid();
        var csvPath = Path.Combine(_readyDir, $"region_{regionId}_ready.csv");
        var summaryPath = Path.Combine(_readyDir, $"region_{regionId}_summary.txt");
        var stitchedPath = Path.Combine(_readyDir, $"region_{regionId}_stitched.jpg");
        await File.WriteAllTextAsync(csvPath, "header\n");
        await File.WriteAllTextAsync(summaryPath, "summary\n");
        await File.WriteAllBytesAsync(stitchedPath, new byte[] { 0xFF, 0xD8 });

        var region = new RegionEntity
        {
            Id = regionId,
            CsvFilePath = csvPath,
            SummaryFilePath = summaryPath,
        };

        // Act
        await sut.CleanupAsync(new[] { region });

        // Assert
        File.Exists(csvPath).Should().BeFalse();
        File.Exists(summaryPath).Should().BeFalse();
        File.Exists(stitchedPath).Should().BeFalse();
    }

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

        var region = new RegionEntity
        {
            Id = Guid.NewGuid(),
            CsvFilePath = "/does/not/exist.csv",
            SummaryFilePath = null,
        };

        // Act
        Func<Task> act = () => sut.CleanupAsync(new[] { region });

        // Assert
        await act.Should().NotThrowAsync();
    }
}
