<?php
/**
 * @intranet-file common/app_guard.php
 * @intranet-file-version 2026.03.13.1
 * @intranet-file-date 2026-03-13
 * @intranet-file-owner CSIF Intranet
 */
// Algunos scripts ya llaman a session_start() antes de incluir este fichero.
// Si intentamos iniciarla de nuevo, PHP lanza un NOTICE.
if (session_status() === PHP_SESSION_NONE) {
    ini_set('session.gc_maxlifetime', '3600');
    session_start();
}

require_once __DIR__ . '/db.php';
require_once __DIR__ . '/catalogo_db.php';
require_once __DIR__ . '/url.php';
require_once __DIR__ . '/user_preferences.php';
require_once __DIR__ . '/roles.php';

/**
 * Verifica si el usuario actual tiene permisos para acceder a la aplicacion actual.
 * Si no tiene permisos, muestra la pantalla de error y detiene la ejecucion.
 */
function checkAppAccess() {
    // 1. Verificar login.
    if (!isset($_SESSION['username'])) {
        header('Location: ' . login_url('expired=1'));
        exit();
    }

    if (!intranet_enforce_session_timeout()) {
        header('Location: ' . login_url('expired=1'));
        exit();
    }

    // 2. Cargar solo la aplicacion actual desde BD.
    try {
        $pdo = db();
        intranet_preferences_ensure_app_registered($pdo);
        intranet_roles_ensure_app_registered($pdo);
        intranet_load_session_theme_mode($pdo);
        $app = catalogo_app_find_by_script($pdo, $_SERVER['PHP_SELF'] ?? '');
    } catch (Throwable $e) {
        error_log('checkAppAccess catalog load failed for ' . ($_SERVER['PHP_SELF'] ?? 'unknown') . ': ' . $e->getMessage());
        die('Error critico: no se pudo cargar el catalogo de aplicaciones.');
    }

    // 3. Identificar roles sin cargar todo el catalogo ni grupos.
    $found = is_array($app);
    $requiredRoles = $found ? catalogo_roles_from_json($app['roles_json'] ?? '') : [];
    $appName = $found ? (string)($app['name'] ?? 'Aplicacion') : 'Aplicacion Desconocida';

    if (!$found) {
        renderErrorPage('Aplicacion no registrada en el sistema de seguridad.');
        exit();
    }

    // 4. Verificar roles.
    $userRoles = $_SESSION['roles'] ?? [];
    $userRoles = array_map('strtolower', is_array($userRoles) ? $userRoles : []);

    if (!catalogo_roles_allow($userRoles, $requiredRoles)) {
        renderErrorPage('No tienes permisos para acceder a <em>' . htmlspecialchars($appName, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') . '</em>.');
        exit();
    }

    return true;
}

/**
 * Funcion auxiliar para pintar el HTML de error usando los estilos centralizados.
 */
function renderErrorPage($message) {
    http_response_code(403);
    $depth = substr_count($_SERVER['PHP_SELF'], '/') - 1;
    $relPath = str_repeat('../', $depth);
    $cssPath = $relPath . 'styles/css/style.css';
    $themeCssPath = $relPath . 'styles/css/theme-vars.css';
    $dashboardPath = app_url('dashboard.php');

    ?>
    <!DOCTYPE html>
    <html lang="es" <?= intranet_theme_html_attr(); ?>>
    <head>
        <meta charset="UTF-8">
        <title>Acceso Denegado</title>
        <?= intranet_theme_bootstrap_script_tag(); ?>
        <link rel="stylesheet" href="<?php echo $cssPath; ?>">
        <link rel="stylesheet" href="<?php echo $themeCssPath; ?>">
    </head>
    <body>
        <div class="centered-layout">
            <div class="msg-card error">
                <div class="msg-body" style="display:flex; flex-direction:column; align-items:center; text-align:center; gap:12px;">
                <svg xmlns="http://www.w3.org/2000/svg" class="msg-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:72px; height:72px; color: var(--error-text); flex:0 0 auto;">
                    <circle cx="12" cy="12" r="10"></circle>
                    <line x1="12" y1="8" x2="12" y2="12"></line>
                    <line x1="12" y1="16" x2="12.01" y2="16"></line>
                </svg>

                <h2 style="margin:0;">Acceso Restringido</h2>
                <p style="margin:0; color: var(--text-muted);">
                    <?php echo $message; ?>
                </p>
                <p style="margin:0; font-size: 0.85rem; color: var(--text-muted);">
                    Usuario: <strong><?php echo htmlspecialchars($_SESSION['username'] ?? 'Anonimo', ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); ?></strong>
                </p>

                <a href="<?php echo $dashboardPath; ?>" target="_top" class="btn-back">Volver al Inicio</a>
                </div>
            </div>
        </div>
    </body>
    </html>
    <?php
}
?>
