using System.Text.RegularExpressions;

namespace Nalu.Web.PostProcessors;

public class FormatPhone : IPostProcessor
{
    public string Name => "format_phone";

    public ProcessorResult Process(string? value)
    {
        if (string.IsNullOrWhiteSpace(value)) return ProcessorResult.Invalid("Telefone não informado");

        var digits = Regex.Replace(value, @"\D", "");

        // Strip Brazilian country code +55
        if (digits.StartsWith("55") && digits.Length is 12 or 13)
            digits = digits[2..];

        return digits.Length switch
        {
            11 => FormatMobile(digits),
            10 => FormatLandline(digits),
            _ => ProcessorResult.Invalid("Telefone inválido (esperado 10 ou 11 dígitos com DDD)")
        };
    }

    private static ProcessorResult FormatMobile(string digits)
    {
        var ddd = digits[..2];
        if (!IsValidDdd(ddd)) return ProcessorResult.Invalid($"DDD inválido: {ddd}");
        if (digits[2] != '9') return ProcessorResult.Invalid("Celular deve começar com 9 após o DDD");
        return ProcessorResult.Ok($"({ddd}) {digits[2..7]}-{digits[7..]}");
    }

    private static ProcessorResult FormatLandline(string digits)
    {
        var ddd = digits[..2];
        if (!IsValidDdd(ddd)) return ProcessorResult.Invalid($"DDD inválido: {ddd}");
        return ProcessorResult.Ok($"({ddd}) {digits[2..6]}-{digits[6..]}");
    }

    // Complete list of valid Brazilian DDDs per ANATEL (Plano de Numeração)
    // Source: anatel.gov.br/outorga/plano-de-numeracao
    private static readonly HashSet<string> ValidDdds =
    [
        // São Paulo
        "11","12","13","14","15","16","17","18","19",
        // Rio de Janeiro, Espírito Santo
        "21","22","24","27","28",
        // Minas Gerais
        "31","32","33","34","35","37","38",
        // Paraná
        "41","42","43","44","45","46",
        // Santa Catarina
        "47","48","49",
        // Rio Grande do Sul
        "51","53","54","55",
        // Distrito Federal / Goiás / Tocantins / MT / MS / AC / RO
        "61","62","63","64","65","66","67","68","69",
        // Bahia, Sergipe
        "71","73","74","75","77","79",
        // PE, AL, PB, RN, CE, PI
        "81","82","83","84","85","86","87","88","89",
        // PA, AM, RR, AP, MA, RO (norte)
        "91","92","93","94","95","96","97","98","99",
    ];

    private static bool IsValidDdd(string ddd) => ValidDdds.Contains(ddd);
}
