const overlaysCtx = {
    inicio: null,
    nivel: null,
    fin: null,
    incompatible: null,
    pausa: null,
    ayuda: null,
    nickname: null,
    ranking: null,
    btnEmpezar: null,
    btnContinuar: null,
    nivelTitulo: null,
    nivelTexto: null,
    nivelContinuar: null,
    finTitulo: null,
    finTexto: null,
    finReintentar: null,
    btnPausaContinuar: null,
    btnPausaAyuda: null,
    btnPausaReiniciar: null,
    btnPausaRanking: null,
    btnAyudaCerrar: null,
    btnRankingInicio: null,
    btnRankingCerrar: null,
    btnRankingCambiarNick: null,
    btnNicknameGuardar: null,
    btnNicknameCancelar: null,
    nicknameInput: null,
    nicknameError: null,
    rankingList: null,
    rankingNickInfo: null,
    nicknamePending: null,
    onEmpezar: null,
    onContinuar: null,
    onSiguienteNivel: null,
    onReintentar: null,
    onReiniciarNivel: null
};

function initOverlays() {
    overlaysCtx.inicio = document.getElementById('overlay-inicio');
    overlaysCtx.nivel = document.getElementById('overlay-nivel');
    overlaysCtx.fin = document.getElementById('overlay-fin');
    overlaysCtx.incompatible = document.getElementById('incompatible');
    overlaysCtx.pausa = document.getElementById('overlay-pausa');
    overlaysCtx.ayuda = document.getElementById('overlay-ayuda');

    overlaysCtx.btnEmpezar = document.getElementById('btn-empezar');
    overlaysCtx.btnContinuar = document.getElementById('btn-continuar');
    overlaysCtx.nivelTitulo = document.getElementById('nivel-titulo');
    overlaysCtx.nivelTexto = document.getElementById('nivel-texto');
    overlaysCtx.nivelContinuar = document.getElementById('nivel-continuar');
    overlaysCtx.finTitulo = document.getElementById('fin-titulo');
    overlaysCtx.finTexto = document.getElementById('fin-texto');
    overlaysCtx.finReintentar = document.getElementById('fin-reintentar');
    overlaysCtx.btnPausaContinuar = document.getElementById('btn-pausa-continuar');
    overlaysCtx.btnPausaAyuda = document.getElementById('btn-pausa-ayuda');
    overlaysCtx.btnPausaReiniciar = document.getElementById('btn-pausa-reiniciar');
    overlaysCtx.btnPausaRanking = document.getElementById('btn-pausa-ranking');
    overlaysCtx.btnAyudaCerrar = document.getElementById('btn-ayuda-cerrar');
    overlaysCtx.nickname = document.getElementById('overlay-nickname');
    overlaysCtx.ranking = document.getElementById('overlay-ranking');
    overlaysCtx.btnRankingInicio = document.getElementById('btn-ranking-inicio');
    overlaysCtx.btnRankingCerrar = document.getElementById('btn-ranking-cerrar');
    overlaysCtx.btnRankingCambiarNick = document.getElementById('btn-ranking-cambiar-nick');
    overlaysCtx.btnNicknameGuardar = document.getElementById('btn-nickname-guardar');
    overlaysCtx.btnNicknameCancelar = document.getElementById('btn-nickname-cancelar');
    overlaysCtx.nicknameInput = document.getElementById('nickname-input');
    overlaysCtx.nicknameError = document.getElementById('nickname-error');
    overlaysCtx.rankingList = document.getElementById('ranking-list');
    overlaysCtx.rankingNickInfo = document.getElementById('ranking-nick-info');

    overlaysCtx.btnEmpezar.addEventListener('click', () => {
        hideOverlay(overlaysCtx.inicio);
        if (overlaysCtx.onEmpezar) overlaysCtx.onEmpezar();
    });
    overlaysCtx.btnContinuar.addEventListener('click', () => {
        hideOverlay(overlaysCtx.inicio);
        if (overlaysCtx.onContinuar) overlaysCtx.onContinuar();
    });
    overlaysCtx.nivelContinuar.addEventListener('click', () => {
        hideOverlay(overlaysCtx.nivel);
        if (overlaysCtx.onSiguienteNivel) overlaysCtx.onSiguienteNivel();
    });
    overlaysCtx.finReintentar.addEventListener('click', () => {
        hideOverlay(overlaysCtx.fin);
        if (overlaysCtx.onReintentar) overlaysCtx.onReintentar();
    });
    if (overlaysCtx.btnPausaContinuar) {
        overlaysCtx.btnPausaContinuar.addEventListener('click', cerrarPausa);
    }
    if (overlaysCtx.btnPausaAyuda) {
        overlaysCtx.btnPausaAyuda.addEventListener('click', () => {
            hideOverlay(overlaysCtx.pausa);
            showOverlay(overlaysCtx.ayuda);
        });
    }
    if (overlaysCtx.btnPausaReiniciar) {
        overlaysCtx.btnPausaReiniciar.addEventListener('click', () => {
            hideOverlay(overlaysCtx.pausa);
            if (overlaysCtx.onReiniciarNivel) overlaysCtx.onReiniciarNivel();
        });
    }
    if (overlaysCtx.btnAyudaCerrar) {
        overlaysCtx.btnAyudaCerrar.addEventListener('click', () => {
            hideOverlay(overlaysCtx.ayuda);
            if (gameState.paused) showOverlay(overlaysCtx.pausa);
        });
    }
    if (overlaysCtx.btnPausaRanking) {
        overlaysCtx.btnPausaRanking.addEventListener('click', () => {
            hideOverlay(overlaysCtx.pausa);
            mostrarRanking({ from: 'pausa' });
        });
    }
    if (overlaysCtx.btnRankingInicio) {
        overlaysCtx.btnRankingInicio.addEventListener('click', () => {
            mostrarRanking({ from: 'inicio' });
        });
    }
    if (overlaysCtx.btnRankingCerrar) {
        overlaysCtx.btnRankingCerrar.addEventListener('click', cerrarRanking);
    }
    if (overlaysCtx.btnRankingCambiarNick) {
        overlaysCtx.btnRankingCambiarNick.addEventListener('click', () => {
            hideOverlay(overlaysCtx.ranking);
            pedirNickname({ next: () => mostrarRanking({ from: 'ranking' }) });
        });
    }
    if (overlaysCtx.btnNicknameGuardar) {
        overlaysCtx.btnNicknameGuardar.addEventListener('click', _confirmarNickname);
    }
    if (overlaysCtx.nicknameInput) {
        overlaysCtx.nicknameInput.addEventListener('keydown', (e) => {
            if (e.key === 'Enter') { e.preventDefault(); _confirmarNickname(); }
        });
    }
    if (overlaysCtx.btnNicknameCancelar) {
        overlaysCtx.btnNicknameCancelar.addEventListener('click', () => {
            hideOverlay(overlaysCtx.nickname);
            overlaysCtx.nicknamePending = null;
        });
    }

    const menuBtn = document.getElementById('menu-btn');
    if (menuBtn) {
        menuBtn.addEventListener('click', (e) => {
            e.preventDefault();
            if (pausaActiva() || ayudaActiva()) {
                cerrarPausa();
            } else if (puedePausar()) {
                mostrarPausa();
            }
        });
    }

    window.addEventListener('keydown', (e) => {
        if (e.key !== 'Escape') return;
        if (nicknameActivo()) {
            e.preventDefault();
            hideOverlay(overlaysCtx.nickname);
            overlaysCtx.nicknamePending = null;
            return;
        }
        if (rankingActivo()) {
            e.preventDefault();
            cerrarRanking();
            return;
        }
        if (ayudaActiva()) {
            e.preventDefault();
            hideOverlay(overlaysCtx.ayuda);
            if (gameState.paused) showOverlay(overlaysCtx.pausa);
            return;
        }
        if (pausaActiva()) {
            e.preventDefault();
            cerrarPausa();
            return;
        }
        if (puedePausar()) {
            e.preventDefault();
            mostrarPausa();
        }
    });
}

function pausaActiva() {
    return overlaysCtx.pausa && overlaysCtx.pausa.classList.contains('overlay-active');
}

function ayudaActiva() {
    return overlaysCtx.ayuda && overlaysCtx.ayuda.classList.contains('overlay-active');
}

function puedePausar() {
    if (!gameState.started) return false;
    if (gameState.encuentroActivo) return false;
    if (gameState.gameOver) return false;
    if (gameState.nivelCompletado) return false;
    if (overlaysCtx.inicio && overlaysCtx.inicio.classList.contains('overlay-active')) return false;
    if (overlaysCtx.fin && overlaysCtx.fin.classList.contains('overlay-active')) return false;
    if (overlaysCtx.nivel && overlaysCtx.nivel.classList.contains('overlay-active')) return false;
    return true;
}

function mostrarPausa() {
    if (!puedePausar()) return;
    gameState.paused = true;
    showOverlay(overlaysCtx.pausa);
}

function cerrarPausa() {
    hideOverlay(overlaysCtx.pausa);
    hideOverlay(overlaysCtx.ayuda);
    if (!gameState.encuentroActivo && !gameState.gameOver && !gameState.nivelCompletado) {
        gameState.paused = false;
    }
}

function setOverlayCallbacks(cbs) {
    Object.assign(overlaysCtx, cbs);
}

function showOverlay(el) {
    if (!el) return;
    el.hidden = false;
    el.classList.add('overlay-active');
}

function hideOverlay(el) {
    if (!el) return;
    el.hidden = true;
    el.classList.remove('overlay-active');
}

function actualizarBotonContinuar(hayPartida) {
    overlaysCtx.btnContinuar.hidden = !hayPartida;
}

function showOverlayInicio() {
    showOverlay(overlaysCtx.inicio);
}

function showOverlayNivelCompletado(nivel, tiempoSegundos, esVictoriaFinal) {
    if (esVictoriaFinal) {
        overlaysCtx.nivelTitulo.textContent = '¡Has llegado a casa!';
        overlaysCtx.nivelTexto.textContent =
            `Has aguantado ${NIVELES.length} niveles. La calle te ha respetado. Cierra la puerta y respira.`;
        overlaysCtx.nivelContinuar.textContent = 'VOLVER AL MENÚ';
    } else {
        const idxMostrar = (gameState.nivelIdx || 0) + 1;
        overlaysCtx.nivelTitulo.textContent = `Nivel ${idxMostrar} superado`;
        const subtitulo = nivel && nivel.nombre ? `${nivel.nombre} · ` : '';
        overlaysCtx.nivelTexto.textContent =
            `${subtitulo}Tiempo: ${tiempoSegundos.toFixed(1)}s · Paciencia restante: ${Math.round(gameState.paciencia)}/${PACIENCIA_INICIAL}`;
        overlaysCtx.nivelContinuar.textContent = 'SIGUIENTE NIVEL';
    }
    if (typeof playSfx === 'function') playSfx(esVictoriaFinal ? 'victory' : 'levelComplete');
    showOverlay(overlaysCtx.nivel);
}

function showOverlayGameOver() {
    const esFinal = gameState.vidas <= 0;
    let titulo;
    let texto;
    if (gameState.causaMuerte) {
        titulo = 'Final del camino';
        texto = gameState.causaMuerte;
        gameState.causaMuerte = null;
    } else if (esFinal) {
        titulo = 'Te ha podido la calle';
        texto = 'Sin vidas. Vuelve a empezar desde el primer nivel.';
    } else {
        titulo = 'Te ha podido la calle';
        texto = 'Has perdido la paciencia. Otra vida, otro intento.';
    }
    if (esFinal) {
        const maxLvl = Math.max(1, gameState.runMaxLevel || (gameState.nivelIdx + 1));
        const t = _formatTiempo(gameState.runTotalMs || 0);
        texto += ' · Nivel ' + maxLvl + ' · ' + t;
    }
    overlaysCtx.finTitulo.textContent = titulo;
    overlaysCtx.finTexto.textContent = texto;
    if (typeof playSfx === 'function') playSfx(esFinal ? 'gameOver' : 'lifeLost');
    showOverlay(overlaysCtx.fin);

    if (esFinal && (gameState.runTotalMs || 0) > 1000) {
        const payload = {
            maxLevel: Math.max(1, gameState.runMaxLevel || 1),
            totalTimeMs: Math.floor(gameState.runTotalMs)
        };
        const nick = (typeof getNickname === 'function') ? getNickname() : null;
        if (nick) {
            if (typeof submitScore === 'function') {
                submitScore(payload).catch(() => {});
            }
        } else if (typeof pedirNickname === 'function') {
            pedirNickname({
                next: () => {
                    if (typeof submitScore === 'function') {
                        submitScore(payload).then(() => mostrarRanking({ from: 'gameover' })).catch(() => {});
                    }
                }
            });
        }
    }
}

function showIncompatible() {
    showOverlay(overlaysCtx.incompatible);
}

function _formatTiempo(ms) {
    if (!Number.isFinite(ms)) return '--';
    const totalSec = Math.floor(ms / 1000);
    const m = Math.floor(totalSec / 60);
    const s = totalSec % 60;
    return m + ':' + String(s).padStart(2, '0');
}

function pedirNickname({ next, prefill } = {}) {
    if (!overlaysCtx.nickname || !overlaysCtx.nicknameInput) return;
    overlaysCtx.nicknamePending = next || null;
    overlaysCtx.nicknameInput.value = prefill || (typeof getNickname === 'function' ? (getNickname() || '') : '');
    if (overlaysCtx.nicknameError) {
        overlaysCtx.nicknameError.hidden = true;
        overlaysCtx.nicknameError.textContent = '';
    }
    showOverlay(overlaysCtx.nickname);
    setTimeout(() => { try { overlaysCtx.nicknameInput.focus(); } catch (e) {} }, 50);
}

function _confirmarNickname() {
    if (typeof setNickname !== 'function' || !overlaysCtx.nicknameInput) return;
    const value = overlaysCtx.nicknameInput.value;
    const saved = setNickname(value);
    if (!saved) {
        if (overlaysCtx.nicknameError) {
            overlaysCtx.nicknameError.textContent = 'Nick inválido (2–16 caracteres, sin símbolos raros).';
            overlaysCtx.nicknameError.hidden = false;
        }
        return;
    }
    hideOverlay(overlaysCtx.nickname);
    const next = overlaysCtx.nicknamePending;
    overlaysCtx.nicknamePending = null;
    if (typeof next === 'function') next();
}

function mostrarRanking({ from } = {}) {
    if (!overlaysCtx.ranking) return;
    const nick = (typeof getNickname === 'function') ? getNickname() : null;
    if (overlaysCtx.rankingNickInfo) {
        overlaysCtx.rankingNickInfo.textContent = nick
            ? 'Compites como ' + nick
            : 'Sin nick — guarda uno para aparecer en el ranking.';
    }
    if (overlaysCtx.rankingList) {
        overlaysCtx.rankingList.innerHTML = '<p class="ranking-loading">Cargando...</p>';
    }
    showOverlay(overlaysCtx.ranking);
    if (typeof fetchTop !== 'function') {
        if (overlaysCtx.rankingList) {
            overlaysCtx.rankingList.innerHTML = '<p class="ranking-error">Ranking no disponible.</p>';
        }
        return;
    }
    fetchTop(20).then((res) => {
        if (!overlaysCtx.rankingList) return;
        if (!res.ok) {
            overlaysCtx.rankingList.innerHTML = '<p class="ranking-error">No se pudo cargar el ranking.</p>';
            return;
        }
        const top = (res.data && res.data.top) || [];
        if (top.length === 0) {
            overlaysCtx.rankingList.innerHTML = '<p class="ranking-empty">Aún no hay puntuaciones. ¡Sé el primero!</p>';
            return;
        }
        const myNickLower = nick ? nick.toLowerCase() : null;
        const rows = top.map((r) => {
            const isMe = myNickLower && r.nickname.toLowerCase() === myNickLower;
            const cls = ['ranking-row'];
            if (isMe) cls.push('is-me');
            if (r.rank === 1) cls.push('is-top1');
            else if (r.rank === 2) cls.push('is-top2');
            else if (r.rank === 3) cls.push('is-top3');
            const safeNick = String(r.nickname).replace(/[<>&"]/g, (c) => ({ '<':'&lt;', '>':'&gt;', '&':'&amp;', '"':'&quot;' }[c]));
            return '<div class="' + cls.join(' ') + '">'
                + '<span class="ranking-rank">#' + r.rank + '</span>'
                + '<span class="ranking-nick">' + safeNick + '</span>'
                + '<span class="ranking-level">N' + r.maxLevel + '</span>'
                + '<span class="ranking-time">' + _formatTiempo(r.totalTimeMs) + '</span>'
                + '</div>';
        }).join('');
        overlaysCtx.rankingList.innerHTML = rows;
    });
}

function cerrarRanking() {
    hideOverlay(overlaysCtx.ranking);
    if (gameState.paused) showOverlay(overlaysCtx.pausa);
}

function rankingActivo() {
    return overlaysCtx.ranking && overlaysCtx.ranking.classList.contains('overlay-active');
}

function nicknameActivo() {
    return overlaysCtx.nickname && overlaysCtx.nickname.classList.contains('overlay-active');
}
