using System.Text.RegularExpressions;

namespace Nalu.Web.PostProcessors;

public class ValidateCpfDigit : IPostProcessor
{
    public string Name => "validate_cpf_digit";

    private static readonly string[] AllSameDigit =
        Enumerable.Range(0, 10).Select(i => new string((char)('0' + i), 11)).ToArray();

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

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

        if (digits.Length != 11)
            return ProcessorResult.Invalid("CPF deve ter 11 dígitos");

        if (Array.IndexOf(AllSameDigit, digits) >= 0)
            return ProcessorResult.Invalid("CPF inválido (dígitos repetidos)");

        if (!ValidateMod11(digits))
            return ProcessorResult.Invalid("CPF inválido (dígitos verificadores incorretos)");

        var formatted = $"{digits[..3]}.{digits[3..6]}.{digits[6..9]}-{digits[9..]}";
        return ProcessorResult.Ok(formatted);
    }

    private static bool ValidateMod11(string digits)
    {
        // First check digit
        int sum = 0;
        for (int i = 0; i < 9; i++) sum += (digits[i] - '0') * (10 - i);
        int rem = sum % 11;
        int d1 = rem < 2 ? 0 : 11 - rem;
        if (d1 != digits[9] - '0') return false;

        // Second check digit
        sum = 0;
        for (int i = 0; i < 10; i++) sum += (digits[i] - '0') * (11 - i);
        rem = sum % 11;
        int d2 = rem < 2 ? 0 : 11 - rem;
        return d2 == digits[10] - '0';
    }
}
