const encuentrosCtx = {
    activo: null,
    onResolved: null
};

function iniciarEncuentro(npc) {
    if (encuentrosCtx.activo) return null;
    gameState.encuentroActivo = true;
    gameState.paused = true;

    const arquetipo = npc.arquetipo;
    const tipo = arquetipo.tipoEncuentro;
    const config = TIPOS_ENCUENTRO[tipo];
    const frase = fraseAleatoriaNPC(arquetipo.id);

    const enc = {
        npc: npc,
        arquetipo: arquetipo,
        tipo: tipo,
        config: config,
        frase: frase,
        startedAt: performance.now(),
        duracionMs: arquetipo.encuentroDuracion * 1000,
        clicks: 0,
        targetClicks: config.targetClicks || 0,
        holding: false,
        holdAcumulado: 0,
        holdRequerido: arquetipo.encuentroDuracion * 1000,
        progresoBar: 1.0,
        finalizado: false,
        exito: false
    };
    encuentrosCtx.activo = enc;

    if (typeof playSfx === 'function') playSfx('encounterStart');
    if (typeof speakLine === 'function') speakLine(frase, arquetipo.id, { priority: 'high' });

    showEncuentroUI(enc);
    return new Promise((resolve) => {
        encuentrosCtx.onResolved = resolve;
    });
}

function tickEncuentro(dtMs) {
    const enc = encuentrosCtx.activo;
    if (!enc || enc.finalizado) return;

    const elapsed = performance.now() - enc.startedAt;

    if (enc.tipo === 'tap') {
        const remaining = Math.max(0, enc.duracionMs - elapsed);
        enc.progresoBar = remaining / enc.duracionMs;
        if (enc.clicks >= enc.targetClicks) {
            _resolverEncuentro(true);
            return;
        }
        if (remaining <= 0) {
            _resolverEncuentro(false);
        }
    } else if (enc.tipo === 'wait') {
        const remaining = Math.max(0, enc.duracionMs - elapsed);
        enc.progresoBar = remaining / enc.duracionMs;
        if (remaining <= 0) {
            _resolverEncuentro(true);
        }
    } else if (enc.tipo === 'hold') {
        if (enc.holding) {
            enc.holdAcumulado += dtMs;
            enc.progresoBar = 1 - (enc.holdAcumulado / enc.holdRequerido);
        } else {
            enc.holdAcumulado = Math.max(0, enc.holdAcumulado - dtMs * 0.6);
            enc.progresoBar = 1 - (enc.holdAcumulado / enc.holdRequerido);
        }
        if (enc.holdAcumulado >= enc.holdRequerido) {
            _resolverEncuentro(true);
        }
    }

    updateEncuentroUI(enc);
}

function registrarClickEncuentro() {
    const enc = encuentrosCtx.activo;
    if (!enc || enc.finalizado) return;

    if (enc.tipo === 'tap') {
        enc.clicks++;
        if (enc.clicks >= enc.targetClicks) {
            _resolverEncuentro(true);
        }
    } else if (enc.tipo === 'wait') {
        const cfg = enc.config;
        const pen = (cfg.clickPenalizacionPct || 8) / 100;
        const reduceMs = enc.duracionMs * pen;
        enc.duracionMs = Math.max(800, enc.duracionMs - reduceMs);
    }
    updateEncuentroUI(enc);
}

function setHoldEncuentro(holding) {
    const enc = encuentrosCtx.activo;
    if (!enc || enc.finalizado) return;
    if (enc.tipo === 'hold') {
        enc.holding = holding;
    }
}

function _resolverEncuentro(exito) {
    const enc = encuentrosCtx.activo;
    if (!enc || enc.finalizado) return;
    enc.finalizado = true;
    enc.exito = exito;

    let mortal = false;
    if (!exito) {
        dañarPaciencia(enc.arquetipo.danoPaciencia);
        const letal = enc.arquetipo.letal;
        if (letal && Math.random() < letal.probabilidad) {
            mortal = true;
            gameState.causaMuerte = letal.mensaje || 'Te ha podido la calle.';
        }
    } else {
        dañarPaciencia(Math.floor(enc.arquetipo.danoPaciencia * 0.25));
    }

    if (typeof stopSpeak === 'function') stopSpeak();
    if (typeof playSfx === 'function') playSfx(exito ? 'encounterSuccess' : 'encounterFail');

    hideEncuentroUI();
    reanudarTrasEncuentro(enc.npc, exito);
    desactivarChaseDeOtros(enc.npc);

    gameState.encuentroActivo = false;
    gameState.paused = false;
    gameState.invulnUntil = performance.now() + 1500;
    gameState.regenBloqueadoHasta = performance.now() + PACIENCIA_REGEN_DELAY_MS;

    const cb = encuentrosCtx.onResolved;
    encuentrosCtx.activo = null;
    encuentrosCtx.onResolved = null;
    if (cb) cb({ exito: exito, paciencia: gameState.paciencia, mortal: mortal });
}

function desactivarChaseDeOtros(except) {
    if (typeof getNPCList !== 'function') return;
    for (const npc of getNPCList()) {
        if (npc === except) continue;
        if (npc.estado === 'chase') {
            npc.estado = 'patrol';
            npc.cooldownDeteccion = 2.0;
        }
    }
}

function getEncuentroActivo() {
    return encuentrosCtx.activo;
}
