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

namespace SatelliteProvider.Tests;

// AZ-364 / C11: tests moved from RouteProcessingServiceTests when the helper
// migrated to RouteImageRenderer. The four tile-coordinate-parsing tests
// preserve the behavior contract (good name → parsed; malformed → sentinel
// + warning log; null → ArgumentNullException).
public class RouteImageRendererTests
{
    private static RouteImageRenderer BuildSut(out Mock<ILogger<RouteImageRenderer>> loggerMock)
    {
        loggerMock = new Mock<ILogger<RouteImageRenderer>>();
        var storageOptions = Options.Create(new StorageConfig());
        var mapOptions = Options.Create(new MapConfig { Service = "GoogleMaps", ApiKey = "" });
        return new RouteImageRenderer(storageOptions, mapOptions, loggerMock.Object);
    }

    private static void VerifyWarningLogged(Mock<ILogger<RouteImageRenderer>> loggerMock, string substringInState)
    {
        loggerMock.Verify(
            l => l.Log(
                LogLevel.Warning,
                It.IsAny<EventId>(),
                It.Is<It.IsAnyType>((state, _) => state.ToString()!.Contains(substringInState)),
                It.IsAny<Exception?>(),
                It.IsAny<Func<It.IsAnyType, Exception?, string>>()),
            Times.AtLeastOnce);
    }

    [Fact]
    public void ExtractTileCoordinatesFromFilename_ValidName_ReturnsParsedCoordinates_AZ364_AC1()
    {
        // Arrange
        var sut = BuildSut(out _);

        // Act
        var (x, y) = sut.ExtractTileCoordinatesFromFilename("/tiles/tile_1700000000_42_99.jpg");

        // Assert
        x.Should().Be(42);
        y.Should().Be(99);
    }

    [Fact]
    public void ExtractTileCoordinatesFromFilename_MalformedName_LogsWarningAndReturnsSentinel_AZ364_AC1()
    {
        // Arrange
        var sut = BuildSut(out var loggerMock);
        const string malformed = "/tmp/not_a_tile_filename.jpg";

        // Act
        var (x, y) = sut.ExtractTileCoordinatesFromFilename(malformed);

        // Assert
        x.Should().Be(-1);
        y.Should().Be(-1);
        VerifyWarningLogged(loggerMock, "not_a_tile_filename");
    }

    [Fact]
    public void ExtractTileCoordinatesFromFilename_TilePrefixWithNonNumericCoords_LogsWarningAndReturnsSentinel_AZ364_AC1()
    {
        // Arrange
        var sut = BuildSut(out var loggerMock);
        const string nonNumeric = "/tiles/tile_1700000000_alpha_beta.jpg";

        // Act
        var (x, y) = sut.ExtractTileCoordinatesFromFilename(nonNumeric);

        // Assert
        x.Should().Be(-1);
        y.Should().Be(-1);
        VerifyWarningLogged(loggerMock, "tile_1700000000_alpha_beta");
    }

    [Fact]
    public void ExtractTileCoordinatesFromFilename_NullPath_PropagatesArgumentNullException_AZ364_AC1()
    {
        // Arrange
        var sut = BuildSut(out _);

        // Act
        Action act = () => sut.ExtractTileCoordinatesFromFilename(null!);

        // Assert
        act.Should().Throw<ArgumentNullException>();
    }
}
