/**
 * Converte um valor monetário em reais (pt-BR) para extenso.
 *
 * Ex: 1234.56 → "mil duzentos e trinta e quatro reais e cinquenta e seis centavos"
 *     150     → "cento e cinquenta reais"
 *     0.75    → "setenta e cinco centavos"
 *
 * Usado em recibos profissionais e documentos formais (CFP exige valor por
 * extenso em alguns modelos). Não-localizado a R$ — só o número por extenso
 * (o template adiciona "R$" no prefixo se quiser).
 */

const UNIDADES = ['', 'um', 'dois', 'três', 'quatro', 'cinco', 'seis', 'sete', 'oito', 'nove'];
const DEZ_A_DEZENOVE = ['dez', 'onze', 'doze', 'treze', 'quatorze', 'quinze', 'dezesseis', 'dezessete', 'dezoito', 'dezenove'];
const DEZENAS = ['', '', 'vinte', 'trinta', 'quarenta', 'cinquenta', 'sessenta', 'setenta', 'oitenta', 'noventa'];
const CENTENAS = ['', 'cento', 'duzentos', 'trezentos', 'quatrocentos', 'quinhentos', 'seiscentos', 'setecentos', 'oitocentos', 'novecentos'];

function centenaPorExtenso(n) {
    if (n === 0) return '';
    if (n === 100) return 'cem';

    const c = Math.floor(n / 100);
    const dezAUm = n % 100;
    const d = Math.floor(dezAUm / 10);
    const u = dezAUm % 10;

    const parts = [];
    if (c > 0) parts.push(CENTENAS[c]);

    if (d === 1) {
        parts.push(DEZ_A_DEZENOVE[u]);
    } else {
        if (d > 1) parts.push(DEZENAS[d]);
        if (u > 0) {
            if (d > 1) parts.push('e ' + UNIDADES[u]);
            else parts.push(UNIDADES[u]);
        }
    }

    return parts.join(' e ').replace(/ e $/, '');
}

function grupoPorExtenso(n) {
    if (n === 0) return '';
    return centenaPorExtenso(n);
}

/**
 * Converte um número inteiro até 999.999.999 para extenso em português.
 */
function inteiroPorExtenso(n) {
    if (n === 0) return 'zero';

    const milhao = Math.floor(n / 1000000);
    const milhar = Math.floor((n % 1000000) / 1000);
    const centena = n % 1000;

    const parts = [];

    if (milhao > 0) {
        parts.push(milhao === 1 ? 'um milhão' : grupoPorExtenso(milhao) + ' milhões');
    }
    if (milhar > 0) {
        parts.push(milhar === 1 ? 'mil' : grupoPorExtenso(milhar) + ' mil');
    }
    if (centena > 0) {
        parts.push(grupoPorExtenso(centena));
    }

    return parts.join(' e ').trim();
}

/**
 * Valor monetário (Number) → "X reais e Y centavos".
 *
 * @param {number|string} valor
 * @returns {string} — vazio se valor inválido
 */
export function valorExtenso(valor) {
    const num = Number(valor);
    if (!isFinite(num) || num < 0) return '';

    const reais = Math.floor(num);
    const centavos = Math.round((num - reais) * 100);

    const partes = [];
    if (reais > 0) {
        partes.push(inteiroPorExtenso(reais) + (reais === 1 ? ' real' : ' reais'));
    }
    if (centavos > 0) {
        partes.push(inteiroPorExtenso(centavos) + (centavos === 1 ? ' centavo' : ' centavos'));
    }

    if (partes.length === 0) return 'zero real';
    return partes.join(' e ');
}

export default valorExtenso;
