// ===============================================================
// controller.fuzzy.js — SUPORTE A 3 NÍVEIS DE PRECISÃO + NÚMEROS
// MODOS (A/B/C):
//   1 - MODO A  → SUPER PRECISO (zero tolerância)  🔵 (recomendado)
//   2 - MODO B  → PRECISO + pequena tolerância
//   3 - MODO C  → FLEXÍVEL INTELIGENTE
// ---------------------------------------------------------------
// Mude o modo aqui:
// ===============================================================

window.MATCH_MODE = 2;   // 🟡 MODO B (tolerância leve por padrão)


// ===============================================================
// NORMALIZAÇÃO BASE
// ===============================================================
function baseNorm(s){
    if (!s) return "";
    return s.toLowerCase()
        .normalize("NFD").replace(/[\u0300-\u036f]/g,"") // tira acento
        .replace(/[^\p{L}\p{N}\s]/gu,"")                 // só letra/número/espaço
        .replace(/\s+/g," ")
        .trim();
}


// ===============================================================
// NORMALIZAÇÃO FRANCESA INTELIGENTE
//  (trata des/de/du/aux + plurais, etc.)
// ===============================================================
function normFRSmart(s){
    if (!s) return "";
    s = baseNorm(s);

    // artigos + plural
    s = s.replace(/\bdes\s+([a-z0-9]+)s?\b/g,"$1");
    s = s.replace(/\bde\s+([a-z0-9]+)s?\b/g,"$1");
    s = s.replace(/\bdu\s+([a-z0-9]+)\b/g,"$1");
    s = s.replace(/\bau[x]?\s+([a-z0-9]+)s?\b/g,"$1");

    // plural simples palavra+s → palavra
    s = s.replace(/\b([a-z0-9]+)s\b/g,"$1");

    return s.trim();
}


// ===============================================================
// FERRAMENTAS
// ===============================================================
function splitWords(s){
    return s.trim().split(/\s+/g).filter(Boolean);
}

function lastWord(s){
    const arr = splitWords(s);
    return arr[arr.length - 1] || "";
}


// ===============================================================
// DETECTA FRASE INCOMPLETA (usado no modo 1 e 2)
// ===============================================================
function isIncomplete(spoken, expected){
    const s = splitWords(spoken);
    const e = splitWords(expected);
    return s.length < e.length;
}


// ===============================================================
// fuzzyMatch — 3 MODOS + SUPORTE A NÚMEROS
//  • Usa baseNorm()
//  • Em seguida aplica normalizeNumbers() (global, do stt.js)
//    → "deux / two / dois" → "2", "vingt" → "20", etc.
//  • Depois normFRSmart()
// ===============================================================
function fuzzyMatch(spoken, expected) {
    if (!spoken || !expected) {
        console.log('[DIAG] fuzzyMatch: spoken or expected missing', {spoken, expected});
        return false;
    }

    // Normalização base
    let sNorm = baseNorm(spoken);
    let eNorm = baseNorm(expected);

    // Normalização de números
    if (typeof normalizeNumbers === "function") {
        sNorm = normalizeNumbers(sNorm);
        eNorm = normalizeNumbers(eNorm);
    }

    // Normalização francesa inteligente
    const sFR = normFRSmart(sNorm);
    const eFR = normFRSmart(eNorm);

    const sWords = splitWords(sFR);
    const eWords = splitWords(eFR);

    // LOGS DE DIAGNÓSTICO
    console.log('[DIAG] fuzzyMatch:', {
        spoken, expected, sNorm, eNorm, sFR, eFR, sWords, eWords, MATCH_MODE: window.MATCH_MODE
    });

    // MODE A (ultra preciso)
    if (window.MATCH_MODE === 1) {
        if (isIncomplete(sNorm, eNorm)) return false;
        if (sWords.length !== eWords.length) return false;
        for (let i = 0; i < eWords.length; i++) {
            if (sWords[i] !== eWords[i]) return false;
        }
        return true;
    }
    // MODE B (preciso + tolerância leve)
    if (window.MATCH_MODE === 2) {
        if (isIncomplete(sNorm, eNorm)) return false;
        if (lastWord(sFR) !== lastWord(eFR)) return false;
        let ok = 0;
        for (let i = 0; i < eWords.length; i++) {
            if (sWords[i] === eWords[i]) ok++;
        }
        return (ok >= eWords.length - 1);
    }
    // MODE C (flexível inteligente)
    if (window.MATCH_MODE === 3) {
        if (sWords.length < eWords.length - 1) return false;
        if (lastWord(sFR) !== lastWord(eFR)) return false;
        return true;
    }
    // fallback
    return false;
}



// EXPORT
window.fuzzyMatch   = fuzzyMatch;
window.normFRSmart  = normFRSmart;
window.baseNorm     = baseNorm;
window.lastWord     = lastWord;
