// Papeles Para Todos - Evaluación de decisiones contra el boletín activo

// Comprueba si un candidato cumple un matcher de regla
function candidatoMatch(candidato, match) {
    if (!match) return false;

    // Tags: al menos uno de los solicitados
    if (match.tagsAny) {
        const tags = candidato.tags || [];
        if (!match.tagsAny.some(t => tags.includes(t))) return false;
    }

    // Visado exacto
    if (typeof match.visado === 'boolean') {
        if (!!candidato.visado !== match.visado) return false;
    }

    // Tiene algún antecedente
    if (match.algunAntecedente === true) {
        if (!candidato.antecedentes || candidato.antecedentes.length === 0) return false;
    }

    // No tiene antecedentes
    if (match.sinAntecedentesDe === true) {
        if (candidato.antecedentes && candidato.antecedentes.length > 0) return false;
    }

    // Reclamado por alguna agencia
    if (match.reclamado === true) {
        if (!candidato.reclamadoPor) return false;
    }

    return true;
}

// Evalúa una decisión del jugador contra el boletín
// Retorna { scoreDelta, strikeAdded, infringidas[], cumplidas[] }
function evaluarDecision(candidato, decision, boletin) {
    const bonusPeligrosidad = decision === 'APROBAR'
        ? (candidato.peligrosidad || 0) * 10
        : 0;
    const resultado = {
        scoreDelta: 0,
        strikeAdded: false,
        infringidas: [],
        cumplidas: [],
        oficial: {
            bonusCumplido: 0,
            bonusInfringido: 0,
            cumplidas: 0,
            infringidas: 0,
            delta: 0,
            acierto: false,
            fallo: false,
            neutro: true
        }
    };

    if (!boletin || !candidato) return resultado;

    // Score base por peligrosidad aprobada (lo que hace el juego sátira: peligrosidad=recompensa)
    resultado.scoreDelta += bonusPeligrosidad;

    // Evaluar cada regla del boletín
    for (const regla of boletin.reglas) {
        const match = candidatoMatch(candidato, regla.match);
        if (!match) continue;

        if (regla.tipo === 'aprobar_si') {
            if (decision === 'APROBAR') {
                resultado.scoreDelta += regla.bonus;
                resultado.cumplidas.push(regla);
                if (regla.oficial) {
                    resultado.oficial.bonusCumplido += regla.bonus;
                    resultado.oficial.cumplidas++;
                }
            } else {
                // Infringida: había que aprobar y rechazó
                resultado.scoreDelta -= Math.round(regla.bonus * 0.6);
                resultado.infringidas.push(regla);
                if (regla.oficial) {
                    resultado.oficial.bonusInfringido += regla.bonus;
                    resultado.oficial.infringidas++;
                }
            }
        } else if (regla.tipo === 'rechazar_si') {
            if (decision === 'RECHAZAR') {
                resultado.scoreDelta += regla.bonus;
                resultado.cumplidas.push(regla);
                if (regla.oficial) {
                    resultado.oficial.bonusCumplido += regla.bonus;
                    resultado.oficial.cumplidas++;
                }
            } else {
                resultado.scoreDelta -= Math.round(regla.bonus * 0.6);
                resultado.infringidas.push(regla);
                if (regla.oficial) {
                    resultado.oficial.bonusInfringido += regla.bonus;
                    resultado.oficial.infringidas++;
                }
            }
        }
    }

    resultado.oficial.delta = resultado.oficial.bonusCumplido - resultado.oficial.bonusInfringido;
    resultado.oficial.acierto = resultado.oficial.delta > 0;
    resultado.oficial.fallo = resultado.oficial.delta < 0;
    resultado.oficial.neutro = !resultado.oficial.acierto && !resultado.oficial.fallo;
    resultado.strikeAdded = resultado.oficial.fallo;

    // Si aprobar contradice la directriz oficial, la peligrosidad deja de ser un bonus "gratis".
    if (decision === 'APROBAR' && resultado.oficial.fallo && bonusPeligrosidad > 0) {
        resultado.scoreDelta -= bonusPeligrosidad;
    }

    return resultado;
}

// Aplica una decisión: actualiza gameState, suma score, registra stats
// opts: { inconsistenciaMarcada: bool }
function aplicarDecision(candidato, decision, opts = {}) {
    if (!gameState || !candidato) return null;
    const boletin = getBoletinDelDia(gameState.dia);
    const resultado = evaluarDecision(candidato, decision, boletin);

    // Resolver marca de inconsistencia
    const marcada = !!opts.inconsistenciaMarcada;
    const teniaInconsistencia = !!(candidato.expediente && candidato.expediente.inconsistencia);
    resultado.inconsistencia = { marcada, teniaInconsistencia, acertada: false };
    if (marcada && teniaInconsistencia) {
        resultado.scoreDelta += INCONSISTENCIA_BONUS;
        resultado.inconsistencia.acertada = true;
        gameState.stats.inconsistenciasDetectadas++;
    } else if (marcada && !teniaInconsistencia) {
        resultado.scoreDelta += INCONSISTENCIA_PENAL;
        gameState.stats.inconsistenciasFalsas++;
    }

    gameState.scoreDia += resultado.scoreDelta;
    gameState.scoreTotal += resultado.scoreDelta;

    // Alineación ministerial: se mueve según reglas oficiales cumplidas/infringidas
    let deltaAlineacion = 0;
    resultado.cumplidas.forEach(r => { if (r.oficial) deltaAlineacion += 3; });
    resultado.infringidas.forEach(r => { if (r.oficial) deltaAlineacion -= 5; });
    gameState.alineacionMinisterial = Math.max(0, Math.min(100, gameState.alineacionMinisterial + deltaAlineacion));

    if (resultado.strikeAdded) gameState.strikes++;

    // Contadores del día
    if (decision === 'APROBAR') gameState.aprobadosDia++;
    else gameState.rechazadosDia++;

    // Stats temáticas
    const tags = candidato.tags || [];
    if (decision === 'APROBAR') {
        if (tags.includes('yihadista_presunto')) gameState.stats.yihadistasAprobados++;
        if (tags.includes('mafioso_presunto')) gameState.stats.mafiososAprobados++;
        if (tags.includes('humanitario')) gameState.stats.humanitariosAprobados++;
        if (tags.includes('citas_revendidas')) gameState.stats.citasRevendidasAprobadas++;
        if (tags.includes('oligarca')) gameState.stats.oligarcasAprobados++;

        // Origenes únicos aprobados
        if (!gameState.stats.origenesAprobados) gameState.stats.origenesAprobados = [];
        if (candidato.origen && !gameState.stats.origenesAprobados.includes(candidato.origen)) {
            gameState.stats.origenesAprobados.push(candidato.origen);
        }
    } else {
        if (tags.includes('europeo_regular')) gameState.stats.europeosRechazados++;
        if (tags.includes('latino_regular')) gameState.stats.latinosRechazados++;
        if (tags.includes('mena')) gameState.stats.menasRechazados++;
        if (tags.includes('vip')) gameState.stats.vipsRechazados++;
        if (candidato.id === 'fermin_alegre') gameState.stats.espanolRechazado = true;
    }

    gameState.stats.totalDecisiones++;
    if (!gameState.stats.decisionesDiaActual) {
        gameState.stats.decisionesDiaActual = { aciertosOficiales: 0, fallosOficiales: 0, neutras: 0 };
    }
    if (resultado.oficial.acierto) {
        gameState.stats.decisionesCorrectas++;
        gameState.stats.decisionesDiaActual.aciertosOficiales++;
    } else if (resultado.oficial.fallo) {
        gameState.stats.decisionesIncorrectas++;
        gameState.stats.decisionesDiaActual.fallosOficiales++;
    } else {
        gameState.stats.decisionesNeutras++;
        gameState.stats.decisionesDiaActual.neutras++;
    }

    return resultado;
}
