<?php
// concurso_nobel/admin/codigos.php
// Listado administrativo de códigos de acceso NOBEX.
// Compatible con ADMIN_GLOBAL sin concurso fijo.
// Permite ver, buscar, copiar, imprimir y exportar códigos por concurso.

declare(strict_types=1);

session_start();

require_once __DIR__ . '/../includes/db.php';

date_default_timezone_set('America/Lima');

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

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

function cod_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_global'],
        $_SESSION['cn_admin_concurso_trabajo']
    );
}

function cod_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;
}

function cod_auditar(
    mysqli $conn,
    ?int $idConcurso,
    ?int $idGrupo,
    ?int $idAcceso,
    ?int $idParticipante,
    string $accion,
    string $detalle
): void {
    if (!cod_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 cod_post_get_int(string $key, int $default = 0): int
{
    $valor = $_GET[$key] ?? $_POST[$key] ?? $default;

    if (is_numeric($valor)) {
        return (int)$valor;
    }

    return $default;
}

function cod_post_string(string $key, string $default = ''): string
{
    return trim((string)($_POST[$key] ?? $default));
}

function cod_fecha_valida(string $fecha): bool
{
    if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $fecha)) {
        return false;
    }

    [$anio, $mes, $dia] = array_map('intval', explode('-', $fecha));
    return checkdate($mes, $dia, $anio);
}

function cod_obtener_acceso(mysqli $conn, int $idAcceso): ?array
{
    $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.estado AS concurso_estado,
            c.fecha_inicio,
            c.fecha_fin
        FROM concurso_accesos a
        LEFT JOIN concursos c
            ON c.id_concurso = a.id_concurso
        WHERE a.id_acceso = ?
        LIMIT 1
    ");

    if (!$stmt) {
        return null;
    }

    mysqli_stmt_bind_param($stmt, 'i', $idAcceso);
    mysqli_stmt_execute($stmt);
    $res = mysqli_stmt_get_result($stmt);
    $row = $res ? mysqli_fetch_assoc($res) : null;
    mysqli_stmt_close($stmt);

    return $row ?: null;
}

function cod_es_admin_global(array $acceso): bool
{
    if ((int)($acceso['puede_administrar'] ?? 0) !== 1) {
        return false;
    }

    if ((string)($acceso['tipo_acceso'] ?? '') === 'ADMIN_GLOBAL') {
        return true;
    }

    if (isset($_SESSION['cn_admin_global']) && (int)$_SESSION['cn_admin_global'] === 1) {
        return true;
    }

    return $acceso['id_concurso'] === null;
}

function cod_concurso_activo_valido(array $acceso): bool
{
    $hoy = date('Y-m-d');

    if ((int)($acceso['id_concurso'] ?? 0) <= 0) {
        return false;
    }

    if (strtoupper((string)($acceso['concurso_estado'] ?? '')) !== 'ACTIVO') {
        return false;
    }

    if (!empty($acceso['fecha_inicio']) && $hoy < (string)$acceso['fecha_inicio']) {
        return false;
    }

    if (!empty($acceso['fecha_fin']) && $hoy > (string)$acceso['fecha_fin']) {
        return false;
    }

    return true;
}

function cod_obtener_concursos(mysqli $conn, int $idConcursoFijo = 0): array
{
    $concursos = [];

    if ($idConcursoFijo > 0) {
        $stmt = mysqli_prepare($conn, "
            SELECT id_concurso, nombre, subtitulo, anio, estado, fecha_inicio, fecha_fin
            FROM concursos
            WHERE id_concurso = ?
            ORDER BY id_concurso DESC
        ");

        if ($stmt) {
            mysqli_stmt_bind_param($stmt, 'i', $idConcursoFijo);
            mysqli_stmt_execute($stmt);
            $res = mysqli_stmt_get_result($stmt);

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

            mysqli_stmt_close($stmt);
        }

        return $concursos;
    }

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

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

        mysqli_free_result($res);
    }

    return $concursos;
}

function cod_obtener_codigos(mysqli $conn, int $idConcurso): array
{
    $codigos = [];

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

    $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,
            a.created_at,
            g.nombre AS grupo_nombre,
            g.nivel,
            g.grado_nombre,
            g.orden AS grupo_orden,
            s.nombre_salon,
            s.codigo_salon,
            s.capacidad,
            s.orden AS salon_orden,
            (
                SELECT COUNT(*)
                FROM concurso_participantes p
                WHERE p.id_concurso = a.id_concurso
                  AND p.id_salon = a.id_salon
                  AND p.estado = 'ACTIVO'
            ) AS ocupados_salon
        FROM concurso_accesos a
        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_concurso = ?
        ORDER BY
            CASE
                WHEN a.puede_administrar = 1 THEN 1
                WHEN a.tipo_acceso = 'REGISTRADOR' AND a.id_grupo IS NULL AND a.id_salon IS NULL THEN 2
                WHEN a.tipo_acceso = 'RESULTADOS' THEN 3
                WHEN a.tipo_acceso = 'SALON' THEN 4
                WHEN a.id_salon IS NOT NULL THEN 5
                WHEN a.id_grupo IS NOT NULL THEN 6
                ELSE 7
            END,
            g.orden ASC,
            s.orden ASC,
            a.id_acceso ASC
    ");

    if (!$stmt) {
        return $codigos;
    }

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

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

    mysqli_stmt_close($stmt);

    return $codigos;
}

function cod_tipo_etiqueta(array $codigo): string
{
    if ((string)$codigo['tipo_acceso'] === 'ADMIN_GLOBAL') {
        return 'ADMIN GLOBAL';
    }

    if ((int)$codigo['puede_administrar'] === 1) {
        return 'ADMINISTRADOR';
    }

    if ((string)$codigo['tipo_acceso'] === 'RESULTADOS') {
        return 'RESULTADOS';
    }

    if ((string)$codigo['tipo_acceso'] === 'SALON' || !empty($codigo['id_salon'])) {
        return 'SALÓN';
    }

    if (!empty($codigo['id_grupo'])) {
        return 'GRADO';
    }

    return (string)$codigo['tipo_acceso'];
}

function cod_ambito(array $codigo): string
{
    if (!empty($codigo['nombre_salon'])) {
        return (string)$codigo['grupo_nombre'] . ' - ' . (string)$codigo['nombre_salon'];
    }

    if (!empty($codigo['grupo_nombre'])) {
        return (string)$codigo['grupo_nombre'];
    }

    return 'General del concurso';
}

function cod_estado_texto(array $codigo): string
{
    if ((int)$codigo['activo'] !== 1) {
        return 'INACTIVO';
    }

    if (!empty($codigo['fecha_expiracion']) && date('Y-m-d') > (string)$codigo['fecha_expiracion']) {
        return 'EXPIRADO';
    }

    return 'ACTIVO';
}

$idAccesoSesion = (int)($_SESSION['cn_acceso_id'] ?? 0);
$idConcursoSesion = (int)($_SESSION['cn_concurso_id'] ?? 0);

if ($idAccesoSesion <= 0) {
    cod_redirigir('../index.php');
}

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

if ($ultimaActividad > 0 && (time() - $ultimaActividad) > $timeout) {
    cod_auditar($conn, $idConcursoSesion > 0 ? $idConcursoSesion : null, null, $idAccesoSesion, null, 'SESION_EXPIRADA_CODIGOS', 'Sesión expirada en consulta de códigos.');
    cod_limpiar_sesion();
    cod_redirigir('../index.php');
}

$acceso = cod_obtener_acceso($conn, $idAccesoSesion);

if (!$acceso) {
    cod_limpiar_sesion();
    cod_redirigir('../index.php');
}

$hoy = date('Y-m-d');

if ((int)$acceso['activo'] !== 1) {
    cod_limpiar_sesion();
    cod_redirigir('../index.php');
}

if (!empty($acceso['fecha_expiracion']) && $hoy > (string)$acceso['fecha_expiracion']) {
    cod_limpiar_sesion();
    cod_redirigir('../index.php');
}

if ((int)$acceso['puede_administrar'] !== 1) {
    http_response_code(403);
    die('Acceso denegado. Este módulo solo está disponible para administradores.');
}

$esAdminGlobal = cod_es_admin_global($acceso);

if (!$esAdminGlobal && !cod_concurso_activo_valido($acceso)) {
    cod_limpiar_sesion();
    cod_redirigir('../index.php');
}

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

$concursos = $esAdminGlobal
    ? cod_obtener_concursos($conn, 0)
    : cod_obtener_concursos($conn, (int)$acceso['id_concurso']);

$idsValidos = [];

foreach ($concursos as $concurso) {
    $idsValidos[] = (int)$concurso['id_concurso'];
}

$idConcursoSeleccionado = cod_post_get_int('id_concurso', 0);

if ($idConcursoSeleccionado <= 0) {
    $idConcursoSeleccionado = (int)($_SESSION['cn_admin_concurso_trabajo'] ?? 0);
}

if ($idConcursoSeleccionado <= 0 && !$esAdminGlobal) {
    $idConcursoSeleccionado = (int)$acceso['id_concurso'];
}

if ($idConcursoSeleccionado <= 0 && !empty($concursos)) {
    $idConcursoSeleccionado = (int)$concursos[0]['id_concurso'];
}

if (!in_array($idConcursoSeleccionado, $idsValidos, true)) {
    $idConcursoSeleccionado = !empty($concursos) ? (int)$concursos[0]['id_concurso'] : 0;
}

if ($idConcursoSeleccionado > 0) {
    $_SESSION['cn_admin_concurso_trabajo'] = $idConcursoSeleccionado;
}

$concursoSeleccionado = null;

foreach ($concursos as $concurso) {
    if ((int)$concurso['id_concurso'] === $idConcursoSeleccionado) {
        $concursoSeleccionado = $concurso;
        break;
    }
}


if (empty($_SESSION['csrf_admin_codigos'])) {
    $_SESSION['csrf_admin_codigos'] = bin2hex(random_bytes(32));
}

$csrfCodigos = (string)$_SESSION['csrf_admin_codigos'];
$mensajeOk = '';
$mensajeError = '';
$fechaSugerida = date('Y-m-d', strtotime('+1 year'));

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $accion = cod_post_string('accion');
    $csrfPost = cod_post_string('csrf_token');
    $fechaExpiracion = cod_post_string('fecha_expiracion', $fechaSugerida);
    $idConcursoPost = cod_post_get_int('id_concurso', $idConcursoSeleccionado);
    $idAccesoCodigo = cod_post_get_int('id_acceso_codigo', 0);

    if (!hash_equals($csrfCodigos, $csrfPost)) {
        $mensajeError = 'Solicitud no válida. Recarga la página.';
    } elseif ($idConcursoPost <= 0 || !in_array($idConcursoPost, $idsValidos, true)) {
        $mensajeError = 'Selecciona un concurso válido.';
    } elseif (!cod_fecha_valida($fechaExpiracion)) {
        $mensajeError = 'La fecha de expiración no es válida.';
    } else {
        $idConcursoSeleccionado = $idConcursoPost;
        $_SESSION['cn_admin_concurso_trabajo'] = $idConcursoSeleccionado;

        try {
            mysqli_begin_transaction($conn);

            if ($accion === 'extender_concurso') {
                $stmtExtender = mysqli_prepare($conn, "
                    UPDATE concurso_accesos
                    SET activo = 1,
                        fecha_expiracion = ?,
                        updated_at = NOW()
                    WHERE id_concurso = ?
                ");

                if (!$stmtExtender) {
                    throw new RuntimeException('No se pudo preparar la extensión de códigos.');
                }

                mysqli_stmt_bind_param($stmtExtender, 'si', $fechaExpiracion, $idConcursoSeleccionado);

                if (!mysqli_stmt_execute($stmtExtender)) {
                    $error = mysqli_stmt_error($stmtExtender);
                    mysqli_stmt_close($stmtExtender);
                    throw new RuntimeException('No se pudo extender los códigos. ' . $error);
                }

                $totalActualizados = mysqli_stmt_affected_rows($stmtExtender);
                mysqli_stmt_close($stmtExtender);

                $stmtConcurso = mysqli_prepare($conn, "
                    UPDATE concursos
                    SET estado = 'ACTIVO',
                        fecha_inicio = CASE
                            WHEN fecha_inicio IS NULL OR fecha_inicio > CURDATE() THEN CURDATE()
                            ELSE fecha_inicio
                        END,
                        fecha_fin = ?,
                        updated_at = NOW()
                    WHERE id_concurso = ?
                    LIMIT 1
                ");

                if ($stmtConcurso) {
                    mysqli_stmt_bind_param($stmtConcurso, 'si', $fechaExpiracion, $idConcursoSeleccionado);
                    mysqli_stmt_execute($stmtConcurso);
                    mysqli_stmt_close($stmtConcurso);
                }

                cod_auditar(
                    $conn,
                    $idConcursoSeleccionado,
                    null,
                    $idAccesoSesion,
                    null,
                    'CODIGOS_EXTENDIDOS',
                    'Se extendieron códigos del concurso hasta ' . $fechaExpiracion . '. Filas afectadas: ' . $totalActualizados
                );

                $mensajeOk = 'Códigos activados y extendidos hasta ' . $fechaExpiracion . '.';
            } elseif ($accion === 'extender_codigo') {
                if ($idAccesoCodigo <= 0) {
                    throw new RuntimeException('Código de acceso no válido.');
                }

                $stmtExtenderUno = mysqli_prepare($conn, "
                    UPDATE concurso_accesos
                    SET activo = 1,
                        fecha_expiracion = ?,
                        updated_at = NOW()
                    WHERE id_acceso = ?
                      AND id_concurso = ?
                    LIMIT 1
                ");

                if (!$stmtExtenderUno) {
                    throw new RuntimeException('No se pudo preparar la extensión del código.');
                }

                mysqli_stmt_bind_param($stmtExtenderUno, 'sii', $fechaExpiracion, $idAccesoCodigo, $idConcursoSeleccionado);

                if (!mysqli_stmt_execute($stmtExtenderUno)) {
                    $error = mysqli_stmt_error($stmtExtenderUno);
                    mysqli_stmt_close($stmtExtenderUno);
                    throw new RuntimeException('No se pudo extender el código. ' . $error);
                }

                $afectados = mysqli_stmt_affected_rows($stmtExtenderUno);
                mysqli_stmt_close($stmtExtenderUno);

                if ($afectados <= 0) {
                    throw new RuntimeException('No se encontró el código seleccionado para este concurso.');
                }

                cod_auditar(
                    $conn,
                    $idConcursoSeleccionado,
                    null,
                    $idAccesoSesion,
                    null,
                    'CODIGO_EXTENDIDO',
                    'Se extendió el código de acceso ID ' . $idAccesoCodigo . ' hasta ' . $fechaExpiracion
                );

                $mensajeOk = 'Código activado y extendido hasta ' . $fechaExpiracion . '.';
            } else {
                throw new RuntimeException('Acción no reconocida.');
            }

            mysqli_commit($conn);

            $_SESSION['csrf_admin_codigos'] = bin2hex(random_bytes(32));
            $csrfCodigos = (string)$_SESSION['csrf_admin_codigos'];
        } catch (Throwable $e) {
            mysqli_rollback($conn);
            $mensajeError = $e->getMessage();
        }
    }

    $concursoSeleccionado = null;

    foreach ($concursos as $concurso) {
        if ((int)$concurso['id_concurso'] === $idConcursoSeleccionado) {
            $concursoSeleccionado = $concurso;
            break;
        }
    }
}

$codigos = $idConcursoSeleccionado > 0 ? cod_obtener_codigos($conn, $idConcursoSeleccionado) : [];


if (isset($_GET['export']) && $_GET['export'] === 'csv' && $idConcursoSeleccionado > 0 && $concursoSeleccionado) {
    $nombreArchivo = 'codigos_nobex_' . $idConcursoSeleccionado . '_' . date('Ymd_His') . '.csv';

    header('Content-Type: text/csv; charset=utf-8');
    header('Content-Disposition: attachment; filename="' . $nombreArchivo . '"');

    $out = fopen('php://output', 'w');
    fprintf($out, chr(0xEF) . chr(0xBB) . chr(0xBF));

    fputcsv($out, [
        'ID',
        'CODIGO',
        'TIPO',
        'RESPONSABLE',
        'AMBITO',
        'GRADO',
        'SALON',
        'CODIGO_SALON',
        'REGISTRA_PARTICIPANTES',
        'REGISTRA_RESULTADOS',
        'VER_RESULTADOS',
        'ADMINISTRA',
        'ESTADO',
        'FECHA_EXPIRACION',
        'CREADO'
    ], ';');

    foreach ($codigos as $codigo) {
        fputcsv($out, [
            $codigo['id_acceso'],
            $codigo['codigo'],
            cod_tipo_etiqueta($codigo),
            $codigo['nombre_responsable'],
            cod_ambito($codigo),
            $codigo['grupo_nombre'],
            $codigo['nombre_salon'],
            $codigo['codigo_salon'],
            (int)$codigo['puede_registrar_participantes'] === 1 ? 'SI' : 'NO',
            (int)$codigo['puede_registrar_resultados'] === 1 ? 'SI' : 'NO',
            (int)$codigo['puede_ver_resultados'] === 1 ? 'SI' : 'NO',
            (int)$codigo['puede_administrar'] === 1 ? 'SI' : 'NO',
            cod_estado_texto($codigo),
            $codigo['fecha_expiracion'],
            $codigo['created_at']
        ], ';');
    }

    fclose($out);
    exit;
}

$totalCodigos = count($codigos);
$totalAdmin = 0;
$totalSalon = 0;
$totalActivos = 0;
$totalInactivos = 0;

foreach ($codigos as $codigo) {
    if ((int)$codigo['puede_administrar'] === 1) {
        $totalAdmin++;
    }

    if ((string)$codigo['tipo_acceso'] === 'SALON' || !empty($codigo['id_salon'])) {
        $totalSalon++;
    }

    if (cod_estado_texto($codigo) === 'ACTIVO') {
        $totalActivos++;
    } else {
        $totalInactivos++;
    }
}

if ($idConcursoSeleccionado > 0) {
    cod_auditar(
        $conn,
        $idConcursoSeleccionado,
        null,
        $idAccesoSesion,
        null,
        'CODIGOS_CONSULTADOS',
        'Administrador consultó códigos de acceso del concurso ID ' . $idConcursoSeleccionado
    );
}

$tituloConcurso = $concursoSeleccionado
    ? trim((string)$concursoSeleccionado['nombre'] . ' ' . (string)$concursoSeleccionado['subtitulo'])
    : 'Sin concurso seleccionado';

$rolAcceso = $esAdminGlobal ? 'Administrador global' : 'Administrador del concurso';
$textoAdministrador = (string)$acceso['nombre_responsable'];
$codigoAdministrador = (string)$acceso['codigo'];
$idConcursoMenu = $idConcursoSeleccionado;
?>
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <title>Códigos de acceso | NOBEX</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css">
    <link rel="stylesheet" href="../assets/css/menu_concurso.css?v=4">
    <style>
        :root{
            --red:#d90000;
            --red-dark:#9f1111;
            --gold:#ffcc00;
            --ink:#0f172a;
            --muted:#64748b;
            --line:#e2e8f0;
            --soft:#f3f6fb;
            --card:#ffffff;
            --blue:#1d4ed8;
            --green:#166534;
            --green-bg:#dcfce7;
            --warn:#92400e;
            --warn-bg:#fef3c7;
        }
        *{box-sizing:border-box}
        body{margin:0;font-family:Arial,Helvetica,sans-serif;background:linear-gradient(180deg,#fff 0%,#f3f6fb 40%,#eef2f7 100%);color:var(--ink)}
        .topbar{background:linear-gradient(135deg,var(--red),var(--red-dark));color:#fff;border-bottom:8px solid var(--gold);padding:24px 20px}
        .topbar-inner{max-width:1300px;margin:0 auto;display:flex;justify-content:space-between;gap:18px;align-items:center}
        .topbar h1{margin:0;font-size:32px;font-weight:900;letter-spacing:-.5px}
        .topbar p{margin:6px 0 0;color:var(--gold);font-weight:900;line-height:1.45}
        .topbar-actions{display:flex;gap:10px;flex-wrap:wrap;justify-content:flex-end}
        .btn-top{color:#fff;text-decoration:none;border:1px solid rgba(255,255,255,.55);border-radius:14px;padding:11px 14px;font-weight:900;white-space:nowrap;background:rgba(255,255,255,.08)}
        .btn-top:hover{background:rgba(255,255,255,.15)}
        .container{max-width:1300px;margin:24px auto;padding:0 18px 44px}
        .hero-grid{display:grid;grid-template-columns:1.2fr .8fr;gap:16px;margin-bottom:16px}
        .card{background:var(--card);border:1px solid var(--line);border-radius:20px;box-shadow:0 16px 36px rgba(15,23,42,.08)}
        .card-pad{padding:22px}
        .title{margin:0 0 8px;font-size:23px;font-weight:900}
        .muted{color:var(--muted);line-height:1.55}
        .filters{display:grid;grid-template-columns:1fr 180px 180px;gap:10px;align-items:end}
        label{display:block;font-size:13px;font-weight:900;color:#334155;margin:0 0 7px}
        select,input{width:100%;border:1px solid #cbd5e1;border-radius:14px;padding:12px 13px;font-size:15px;outline:none;background:#fff}
        select:focus,input:focus{border-color:var(--blue);box-shadow:0 0 0 4px rgba(29,78,216,.12)}
        .btn{border:0;border-radius:14px;background:var(--blue);color:#fff;padding:12px 15px;font-weight:900;text-decoration:none;display:inline-flex;align-items:center;justify-content:center;gap:8px;cursor:pointer}
        .btn:hover{background:#1e40af}
        .btn.secondary{background:#111827}
        .btn.gray{background:#475569}
        .btn.gold{background:#b45309}
        .toolbar{display:flex;gap:10px;flex-wrap:wrap;margin-top:14px}.extend-box{margin-top:14px;padding:14px;border:1px solid var(--line);border-radius:16px;background:#f8fafc;display:grid;grid-template-columns:1fr auto;gap:10px;align-items:end}.inline-form{display:inline}.btn-mini{border:0;border-radius:10px;background:#1d4ed8;color:#fff;padding:7px 9px;font-weight:900;cursor:pointer;font-size:12px}.btn-mini:hover{background:#1e40af}
        .stats{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}
        .stat{padding:16px;border-radius:16px;background:#f8fafc;border:1px solid var(--line)}
        .stat .num{font-size:30px;font-weight:900;color:var(--blue);line-height:1}
        .stat .lab{font-size:12px;text-transform:uppercase;font-weight:900;color:var(--muted);margin-top:8px}
        .notice{background:#eff6ff;border:1px solid #bfdbfe;color:#1e40af;border-radius:16px;padding:14px 16px;font-weight:800;line-height:1.5}
        .notice.warn{background:#fef3c7;border-color:#fde68a;color:#92400e}
        .search-row{display:grid;grid-template-columns:1fr auto auto;gap:10px;margin-bottom:14px}
        .table-wrap{overflow-x:auto}
        table{width:100%;border-collapse:collapse;font-size:14px;min-width:1240px}
        th,td{padding:12px;border-bottom:1px solid var(--line);text-align:left;vertical-align:top}
        th{background:#f8fafc;color:#334155;font-size:12px;text-transform:uppercase;font-weight:900;white-space:nowrap}
        .code{font-family:"Courier New",monospace;color:#0f172a;font-weight:900;background:#f8fafc;border:1px solid #e2e8f0;border-radius:12px;padding:8px 10px;display:inline-flex;gap:8px;align-items:center;word-break:break-all}
        .copy{border:0;background:#dbeafe;color:#1e40af;border-radius:9px;font-weight:900;padding:6px 8px;cursor:pointer}
        .copy:hover{background:#bfdbfe}
        .badge{display:inline-block;border-radius:999px;padding:5px 9px;font-size:11px;font-weight:900;border:1px solid #bfdbfe;background:#eff6ff;color:#1e40af;white-space:nowrap}
        .badge.admin{background:var(--warn-bg);border-color:#fde68a;color:var(--warn)}
        .badge.ok{background:var(--green-bg);border-color:#bbf7d0;color:var(--green)}
        .badge.bad{background:#fee2e2;border-color:#fecaca;color:#991b1b}
        .small{font-size:12px;color:var(--muted);line-height:1.45}
        .perm{display:flex;flex-wrap:wrap;gap:5px}
        .empty{padding:28px;border:1px dashed #cbd5e1;border-radius:16px;background:#f8fafc;color:var(--muted);font-weight:800;text-align:center}
        .toast{position:fixed;right:18px;bottom:18px;background:#111827;color:#fff;border-radius:14px;padding:12px 14px;font-weight:900;box-shadow:0 16px 35px rgba(15,23,42,.25);display:none;z-index:99}
        @media(max-width:980px){.extend-box{grid-template-columns:1fr}.hero-grid{grid-template-columns:1fr}.filters{grid-template-columns:1fr}.stats{grid-template-columns:repeat(2,1fr)}.topbar-inner{flex-direction:column;align-items:flex-start}.topbar-actions{justify-content:flex-start}.search-row{grid-template-columns:1fr}}
        @media(max-width:620px){.stats{grid-template-columns:1fr}.topbar h1{font-size:24px}.container{padding:0 12px 32px}.card-pad{padding:16px}}
        @media print{.topbar-actions,.filters,.toolbar,.search-row,.copy,.btn{display:none!important}body{background:#fff}.card{box-shadow:none}.container{max-width:none}.topbar{background:#111!important;color:#fff!important}}
    </style>
</head>
<body class="cn-con-sidebar">

<?php include __DIR__ . '/../includes/sidebar_concurso.php'; ?>

<header class="topbar">
    <div class="topbar-inner">
        <div>
            <h1>Códigos de acceso</h1>
            <p>
                <?php echo cod_h($tituloConcurso); ?>
                | <?php echo cod_h($rolAcceso); ?>:
                <?php echo cod_h($textoAdministrador); ?>
                | Código: <?php echo cod_h($codigoAdministrador); ?>
            </p>
        </div>
        <div class="topbar-actions">
            <a class="btn-top" href="../panel.php">Volver al panel</a>
            <a class="btn-top" href="concursos.php">Administrar concursos</a>
            <a class="btn-top" href="../salir.php">Salir</a>
        </div>
    </div>
</header>

<main class="container">
    <?php if ($mensajeOk !== ''): ?>
        <p class="notice" style="margin-bottom:16px;"><?php echo cod_h($mensajeOk); ?></p>
    <?php endif; ?>

    <?php if ($mensajeError !== ''): ?>
        <p class="notice warn" style="margin-bottom:16px;"><?php echo cod_h($mensajeError); ?></p>
    <?php endif; ?>

    <section class="hero-grid">
        <div class="card card-pad">
            <h2 class="title">Consulta centralizada de códigos</h2>

            <?php if (empty($concursos)): ?>
                <p class="notice warn">
                    Todavía no hay concursos creados. Primero crea un concurso desde “Administrar concursos”.
                    Cuando exista un concurso, aquí podrás ver sus códigos de administrador, resultados y salones.
                </p>
                <div class="toolbar">
                    <a class="btn" href="concursos.php">Crear concurso</a>
                    <a class="btn gray" href="../panel.php">Volver al panel</a>
                </div>
            <?php else: ?>
                <p class="muted">
                    Este módulo permite recuperar los códigos creados para cada concurso:
                    administrador del concurso, registrador general, resultados y códigos de salón.
                </p>

                <form method="get" action="" class="filters">
                    <div>
                        <label>Concurso</label>
                        <select name="id_concurso">
                            <?php foreach ($concursos as $concurso): ?>
                                <option value="<?php echo cod_h($concurso['id_concurso']); ?>" <?php echo (int)$concurso['id_concurso'] === $idConcursoSeleccionado ? 'selected' : ''; ?>>
                                    <?php echo cod_h($concurso['nombre'] . ' ' . $concurso['subtitulo'] . ' | ' . $concurso['estado']); ?>
                                </option>
                            <?php endforeach; ?>
                        </select>
                    </div>
                    <button class="btn" type="submit">Ver códigos</button>
                    <?php if ($idConcursoSeleccionado > 0): ?>
                        <a class="btn gray" href="?id_concurso=<?php echo cod_h($idConcursoSeleccionado); ?>&export=csv">Exportar CSV</a>
                    <?php else: ?>
                        <span class="btn gray" style="opacity:.55;cursor:not-allowed;">Exportar CSV</span>
                    <?php endif; ?>
                </form>

                <div class="toolbar">
                    <button class="btn secondary" type="button" id="btnCopiarTodos">Copiar todos</button>
                    <button class="btn gold" type="button" onclick="window.print()">Imprimir</button>
                    <?php if ($idConcursoSeleccionado > 0): ?>
                        <a class="btn" href="salones.php?id_concurso=<?php echo cod_h($idConcursoSeleccionado); ?>">Control de salones</a>
                    <?php else: ?>
                        <a class="btn" href="salones.php">Control de salones</a>
                    <?php endif; ?>
                </div>

                <?php if ($idConcursoSeleccionado > 0): ?>
                    <form method="post" action="" class="extend-box">
                        <input type="hidden" name="csrf_token" value="<?php echo cod_h($csrfCodigos); ?>">
                        <input type="hidden" name="accion" value="extender_concurso">
                        <input type="hidden" name="id_concurso" value="<?php echo cod_h($idConcursoSeleccionado); ?>">
                        <div>
                            <label>Extender vigencia de códigos hasta</label>
                            <input type="date" name="fecha_expiracion" value="<?php echo cod_h($fechaSugerida); ?>" required>
                        </div>
                        <button class="btn" type="submit">Activar y extender todos</button>
                        <p class="small" style="margin:8px 0 0;">
                            Esta acción activa todos los códigos del concurso seleccionado y actualiza también la fecha fin del concurso.
                        </p>
                    </form>
                <?php endif; ?>
            <?php endif; ?>
        </div>

        <div class="card card-pad">
            <div class="stats">
                <div class="stat">
                    <div class="num"><?php echo cod_h($totalCodigos); ?></div>
                    <div class="lab">Total códigos</div>
                </div>
                <div class="stat">
                    <div class="num"><?php echo cod_h($totalSalon); ?></div>
                    <div class="lab">Códigos salón</div>
                </div>
                <div class="stat">
                    <div class="num"><?php echo cod_h($totalAdmin); ?></div>
                    <div class="lab">Admin concurso</div>
                </div>
                <div class="stat">
                    <div class="num"><?php echo cod_h($totalActivos); ?></div>
                    <div class="lab">Activos</div>
                </div>
            </div>

            <?php if (empty($concursos)): ?>
                <p class="notice warn" style="margin:14px 0 0;">
                    No hay datos de códigos porque todavía no existe ningún concurso operativo.
                </p>
            <?php elseif ($totalInactivos > 0): ?>
                <p class="notice warn" style="margin:14px 0 0;">
                    Hay <?php echo cod_h($totalInactivos); ?> código(s) inactivo(s) o expirado(s). Revisa antes de compartirlos.
                </p>
            <?php else: ?>
                <p class="notice" style="margin:14px 0 0;">
                    Todos los códigos listados están activos según la fecha actual.
                </p>
            <?php endif; ?>
        </div>
    </section>

    <section class="card card-pad">
        <?php if (!empty($concursos)): ?>
            <div class="search-row">
                <input type="search" id="buscador" placeholder="Buscar por código, responsable, grado, salón o tipo...">
                <button class="btn gray" type="button" id="btnLimpiar">Limpiar</button>
                <button class="btn secondary" type="button" id="btnSoloSalon">Solo salones</button>
            </div>
        <?php endif; ?>

        <?php if (!empty($codigos)): ?>
            <div class="table-wrap">
                <table id="tablaCodigos">
                    <thead>
                        <tr>
                            <th>ID</th>
                            <th>Código</th>
                            <th>Tipo</th>
                            <th>Responsable</th>
                            <th>Ámbito</th>
                            <th>Permisos</th>
                            <th>Cupo salón</th>
                            <th>Estado</th>
                            <th>Expira</th>
                            <th>Creado</th>
                            <th>Acción</th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php foreach ($codigos as $codigo): ?>
                            <?php
                                $tipoEtiqueta = cod_tipo_etiqueta($codigo);
                                $estadoTexto = cod_estado_texto($codigo);
                                $esSalon = (string)$codigo['tipo_acceso'] === 'SALON' || !empty($codigo['id_salon']);
                                $capacidadOriginal = !empty($codigo['capacidad']) ? (int)$codigo['capacidad'] : 30;
                                $capacidad = min(30, max(1, $capacidadOriginal));
                                $ocupados = (int)($codigo['ocupados_salon'] ?? 0);
                                $libres = max(0, $capacidad - $ocupados);
                            ?>
                            <tr data-row data-salon="<?php echo $esSalon ? '1' : '0'; ?>">
                                <td><?php echo cod_h($codigo['id_acceso']); ?></td>
                                <td>
                                    <span class="code">
                                        <span class="code-text"><?php echo cod_h($codigo['codigo']); ?></span>
                                        <button class="copy" type="button" data-copy="<?php echo cod_h($codigo['codigo']); ?>">Copiar</button>
                                    </span>
                                </td>
                                <td>
                                    <span class="badge <?php echo (int)$codigo['puede_administrar'] === 1 ? 'admin' : ''; ?>">
                                        <?php echo cod_h($tipoEtiqueta); ?>
                                    </span>
                                </td>
                                <td>
                                    <strong><?php echo cod_h($codigo['nombre_responsable']); ?></strong>
                                    <div class="small">Tipo original: <?php echo cod_h($codigo['tipo_acceso']); ?></div>
                                </td>
                                <td>
                                    <strong><?php echo cod_h(cod_ambito($codigo)); ?></strong>
                                    <?php if (!empty($codigo['codigo_salon'])): ?>
                                        <div class="small">Código salón: <?php echo cod_h($codigo['codigo_salon']); ?></div>
                                    <?php endif; ?>
                                </td>
                                <td>
                                    <div class="perm">
                                        <?php if ((int)$codigo['puede_registrar_participantes'] === 1): ?>
                                            <span class="badge ok">Participantes</span>
                                        <?php endif; ?>

                                        <?php if ((int)$codigo['puede_registrar_resultados'] === 1): ?>
                                            <span class="badge ok">Calificaciones</span>
                                        <?php endif; ?>

                                        <?php if ((int)$codigo['puede_ver_resultados'] === 1): ?>
                                            <span class="badge ok">Resultados</span>
                                        <?php endif; ?>

                                        <?php if ((int)$codigo['puede_administrar'] === 1): ?>
                                            <span class="badge admin">Administra</span>
                                        <?php endif; ?>
                                    </div>
                                </td>
                                <td>
                                    <?php if ($esSalon): ?>
                                        <strong><?php echo cod_h($ocupados); ?> / <?php echo cod_h($capacidad); ?></strong>
                                        <div class="small">Libres: <?php echo cod_h($libres); ?></div>
                                    <?php else: ?>
                                        <span class="small">No aplica</span>
                                    <?php endif; ?>
                                </td>
                                <td>
                                    <span class="badge <?php echo $estadoTexto === 'ACTIVO' ? 'ok' : 'bad'; ?>">
                                        <?php echo cod_h($estadoTexto); ?>
                                    </span>
                                </td>
                                <td><?php echo cod_h($codigo['fecha_expiracion'] ?: 'Sin fecha'); ?></td>
                                <td><?php echo cod_h($codigo['created_at'] ?: ''); ?></td>
                                <td>
                                    <form method="post" action="" class="inline-form">
                                        <input type="hidden" name="csrf_token" value="<?php echo cod_h($csrfCodigos); ?>">
                                        <input type="hidden" name="accion" value="extender_codigo">
                                        <input type="hidden" name="id_concurso" value="<?php echo cod_h($idConcursoSeleccionado); ?>">
                                        <input type="hidden" name="id_acceso_codigo" value="<?php echo cod_h($codigo['id_acceso']); ?>">
                                        <input type="hidden" name="fecha_expiracion" value="<?php echo cod_h($fechaSugerida); ?>">
                                        <button class="btn-mini" type="submit">Extender 1 año</button>
                                    </form>
                                </td>
                            </tr>
                        <?php endforeach; ?>
                    </tbody>
                </table>
            </div>
        <?php elseif (empty($concursos)): ?>
            <div class="empty">
                No hay concursos creados todavía. Cuando crees un concurso, sus códigos aparecerán aquí.
            </div>
        <?php else: ?>
            <div class="empty">
                No hay códigos registrados para el concurso seleccionado.
            </div>
        <?php endif; ?>
    </section>
</main>

<div class="toast" id="toast">Código copiado</div>

<script>
document.addEventListener('DOMContentLoaded', function () {
    const buscador = document.getElementById('buscador');
    const filas = Array.from(document.querySelectorAll('[data-row]'));
    const toast = document.getElementById('toast');
    const btnLimpiar = document.getElementById('btnLimpiar');
    const btnSoloSalon = document.getElementById('btnSoloSalon');
    const btnCopiarTodos = document.getElementById('btnCopiarTodos');
    let soloSalon = false;

    function mostrarToast(texto) {
        if (!toast) return;
        toast.textContent = texto || 'Copiado';
        toast.style.display = 'block';
        window.setTimeout(function () {
            toast.style.display = 'none';
        }, 1600);
    }

    function filtrar() {
        const q = buscador ? buscador.value.trim().toLowerCase() : '';

        filas.forEach(function (fila) {
            const texto = fila.textContent.toLowerCase();
            const esSalon = fila.getAttribute('data-salon') === '1';
            const coincideTexto = q === '' || texto.indexOf(q) !== -1;
            const coincideSalon = !soloSalon || esSalon;

            fila.style.display = coincideTexto && coincideSalon ? '' : 'none';
        });
    }

    document.querySelectorAll('[data-copy]').forEach(function (btn) {
        btn.addEventListener('click', async function () {
            const codigo = btn.getAttribute('data-copy') || '';

            try {
                await navigator.clipboard.writeText(codigo);
                mostrarToast('Código copiado: ' + codigo);
            } catch (e) {
                const area = document.createElement('textarea');
                area.value = codigo;
                document.body.appendChild(area);
                area.select();
                document.execCommand('copy');
                document.body.removeChild(area);
                mostrarToast('Código copiado: ' + codigo);
            }
        });
    });

    if (buscador) {
        buscador.addEventListener('input', filtrar);
    }

    if (btnLimpiar) {
        btnLimpiar.addEventListener('click', function () {
            if (buscador) {
                buscador.value = '';
            }

            soloSalon = false;

            if (btnSoloSalon) {
                btnSoloSalon.textContent = 'Solo salones';
            }

            filtrar();
        });
    }

    if (btnSoloSalon) {
        btnSoloSalon.addEventListener('click', function () {
            soloSalon = !soloSalon;
            btnSoloSalon.textContent = soloSalon ? 'Ver todos' : 'Solo salones';
            filtrar();
        });
    }

    if (btnCopiarTodos) {
        btnCopiarTodos.addEventListener('click', async function () {
            const lineas = filas
                .filter(function (fila) {
                    return fila.style.display !== 'none';
                })
                .map(function (fila) {
                    const codigo = fila.querySelector('.code-text');
                    const celdas = fila.querySelectorAll('td');
                    const tipo = celdas[2] ? celdas[2].textContent.trim().replace(/\s+/g, ' ') : '';
                    const responsable = celdas[3] ? celdas[3].textContent.trim().replace(/\s+/g, ' ') : '';
                    const ambito = celdas[4] ? celdas[4].textContent.trim().replace(/\s+/g, ' ') : '';
                    return (codigo ? codigo.textContent.trim() : '') + ' | ' + tipo + ' | ' + responsable + ' | ' + ambito;
                })
                .filter(Boolean);

            const texto = lineas.join('\n');

            try {
                await navigator.clipboard.writeText(texto);
                mostrarToast('Listado copiado');
            } catch (e) {
                const area = document.createElement('textarea');
                area.value = texto;
                document.body.appendChild(area);
                area.select();
                document.execCommand('copy');
                document.body.removeChild(area);
                mostrarToast('Listado copiado');
            }
        });
    }
});
</script>

</body>
</html>
