<?php
// CONFIGURACIÓN SEGURA DE SESIONES PARA PRODUCCIÓN

// Regenerar ID de sesión regularmente
function secure_session_start()
{
    if (session_status() === PHP_SESSION_NONE) {
        // La configuración de la sesión DEBE hacerse ANTES de session_start().
        ini_set('session.cookie_httponly', 1);     // Solo HTTP, no JavaScript
        ini_set('session.cookie_secure', 1);       // Solo HTTPS en producción
        ini_set('session.use_only_cookies', 1);    // Solo cookies, no URL
        ini_set('session.cookie_samesite', 'Strict'); // CSRF protection
        ini_set('session.gc_maxlifetime', 1200);   // 20 minutos de inactividad
        ini_set('session.cookie_lifetime', 0);     // La cookie de sesión expira al cerrar el navegador

        session_start();
    }

    if (isset($_SESSION['user_id'])) {
        // Regenerar ID cada 10 minutos
        // Se comprueba si 'last_regeneration' existe ANTES de intentar la regeneración.
        // Esto evita que se regenere el ID justo después del login, lo que invalidaba la sesión.
        if (isset($_SESSION['last_regeneration']) && (time() - $_SESSION['last_regeneration'] > 600)) {
            session_regenerate_id(true);
            $_SESSION['last_regeneration'] = time();
        } elseif (!isset($_SESSION['last_regeneration'])) {
            $_SESSION['last_regeneration'] = time(); // Se establece por primera vez.
        }

        // Verificar timeout de sesión
        if (isset($_SESSION['last_activity']) && (time() - $_SESSION['last_activity'] > 1200)) {
            // Si la sesión ha expirado por inactividad, destrúyela.
            session_unset();
            session_destroy();
            header('Location: ' . url('views/login.php?error=' . urlencode('Sesión expirada por inactividad')));
            exit;
        } else {
            // Si la sesión es válida, o es la primera actividad, actualiza el tiempo.
            $_SESSION['last_activity'] = time();
        }
    }
}

// Función para verificar autenticación
function require_auth($is_ajax = false)
{
    // Esta función asume que secure_session_start() ya ha sido llamada.
    if (!isset($_SESSION['user_id']) || empty($_SESSION['user_id'])) {
        if ($is_ajax) {
            http_response_code(401); // Unauthorized
            echo json_encode(['success' => false, 'error' => 'No autorizado. Debe iniciar sesión.']);
            exit;
        } else {
            // Si ya se ha enviado contenido, no se puede redirigir con header().
            // En su lugar, mostramos un mensaje y un enlace.
            if (headers_sent()) {
                echo '<div class="container mt-5"><div class="alert alert-danger"><strong>Error de Sesión:</strong> Su sesión ha expirado o no es válida. Por favor, <a href="' . url('views/login.php') . '">inicie sesión de nuevo</a>.</div></div>';
            } else {
                // Si no se ha enviado nada, redirigimos como siempre.
                header('Location: ' . url('views/login.php?error=' . urlencode('Acceso no autorizado. Debe iniciar sesión.')));
            }
            exit;
        }
    }
}

// Función para verificar rol
function require_role($required_roles, $is_ajax = false)
{
    require_auth($is_ajax); // Primero, asegurar que el usuario está autenticado, pasando el flag AJAX.

    $user_role = strtolower($_SESSION['rol'] ?? '');
    $allowed_roles = array_map('strtolower', (array)$required_roles);

    if (!in_array($user_role, $allowed_roles)) {
        if ($is_ajax) {
            http_response_code(403); // Forbidden
            echo json_encode(['success' => false, 'error' => 'No tiene permisos para esta función.']);
            exit;
        } else {
            // Si ya se ha enviado contenido, no se puede redirigir con header().
            if (headers_sent()) {
                echo '<div class="container mt-5"><div class="alert alert-danger"><strong>Acceso Denegado:</strong> No tiene los permisos necesarios para acceder a esta página. <a href="' . url('views/menu.php') . '">Volver al menú principal</a>.</div></div>';
            } else {
                header('Location: ' . url('views/menu.php?error=' . urlencode('No tiene permisos para esta función')));
            }
            exit; // Detener la ejecución en cualquier caso.
        }
    }
}

// Función para limpiar sesión de forma segura
function secure_logout()
{
    if (session_status() === PHP_SESSION_ACTIVE) {
        session_unset();
        session_destroy();

        // Eliminar cookie de sesión
        if (ini_get("session.use_cookies")) {
            $params = session_get_cookie_params();
            setcookie(session_name(), '', time() - 3600, $params["path"], $params["domain"], $params["secure"], $params["httponly"]);
        }
    }
}

// Token CSRF
function generate_csrf_token()
{
    if (!isset($_SESSION['csrf_token'])) {
        $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
    }
    return $_SESSION['csrf_token'];
}

function verify_csrf_token($token)
{
    return isset($_SESSION['csrf_token']) &&
        hash_equals($_SESSION['csrf_token'], $token);
}
