<?php
// concurso_nobel/includes/concurso_contexto.php
// Helper común para validar acceso, concurso de trabajo y filtros por admin/docente.
// Soporta ADMIN_GLOBAL sin concurso fijo y conserva compatibilidad con accesos ligados a concurso.

declare(strict_types=1);

if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

date_default_timezone_set('America/Lima');

function cn_h($valor): string
{
    return htmlspecialchars((string)$valor, ENT_QUOTES, 'UTF-8');
}

function cn_redirigir(string $url): void
{
    header('Location: ' . $url);
    exit;
}

function cn_limpiar_sesion(): void
{
    unset(
        $_SESSION['cn_acceso_id'],
        $_SESSION['cn_concurso_id'],
        $_SESSION['cn_grupo_id'],
        $_SESSION['cn_salon_id'],
        $_SESSION['cn_codigo'],
        $_SESSION['cn_responsable'],
        $_SESSION['cn_last_activity'],
        $_SESSION['cn_admin_concurso_trabajo'],
        $_SESSION['cn_admin_global']
    );
}

function cn_tabla_existe(mysqli $conn, string $tabla): bool
{
    $tabla = mysqli_real_escape_string($conn, $tabla);
    $res = @mysqli_query($conn, "SHOW TABLES LIKE '{$tabla}'");
    return $res && mysqli_num_rows($res) > 0;
}

if (!function_exists('cn_auditar')) {
function cn_auditar(
    mysqli $conn,
    ?int $idConcurso,
    ?int $idGrupo,
    ?int $idAcceso,
    ?int $idParticipante,
    string $accion,
    string $detalle
): void {
    if (!cn_tabla_existe($conn, 'concurso_auditoria')) {
        return;
    }

    $ip = $_SERVER['REMOTE_ADDR'] ?? '';
    $ua = $_SERVER['HTTP_USER_AGENT'] ?? '';

    $stmt = mysqli_prepare($conn, "
        INSERT INTO concurso_auditoria
            (id_concurso, id_grupo, id_acceso, id_participante, accion, detalle, ip, user_agent, created_at)
        VALUES
            (?, ?, ?, ?, ?, ?, ?, ?, NOW())
    ");

    if (!$stmt) {
        return;
    }

    mysqli_stmt_bind_param($stmt, 'iiiissss', $idConcurso, $idGrupo, $idAcceso, $idParticipante, $accion, $detalle, $ip, $ua);
    mysqli_stmt_execute($stmt);
    mysqli_stmt_close($stmt);
}
}


function cn_es_admin_global(array $acceso): bool
{
    $tipo = strtoupper(trim((string)($acceso['tipo_acceso'] ?? '')));
    $idConcurso = $acceso['id_concurso'] ?? null;
    $puedeAdministrar = (int)($acceso['puede_administrar'] ?? 0);

    return $tipo === 'ADMIN_GLOBAL' || ($puedeAdministrar === 1 && ($idConcurso === null || (int)$idConcurso === 0));
}

function cn_es_admin(array $acceso): bool
{
    return (int)($acceso['puede_administrar'] ?? 0) === 1 || cn_es_admin_global($acceso);
}

function cn_requiere_concurso(array $acceso): bool
{
    return !cn_es_admin_global($acceso);
}

function cn_validar_acceso(mysqli $conn, string $baseRedirect = 'index.php'): array
{
    $idAccesoSesion = (int)($_SESSION['cn_acceso_id'] ?? 0);
    $idConcursoSesion = (int)($_SESSION['cn_concurso_id'] ?? 0);

    if ($idAccesoSesion <= 0) {
        cn_redirigir($baseRedirect);
    }

    $ultimaActividad = (int)($_SESSION['cn_last_activity'] ?? 0);

    if ($ultimaActividad > 0 && (time() - $ultimaActividad) > 10800) {
        cn_auditar(
            $conn,
            $idConcursoSesion > 0 ? $idConcursoSesion : null,
            null,
            $idAccesoSesion,
            null,
            'SESION_EXPIRADA',
            'Sesión expirada.'
        );
        cn_limpiar_sesion();
        cn_redirigir($baseRedirect);
    }

    $stmt = mysqli_prepare($conn, "
        SELECT
            a.id_acceso,
            a.id_concurso,
            a.id_grupo,
            a.id_salon,
            a.codigo,
            a.nombre_responsable,
            a.tipo_acceso,
            a.puede_registrar_participantes,
            a.puede_registrar_resultados,
            a.puede_ver_resultados,
            a.puede_administrar,
            a.activo,
            a.fecha_expiracion,
            c.nombre AS concurso_nombre,
            c.subtitulo AS concurso_subtitulo,
            c.anio,
            c.estado AS concurso_estado,
            c.fecha_inicio,
            c.fecha_fin,
            g.nombre AS grupo_nombre,
            s.nombre_salon,
            s.codigo_salon
        FROM concurso_accesos a
        LEFT JOIN concursos c ON c.id_concurso = a.id_concurso
        LEFT JOIN concurso_grupos g ON g.id_grupo = a.id_grupo
        LEFT JOIN concurso_salones s ON s.id_salon = a.id_salon
        WHERE a.id_acceso = ?
        LIMIT 1
    ");

    if (!$stmt) {
        http_response_code(500);
        die('No se pudo validar el acceso.');
    }

    mysqli_stmt_bind_param($stmt, 'i', $idAccesoSesion);
    mysqli_stmt_execute($stmt);
    $res = mysqli_stmt_get_result($stmt);
    $acceso = mysqli_fetch_assoc($res);
    mysqli_stmt_close($stmt);

    if (!$acceso) {
        cn_limpiar_sesion();
        cn_redirigir($baseRedirect);
    }

    $hoy = date('Y-m-d');
    $esAdminGlobal = cn_es_admin_global($acceso);
    $idConcursoAcceso = $acceso['id_concurso'] !== null ? (int)$acceso['id_concurso'] : 0;

    if ((int)$acceso['activo'] !== 1) {
        cn_limpiar_sesion();
        cn_redirigir($baseRedirect);
    }

    if (!empty($acceso['fecha_expiracion']) && $hoy > $acceso['fecha_expiracion']) {
        cn_limpiar_sesion();
        cn_redirigir($baseRedirect);
    }

    if ($esAdminGlobal) {
        $_SESSION['cn_last_activity'] = time();
        $_SESSION['cn_admin_global'] = 1;
        $_SESSION['cn_concurso_id'] = 0;
        $_SESSION['cn_grupo_id'] = 0;
        $_SESSION['cn_salon_id'] = 0;

        return $acceso;
    }

    if ($idConcursoAcceso <= 0 || $idConcursoSesion <= 0 || $idConcursoSesion !== $idConcursoAcceso) {
        cn_limpiar_sesion();
        cn_redirigir($baseRedirect);
    }

    if (
        strtoupper((string)$acceso['concurso_estado']) !== 'ACTIVO' ||
        (!empty($acceso['fecha_inicio']) && $hoy < $acceso['fecha_inicio']) ||
        (!empty($acceso['fecha_fin']) && $hoy > $acceso['fecha_fin'])
    ) {
        cn_limpiar_sesion();
        cn_redirigir($baseRedirect);
    }

    $_SESSION['cn_last_activity'] = time();
    $_SESSION['cn_admin_global'] = 0;

    return $acceso;
}


if (!function_exists('cn_obtener_acceso_sesion')) {
function cn_obtener_acceso_sesion(mysqli $conn): ?array
{
    $idAccesoSesion = (int)($_SESSION['cn_acceso_id'] ?? 0);
    $idConcursoSesion = (int)($_SESSION['cn_concurso_id'] ?? 0);

    if ($idAccesoSesion <= 0) {
        return null;
    }

    $ultimaActividad = (int)($_SESSION['cn_last_activity'] ?? 0);

    if ($ultimaActividad > 0 && (time() - $ultimaActividad) > 10800) {
        cn_auditar(
            $conn,
            $idConcursoSesion > 0 ? $idConcursoSesion : null,
            null,
            $idAccesoSesion,
            null,
            'SESION_EXPIRADA',
            'Sesión expirada.'
        );
        cn_limpiar_sesion();
        return null;
    }

    $stmt = mysqli_prepare($conn, "
        SELECT
            a.id_acceso,
            a.id_concurso,
            a.id_grupo,
            a.id_salon,
            a.codigo,
            a.nombre_responsable,
            a.tipo_acceso,
            a.puede_registrar_participantes,
            a.puede_registrar_resultados,
            a.puede_ver_resultados,
            a.puede_administrar,
            a.activo,
            a.fecha_expiracion,
            c.nombre AS concurso_nombre,
            c.subtitulo AS concurso_subtitulo,
            c.anio,
            c.estado AS concurso_estado,
            c.fecha_inicio,
            c.fecha_fin,
            g.nombre AS grupo_nombre,
            s.nombre_salon,
            s.codigo_salon
        FROM concurso_accesos a
        LEFT JOIN concursos c ON c.id_concurso = a.id_concurso
        LEFT JOIN concurso_grupos g ON g.id_grupo = a.id_grupo
        LEFT JOIN concurso_salones s ON s.id_salon = a.id_salon
        WHERE a.id_acceso = ?
        LIMIT 1
    ");

    if (!$stmt) {
        return null;
    }

    mysqli_stmt_bind_param($stmt, 'i', $idAccesoSesion);
    mysqli_stmt_execute($stmt);
    $res = mysqli_stmt_get_result($stmt);
    $acceso = mysqli_fetch_assoc($res);
    mysqli_stmt_close($stmt);

    if (!$acceso) {
        cn_limpiar_sesion();
        return null;
    }

    $hoy = date('Y-m-d');
    $esAdminGlobal = cn_es_admin_global($acceso);
    $idConcursoAcceso = $acceso['id_concurso'] !== null ? (int)$acceso['id_concurso'] : 0;

    if ((int)$acceso['activo'] !== 1) {
        cn_limpiar_sesion();
        return null;
    }

    if (!empty($acceso['fecha_expiracion']) && $hoy > $acceso['fecha_expiracion']) {
        cn_limpiar_sesion();
        return null;
    }

    if ($esAdminGlobal) {
        $_SESSION['cn_last_activity'] = time();
        $_SESSION['cn_admin_global'] = 1;
        $_SESSION['cn_concurso_id'] = 0;
        $_SESSION['cn_grupo_id'] = 0;
        $_SESSION['cn_salon_id'] = 0;

        return $acceso;
    }

    if ($idConcursoAcceso <= 0 || $idConcursoSesion <= 0 || $idConcursoSesion !== $idConcursoAcceso) {
        cn_limpiar_sesion();
        return null;
    }

    if (
        strtoupper((string)$acceso['concurso_estado']) !== 'ACTIVO' ||
        (!empty($acceso['fecha_inicio']) && $hoy < $acceso['fecha_inicio']) ||
        (!empty($acceso['fecha_fin']) && $hoy > $acceso['fecha_fin'])
    ) {
        cn_limpiar_sesion();
        return null;
    }

    $_SESSION['cn_last_activity'] = time();
    $_SESSION['cn_admin_global'] = 0;

    return $acceso;
}
}

function cn_exigir_admin(array $acceso): void
{
    if (!cn_es_admin($acceso)) {
        http_response_code(403);
        die('Acceso denegado. Se requiere permiso administrativo.');
    }
}

function cn_id_grupo_fijo(array $acceso): int
{
    return $acceso['id_grupo'] !== null ? (int)$acceso['id_grupo'] : 0;
}

function cn_id_salon_fijo(array $acceso): int
{
    return $acceso['id_salon'] !== null ? (int)$acceso['id_salon'] : 0;
}

function cn_concursos_activos(mysqli $conn): array
{
    $items = [];

    $res = mysqli_query($conn, "
        SELECT id_concurso, nombre, subtitulo, anio, estado
        FROM concursos
        WHERE estado = 'ACTIVO'
        ORDER BY anio DESC, id_concurso DESC
    ");

    if ($res) {
        while ($row = mysqli_fetch_assoc($res)) {
            $items[] = $row;
        }
    }

    return $items;
}

function cn_concursos_todos(mysqli $conn): array
{
    $items = [];

    $res = mysqli_query($conn, "
        SELECT id_concurso, nombre, subtitulo, anio, estado
        FROM concursos
        ORDER BY anio DESC, id_concurso DESC
    ");

    if ($res) {
        while ($row = mysqli_fetch_assoc($res)) {
            $items[] = $row;
        }
    }

    return $items;
}

function cn_concurso_existe_activo(mysqli $conn, int $idConcurso): bool
{
    $stmt = mysqli_prepare($conn, "
        SELECT id_concurso
        FROM concursos
        WHERE id_concurso = ?
          AND estado = 'ACTIVO'
        LIMIT 1
    ");

    if (!$stmt) {
        return false;
    }

    mysqli_stmt_bind_param($stmt, 'i', $idConcurso);
    mysqli_stmt_execute($stmt);
    $res = mysqli_stmt_get_result($stmt);
    $row = mysqli_fetch_assoc($res);
    mysqli_stmt_close($stmt);

    return (bool)$row;
}

function cn_concurso_existe(mysqli $conn, int $idConcurso): bool
{
    $stmt = mysqli_prepare($conn, "
        SELECT id_concurso
        FROM concursos
        WHERE id_concurso = ?
        LIMIT 1
    ");

    if (!$stmt) {
        return false;
    }

    mysqli_stmt_bind_param($stmt, 'i', $idConcurso);
    mysqli_stmt_execute($stmt);
    $res = mysqli_stmt_get_result($stmt);
    $row = mysqli_fetch_assoc($res);
    mysqli_stmt_close($stmt);

    return (bool)$row;
}

function cn_concurso_trabajo(mysqli $conn, array $acceso): int
{
    if (!cn_es_admin($acceso)) {
        return (int)$acceso['id_concurso'];
    }

    $solicitado = (int)($_POST['id_concurso'] ?? ($_GET['id_concurso'] ?? ($_SESSION['cn_admin_concurso_trabajo'] ?? 0)));

    if ($solicitado > 0 && cn_concurso_existe_activo($conn, $solicitado)) {
        $_SESSION['cn_admin_concurso_trabajo'] = $solicitado;
        return $solicitado;
    }

    if (!cn_es_admin_global($acceso)) {
        $idAccesoConcurso = (int)$acceso['id_concurso'];

        if ($idAccesoConcurso > 0 && cn_concurso_existe_activo($conn, $idAccesoConcurso)) {
            $_SESSION['cn_admin_concurso_trabajo'] = $idAccesoConcurso;
            return $idAccesoConcurso;
        }
    }

    $concursos = cn_concursos_activos($conn);

    if (!empty($concursos)) {
        $id = (int)$concursos[0]['id_concurso'];
        $_SESSION['cn_admin_concurso_trabajo'] = $id;
        return $id;
    }

    unset($_SESSION['cn_admin_concurso_trabajo']);

    return 0;
}

function cn_datos_concurso(mysqli $conn, int $idConcurso): ?array
{
    $stmt = mysqli_prepare($conn, "
        SELECT id_concurso, nombre, subtitulo, anio, estado, fecha_inicio, fecha_fin
        FROM concursos
        WHERE id_concurso = ?
        LIMIT 1
    ");

    if (!$stmt) {
        return null;
    }

    mysqli_stmt_bind_param($stmt, 'i', $idConcurso);
    mysqli_stmt_execute($stmt);
    $res = mysqli_stmt_get_result($stmt);
    $row = mysqli_fetch_assoc($res);
    mysqli_stmt_close($stmt);

    return $row ?: null;
}

function cn_grupos_concurso(mysqli $conn, int $idConcurso, int $idGrupoFijo = 0): array
{
    $items = [];

    if ($idConcurso <= 0) {
        return $items;
    }

    if ($idGrupoFijo > 0) {
        $stmt = mysqli_prepare($conn, "
            SELECT *
            FROM concurso_grupos
            WHERE id_concurso = ?
              AND id_grupo = ?
              AND estado = 1
            ORDER BY orden ASC
        ");

        if ($stmt) {
            mysqli_stmt_bind_param($stmt, 'ii', $idConcurso, $idGrupoFijo);
        }
    } else {
        $stmt = mysqli_prepare($conn, "
            SELECT *
            FROM concurso_grupos
            WHERE id_concurso = ?
              AND estado = 1
            ORDER BY orden ASC
        ");

        if ($stmt) {
            mysqli_stmt_bind_param($stmt, 'i', $idConcurso);
        }
    }

    if (isset($stmt) && $stmt) {
        mysqli_stmt_execute($stmt);
        $res = mysqli_stmt_get_result($stmt);

        while ($row = mysqli_fetch_assoc($res)) {
            $items[] = $row;
        }

        mysqli_stmt_close($stmt);
    }

    return $items;
}

function cn_ambito_texto(array $acceso, ?array $concursoTrabajo = null): string
{
    if (cn_es_admin_global($acceso)) {
        if ($concursoTrabajo) {
            return $concursoTrabajo['nombre'] . ' ' . $concursoTrabajo['subtitulo'] . ' | Administrador global';
        }

        return 'Administrador global | Sin concurso seleccionado';
    }

    if (cn_es_admin($acceso)) {
        if ($concursoTrabajo) {
            return $concursoTrabajo['nombre'] . ' ' . $concursoTrabajo['subtitulo'] . ' | Todos los grados y salones';
        }

        return 'Administrador del concurso';
    }

    $ambito = trim((string)($acceso['concurso_nombre'] ?? '') . ' ' . (string)($acceso['concurso_subtitulo'] ?? ''));

    if (!empty($acceso['grupo_nombre'])) {
        $ambito .= ' | ' . $acceso['grupo_nombre'];
    }

    if (!empty($acceso['nombre_salon'])) {
        $ambito .= ' - ' . $acceso['nombre_salon'];
    }

    return $ambito !== '' ? $ambito : 'Ámbito no definido';
}
