using ApiOPE.Configuration;
using ApiOPE.Contracts;
using ApiOPE.Services;
using Microsoft.Extensions.Options;

namespace ApiOPE.Tests;

public sealed class OpeFieldMapperTests
{
    [Fact]
    public void Map_UsesConfiguredOrderAndFieldNames()
    {
        var options = Options.Create(new OpeOptions
        {
            OutputFields = ["numeroDenunciaCanal", "fechaDenuncia", "resumenDenuncia"]
        });
        var mapper = new OpeFieldMapper(options);
        var source = new InternalGestionaFieldsResponse(
            new Dictionary<string, OpeFieldValue>
            {
                ["fechaDenuncia"] = new("STRING", "2026-07-10"),
                ["numeroDenunciaCanal"] = new("STRING", "116"),
                ["resumenDenuncia"] = new("STRING", "Prueba")
            });

        var result = mapper.Map(source);

        Assert.Equal("116", result.Data["FIELD_0"].Value);
        Assert.Equal("2026-07-10", result.Data["FIELD_1"].Value);
        Assert.Equal("Prueba", result.Data["FIELD_2"].Value);
    }

    [Fact]
    public void Map_RejectsMissingInternalField()
    {
        var mapper = new OpeFieldMapper(Options.Create(new OpeOptions
        {
            OutputFields = ["fechaDenuncia"]
        }));
        var source = new InternalGestionaFieldsResponse(
            new Dictionary<string, OpeFieldValue>());

        Assert.Throws<InvalidDataException>(() => mapper.Map(source));
    }

    [Theory]
    [InlineData("53/2026", "api/denuncias/53/2026/gestiona-fields")]
    [InlineData("116", "api/denuncias/116/gestiona-fields")]
    public void LookupParser_AcceptsExpedienteAndComplaintId(string value, string expectedPath)
    {
        var parsed = DenunciaLookupParser.TryParse(value, out var lookup);

        Assert.True(parsed);
        Assert.Equal(expectedPath, lookup!.RelativePath);
    }

    [Theory]
    [InlineData(0)]
    [InlineData(11)]
    public void OptionsValidator_RejectsInvalidOutputCount(int count)
    {
        var options = new OpeOptions
        {
            ClientToken = "client",
            SecretKey = "test-secret-key-with-more-than-32-characters",
            PublicBaseUrl = "https://ope.example.test",
            OrganizationId = "organization",
            OrganizationDir3 = "dir3",
            OrganizationCif = "cif",
            OutputFields = Enumerable.Repeat("fechaDenuncia", count).ToList()
        };

        Assert.False(OpeOptionsValidator.IsValid(options, isDevelopment: false));
    }

    [Fact]
    public void OptionsValidator_AcceptsTenUniqueConfiguredFields()
    {
        var options = new OpeOptions
        {
            ClientToken = "client",
            SecretKey = "test-secret-key-with-more-than-32-characters",
            PublicBaseUrl = "https://ope.example.test",
            OrganizationId = "organization",
            OrganizationDir3 = "dir3",
            OrganizationCif = "cif",
            OutputFields = OpeFieldMapper.SupportedInternalFields.Take(10).ToList()
        };

        Assert.True(OpeOptionsValidator.IsValid(options, isDevelopment: false));
    }
}
