using System.Reflection;
using FluentAssertions;
using SIGCM2.Domain.Fiscal;

namespace SIGCM2.Application.Tests.Domain.Fiscal;

public class ProvinciaArgentinaTests
{
    // ── T200.1: enum tiene exactamente 24 valores ─────────────────────────────

    [Fact]
    public void ProvinciaArgentina_Enum_Has_Exactly_24_Values()
    {
        var values = Enum.GetValues<ProvinciaArgentina>();

        values.Should().HaveCount(24, "Argentina tiene 23 provincias INDEC + CABA = 24 jurisdicciones fiscales");
    }

    // ── T200.1: cada valor tiene el nombre canónico exacto ────────────────────

    [Theory]
    [InlineData("BuenosAires")]
    [InlineData("Catamarca")]
    [InlineData("Chaco")]
    [InlineData("Chubut")]
    [InlineData("CiudadAutonomaDeBuenosAires")]
    [InlineData("Cordoba")]
    [InlineData("Corrientes")]
    [InlineData("EntreRios")]
    [InlineData("Formosa")]
    [InlineData("Jujuy")]
    [InlineData("LaPampa")]
    [InlineData("LaRioja")]
    [InlineData("Mendoza")]
    [InlineData("Misiones")]
    [InlineData("Neuquen")]
    [InlineData("RioNegro")]
    [InlineData("Salta")]
    [InlineData("SanJuan")]
    [InlineData("SanLuis")]
    [InlineData("SantaCruz")]
    [InlineData("SantaFe")]
    [InlineData("SantiagoDelEstero")]
    [InlineData("TierraDelFuego")]
    [InlineData("Tucuman")]
    public void ProvinciaArgentina_Enum_Contains_CanonicalName(string nombre)
    {
        var defined = Enum.IsDefined(typeof(ProvinciaArgentina), nombre);

        defined.Should().BeTrue($"ProvinciaArgentina debe contener el valor '{nombre}'");
    }

    // ── T200.3: mapping bidireccional string BD ↔ enum ───────────────────────

    [Theory]
    [InlineData(ProvinciaArgentina.BuenosAires, "Buenos Aires")]
    [InlineData(ProvinciaArgentina.CiudadAutonomaDeBuenosAires, "Ciudad Autónoma de Buenos Aires")]
    [InlineData(ProvinciaArgentina.Cordoba, "Córdoba")]
    [InlineData(ProvinciaArgentina.EntreRios, "Entre Ríos")]
    [InlineData(ProvinciaArgentina.Neuquen, "Neuquén")]
    [InlineData(ProvinciaArgentina.RioNegro, "Río Negro")]
    [InlineData(ProvinciaArgentina.TierraDelFuego, "Tierra del Fuego")]
    public void ToDisplayString_ReturnsCorrectDisplayName(ProvinciaArgentina provincia, string expected)
    {
        var result = provincia.ToDisplayString();

        result.Should().Be(expected);
    }

    [Fact]
    public void ToDisplayString_AllValues_ReturnNonEmptyString()
    {
        foreach (var value in Enum.GetValues<ProvinciaArgentina>())
        {
            var display = value.ToDisplayString();
            display.Should().NotBeNullOrWhiteSpace($"{value} debe tener un display string");
        }
    }

    [Theory]
    [InlineData("Buenos Aires", ProvinciaArgentina.BuenosAires)]
    [InlineData("Ciudad Autónoma de Buenos Aires", ProvinciaArgentina.CiudadAutonomaDeBuenosAires)]
    [InlineData("Córdoba", ProvinciaArgentina.Cordoba)]
    public void FromDisplayString_ReturnsCorrectEnum(string displayName, ProvinciaArgentina expected)
    {
        var result = ProvinciaArgentinaExtensions.FromDisplayString(displayName);

        result.Should().Be(expected);
    }

    [Fact]
    public void FromDisplayString_InvalidName_ThrowsArgumentException()
    {
        var act = () => ProvinciaArgentinaExtensions.FromDisplayString("Patagonia Inventada");

        act.Should().Throw<ArgumentException>();
    }
}
