// ======================================================================
// controller.stt.js — versão FINAL com comandos universais integrados
// ======================================================================


// ======================================================================
// Normalização de números conforme idioma do card
// ======================================================================
function fixNumberStyle(spoken, expected){

    if (!spoken) return spoken;
    if (!expected) return spoken;

    const NUM_MAP = {
        "un": "1", "une": "1",
        "deux": "2",
        "trois": "3",
        "quatre": "4",
        "cinq": "5",
        "six": "6",
        "sept": "7",
        "huit": "8",
        "neuf": "9",
        "dix": "10",
        "onze": "11",
        "douze": "12",
        "treize": "13",
        "quatorze": "14",
        "quinze": "15",
        "seize": "16",
        "vingt": "20"
    };

    if (/\b\d+\b/.test(expected)) {
        for (const txt in NUM_MAP){
            const num = NUM_MAP[txt];
            spoken = spoken.replace(new RegExp(`\\b${txt}\\b`, "gi"), num);
        }
        return spoken;
    }

    for (const txt in NUM_MAP){
        const num = NUM_MAP[txt];
        if (new RegExp(`\\b${txt}\\b`, "i").test(expected)){
            spoken = spoken.replace(new RegExp(`\\b${num}\\b`, "g"), txt);
        }
    }

    return spoken;
}



// ======================================================================
// *** COMANDOS UNIVERSAIS DE VOZ (commands.js embutido aqui) ***
// ======================================================================

// 1) Palavras para cada comando:

window.CMD_CURRENT = ["ok"];   // repetir card atual

window.CMD_BACK = [
    "bach", "bac", "beck", "back",
    "마켓", "마켓.",
    "バック", "バック。"
];

window.CMD_NEXT = [
    "next",
    "ネクスト"
];


// 2) Normalização universal
window.normCmd = function (s){
    if (!s) return "";

    return s
        .toLowerCase()
        .normalize("NFD").replace(/[\u0300-\u036f]/g, "")
        .replace(/[^\p{L}\p{N}]/gu, "") // remove símbolos e pontuação
        .trim();
};


// 3) Detector universal
window.detectVoiceCommand = function (rawText){

    const txt = normCmd(rawText);

    if (window.CMD_CURRENT.map(normCmd).includes(txt))
        return "current";

    if (window.CMD_BACK.map(normCmd).includes(txt))
        return "back";

    if (window.CMD_NEXT.map(normCmd).includes(txt))
        return "next";

    return null;
};


// 4) 3 beeps de confirmação
window.playCommandBeep = function(){
    const beep = new Audio("beep.mp3");
    beep.play();
    setTimeout(() => beep.play(), 120);
    setTimeout(() => beep.play(), 240);
};



// ======================================================================
// STT PRINCIPAL
// ======================================================================
(function(){

    function qs(sel){ return document.querySelector(sel); }

    window.bindSTT = function(){

        // AJUSTA IDIOMA DO STT PARA O "TO"
        if (SttEngine && SttEngine.recognition){
            SttEngine.recognition.lang = LANGS_BCP[ window.CFG.to ];
            console.log("🚀 STT ouvindo idioma:", SttEngine.recognition.lang);
        }

        SttEngine.onPartial = (txt)=>{
            UI.updateHeardFooter(
                LANGS[window.TO],
                txt.toLowerCase().replace(/#(\d+)/g,"$1")
            );
        };

        let buffer = "";
        let timer  = null;

        SttEngine.onFinal = (txt)=>{

            if (window.showWait) showWait();

            buffer = (buffer + " " + txt).trim();

            if (timer) clearTimeout(timer);

            timer = setTimeout(()=>{

                const finalRaw  = buffer;
                const finalText = buffer.toLowerCase();

                buffer = "";
                timer  = null;



                // ==================================================================
                // *** COMANDOS UNIVERSAIS (OK / BACK / NEXT) ***
                // ==================================================================
                const cmd = detectVoiceCommand(finalRaw);

                if (cmd){
                    console.log("🎤 Comando detectado:", cmd);
                    playCommandBeep();

                    if (cmd === "current"){
                        if (window.repeatCurrentCard)
                            repeatCurrentCard();
                        if (window.hideWait) hideWait();
                        return;
                    }

                    if (cmd === "back"){
                        if (window.goPrevCard)
                            goPrevCard();
                        if (window.hideWait) hideWait();
                        return;
                    }

                    if (cmd === "next"){
                        if (window.goNextCard)
                            goNextCard();
                        if (window.hideWait) hideWait();
                        return;
                    }
                }



                // ==================================================================
                // Atualiza footer
                // ==================================================================
                UI.updateHeardFooter(
                    LANGS[window.TO],
                    finalText.replace(/#(\d+)/g, "$1")
                );



                // ==================================================================
                // Identifica card correspondente
                // ==================================================================
                const card = window.bestCardFor(finalRaw);

                let finalFixed = finalRaw;

                if (card){
                    const expected = card.dataset.to || "";
                    finalFixed = fixNumberStyle(finalRaw, expected);
                }

                UI.updateHeardFooter(
                    LANGS[window.TO],
                    finalFixed.toLowerCase().replace(/#(\d+)/g,"$1")
                );



                // ==================================================================
                // Processar acerto/erro (card-0 só compara se modo diálogo NÃO ativo)
                // ==================================================================
                let isCardZero = false;
                if (card && card.id === "card-0") isCardZero = true;
                const modoDialogo = document.getElementById('chkNodoDialogo');
                const dialogoAtivo = !!(modoDialogo && modoDialogo.checked);
                if (card) {
                    if (isCardZero && dialogoAtivo) {
                        // Só exibe texto reconhecido, não compara/acerta/erra
                        if (card.querySelector('.card-recognized')) {
                            card.querySelector('.card-recognized').textContent = finalFixed;
                        }
                    } else {
                        processCardRecognition(card, finalFixed);
                    }
                } else {
                    UI.toast("🤔 Não encontrei CARD correspondente.", 2000);
                }


                // ==================================================================
                // Stats + autoStop
                // ==================================================================
                UI.updateStats();
                checkAutoStop();

                if (window.hideWait) hideWait();

            }, 900);
        };
    };



    // ==================================================================
    // ACERTO / ERRO
    // ==================================================================
    function processCardRecognition(card, finalText){
        const alreadyHit  = card.classList.contains("hit");
        const recognized = card.querySelector(".card-recognized");
        if (recognized) recognized.textContent = finalText;

        // LOGS DE DIAGNÓSTICO
        console.log("[DIAG] processCardRecognition:", {
            cardId: card.id,
            finalText,
            expected: card.dataset.to,
            fuzzyResult: fuzzyMatch(finalText, card.dataset.to)
        });

        if (fuzzyMatch(finalText, card.dataset.to)){
            // Feedback visual/textual sempre
            UI.toast("✅ Acertou!");
            card.classList.add("hit");
            card.classList.remove("blue");
            if (window.UI && window.UI.clearPronunciationError) window.UI.clearPronunciationError(card);
            incrementCardCounter(card);
            window.playBeep();

            // Garante centralização do card acertado
            if (typeof markAsCurrent === 'function') markAsCurrent(card);

            const idx   = parseInt(card.id.replace("card-",""));
            const obj   = window.CARDS_DATA[idx];
            const count = obj?._count || 0;

            if (window.HIT_TARGET && count === window.HIT_TARGET){
                setTimeout(()=>window.playBeep(),150);
                setTimeout(()=>window.playBeep(),300);
                if (window.speakNextFrom) speakNextFrom(card);
            }

            return;
        }

        card.classList.add("blue");
        card.classList.remove("hit");
        if (window.UI && window.UI.markPronunciationError) window.UI.markPronunciationError(card);
        // Dispara evento customizado para o AutoPlayer
        card.dispatchEvent(new CustomEvent('pronunciation-error'));
        // NÃO remove .autoplay-current aqui!
        incrementCardCounter(card);

        UI.toast("❌ Não corresponde", 1500);
    }

    // Limpar todos os destaques amarelos no reset
    window.resetAutoplayHighlights = function(){
      if (window.UI && window.UI.clearAllAutoplayCurrent) window.UI.clearAllAutoplayCurrent();
    };

    // ==================================================================
    // AUTO-STOP
    // ==================================================================
    function checkAutoStop(){

        const visible = UI.getVisibleCards();

        const completed = visible.every(c =>
            c.classList.contains("hit") ||
            c.classList.contains("blue")
        );

        if (!completed) return;

        if (AutoPlayer.running){
            AutoPlayer.stop();
            const b = qs("#btnAuto");
            if (b) b.textContent = "▶️ Auto (Iniciar)";
        }

        if (SttEngine.enabled){
            SttEngine.stop();
            const mic = qs("#btnMic");
            if (mic) mic.textContent = "🎤 Microfone";
        }

        // Se modo diálogo está ativo, mostra mensagem especial
        const modoDialogo = document.getElementById('chkNodoDialogo');
        const dialogoAtivo = !!(modoDialogo && modoDialogo.checked);
        if (dialogoAtivo) {
            setTimeout(() => {
                // Exibe popup modal centralizado
                const modal = document.getElementById('dialogoModal');
                if (modal) {
                  modal.style.display = 'flex';
                  // Some após 5 segundos
                  setTimeout(() => {
                    modal.style.display = 'none';
                  }, 5000);
                }
            }, 100);
        } else {
            setTimeout(() => {
                UI.toast("🎉 Todos concluídos!");
            }, 100);
        }
    }


    // ======================================================================
    // FUNÇÕES DE NAVEGAÇÃO POR VOZ (OBRIGATÓRIAS)
    // ======================================================================

    // Guarda índice atual apenas para referência (sincronizado pelo DOM)
    window.CURRENT_INDEX = 0;

    // Helper: obter o "card atual" para comandos de voz
    function getCurrentVoiceCard(){
        // 1) preferir o autoplay-current (usado pelo AutoPlayer)
        let card = document.querySelector(".autoplay-current");

        // 2) se não tiver, usar algum card já interagido
        if (!card){
            card = document.querySelector(".card.spoken, .card.hit, .card.blue");
        }

        // 3) se ainda não tiver, pegar o primeiro visível
        if (!card){
            const list = UI.getVisibleCards();
            if (!list.length) return null;
            card = list[0];
        }

        return card;
    }

    // Atualiza CURRENT_INDEX e marca visivelmente
    function markAsCurrent(card){
        if (!card) return;
        const id = card.id || "";
        const idx = parseInt(id.replace("card-","")) || 0;
        window.CURRENT_INDEX = idx;
        if (UI.setAutoplayCurrent){
            UI.setAutoplayCurrent(card);
        }
    }

    // ----------------------------------------------------------
    // Repetir card atual (OK)
    // ----------------------------------------------------------
    window.repeatCurrentCard = function(){
        window.playBeep();

        const card = getCurrentVoiceCard();
        if (!card){
            console.warn("repeatCurrentCard(): nenhum card disponível");
            return;
        }

        markAsCurrent(card);

        // FALA EXATAMENTE O CARD ATUAL
        if (window.speakCardText){
            window.speakCardText(card);
        }
    };

    // ----------------------------------------------------------
    // Ir para o próximo card (NEXT)
    // ----------------------------------------------------------
    window.goNextCard = function(){
        window.playBeep();

        const list = UI.getVisibleCards();
        if (!list.length){
            UI.toast("Nenhum CARD disponível.");
            return;
        }

        const current = getCurrentVoiceCard();
        const idxCur  = list.indexOf(current);
        let nextIdx   = idxCur >= 0 ? idxCur + 1 : 0;

        if (nextIdx >= list.length){
            nextIdx = list.length - 1; // trava no último
        }

        const target = list[nextIdx];
        if (!target) return;

        markAsCurrent(target);

        if (window.speakCardText){
            window.speakCardText(target);
        }
    };

    // ----------------------------------------------------------
    // Ir para o card anterior (BACK)
    // ----------------------------------------------------------
    window.goPrevCard = function(){
        window.playBeep();

        const list = UI.getVisibleCards();
        if (!list.length){
            UI.toast("Nenhum CARD disponível");
            return;
        }

        const current = getCurrentVoiceCard();
        const idxCur  = list.indexOf(current);
        let prevIdx   = idxCur >= 0 ? idxCur - 1 : 0;

        if (prevIdx < 0){
            prevIdx = 0; // trava no primeiro
        }

        const target = list[prevIdx];
        if (!target) return;

        markAsCurrent(target);

        if (window.speakCardText){
            window.speakCardText(target);
        }
    };

})();
