using System.Text.Json;
using Microsoft.Extensions.Logging;

namespace Nalu.Jobs;

public static class IbgeClient
{
    private static readonly JsonSerializerOptions JsonOpts = new()
    {
        PropertyNameCaseInsensitive = true
    };

    private static readonly (string Url, string? Genero)[] Endpoints =
    [
        ("https://servicodados.ibge.gov.br/api/v2/censos/nomes/ranking/",        null),
        ("https://servicodados.ibge.gov.br/api/v2/censos/nomes/ranking/?sexo=M", "M"),
        ("https://servicodados.ibge.gov.br/api/v2/censos/nomes/ranking/?sexo=F", "F"),
    ];

    /// <summary>
    /// Fetches names from the 3 IBGE ranking endpoints and aggregates into a single map.
    /// M+F overlap → genero becomes "N".
    /// </summary>
    public static async Task<Dictionary<string, AggregatedName>> FetchNamesAsync(
        HttpClient http,
        ILogger logger,
        CancellationToken ct)
    {
        var aggregated = new Dictionary<string, AggregatedName>(StringComparer.OrdinalIgnoreCase);

        foreach (var (url, generoOverride) in Endpoints)
        {
            logger.LogInformation("GET {Url}", url);

            var response = await http.GetAsync(url, ct);
            response.EnsureSuccessStatusCode();

            var raw = await response.Content.ReadAsStringAsync(ct);
            var groups = JsonSerializer.Deserialize<IbgeRankingGroup[]>(raw, JsonOpts) ?? [];

            foreach (var group in groups)
            {
                var groupGenero = generoOverride
                    ?? group.Sexo?.ToUpperInvariant() switch { "M" => "M", "F" => "F", _ => "N" };

                foreach (var entry in group.Res)
                {
                    if (string.IsNullOrWhiteSpace(entry.Nome)) continue;

                    var nomeUpper = entry.Nome.Trim().ToUpperInvariant();

                    if (aggregated.TryGetValue(nomeUpper, out var existing))
                    {
                        aggregated[nomeUpper] = existing with
                        {
                            Frequencia = Math.Max(existing.Frequencia, entry.Frequencia),
                            Genero     = existing.Genero == groupGenero ? groupGenero : "N"
                        };
                    }
                    else
                    {
                        aggregated[nomeUpper] = new AggregatedName(nomeUpper, entry.Frequencia, groupGenero);
                    }
                }

                logger.LogDebug("  → {Count} entries (total unique: {Total})", group.Res.Length, aggregated.Count);
            }
        }

        logger.LogInformation("IBGE fetch complete — {Count} unique names", aggregated.Count);
        return aggregated;
    }
}
