using FluentAssertions;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using Moq;
using SatelliteProvider.Common.Configs;
using SatelliteProvider.Common.DTO;
using SatelliteProvider.Common.Interfaces;
using SatelliteProvider.DataAccess.Models;
using SatelliteProvider.DataAccess.Repositories;
using SatelliteProvider.Services.TileDownloader;
using SatelliteProvider.Tests.Fixtures;

namespace SatelliteProvider.Tests;

public class InfrastructureTests
{
    [Fact]
    public void AllMockableInterfaces_CanBeMocked()
    {
        // Arrange + Act
        var downloader = new Mock<ISatelliteDownloader>();
        var tileRepo = new Mock<ITileRepository>();
        var regionRepo = new Mock<IRegionRepository>();
        var routeRepo = new Mock<IRouteRepository>();
        var queue = new Mock<IRegionRequestQueue>();
        var tileService = new Mock<ITileService>();
        var regionService = new Mock<IRegionService>();
        var routeService = new Mock<IRouteService>();

        // Assert
        downloader.Object.Should().NotBeNull();
        tileRepo.Object.Should().NotBeNull();
        regionRepo.Object.Should().NotBeNull();
        routeRepo.Object.Should().NotBeNull();
        queue.Object.Should().NotBeNull();
        tileService.Object.Should().NotBeNull();
        regionService.Object.Should().NotBeNull();
        routeService.Object.Should().NotBeNull();
    }

    [Fact]
    public void TestCoordinates_TileCenter_MatchesPrimaryTilePoint()
    {
        // Assert
        TestCoordinates.TileCenter.Lat.Should().Be(47.461747);
        TestCoordinates.TileCenter.Lon.Should().Be(37.647063);
        TestCoordinates.DefaultZoom.Should().Be(18);
    }

    [Fact]
    public void TestCoordinates_RoutePoints_HaveExpectedCounts()
    {
        // Assert
        TestCoordinates.Route.Route01Points.Should().HaveCount(2);
        TestCoordinates.Route.Route04Points.Should().HaveCount(10);
        TestCoordinates.Route.Route06Points.Should().HaveCount(20);
    }

    [Fact]
    public void TileService_ConstructsWithMockedDependencies()
    {
        // Arrange
        var downloader = new Mock<ISatelliteDownloader>().Object;
        var tileRepo = new Mock<ITileRepository>().Object;
        var cache = new MemoryCache(new MemoryCacheOptions());
        var logger = NullLogger<TileService>.Instance;

        // Act
        var mapConfig = Options.Create(new MapConfig { Service = "GoogleMaps", ApiKey = "" });
        var service = new TileService(downloader, tileRepo, cache, mapConfig, logger);

        // Assert
        service.Should().NotBeNull();
    }
}
