<?php
/**
 * csrf.php — Sprint 4: Protección CSRF básica
 *
 * Uso en formularios:
 *   <?php echo csrfField(); ?>
 *
 * Validación en controllers:
 *   require_once __DIR__ . '/../../app/helpers/csrf.php';
 *   validarCSRF(); // Muere si el token no es válido
 */

/**
 * Generar o recuperar token CSRF de la sesión actual.
 */
function generarTokenCSRF()
{
    if (session_status() === PHP_SESSION_NONE) {
        session_start();
    }
    if (empty($_SESSION['csrf_token'])) {
        $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
    }
    return $_SESSION['csrf_token'];
}

/**
 * Retorna el campo hidden HTML para incluir en formularios.
 */
function csrfField()
{
    $token = generarTokenCSRF();
    return '<input type="hidden" name="csrf_token" value="' . htmlspecialchars($token) . '">';
}

/**
 * Validar token CSRF del POST contra la sesión.
 * Si falla, redirige al admin con error.
 */
function validarCSRF()
{
    if (session_status() === PHP_SESSION_NONE) {
        session_start();
    }

    $tokenPost = isset($_POST['csrf_token']) ? $_POST['csrf_token'] : '';
    $tokenSession = isset($_SESSION['csrf_token']) ? $_SESSION['csrf_token'] : '';

    if (empty($tokenPost) || empty($tokenSession) || !hash_equals($tokenSession, $tokenPost)) {
        error_log('[CSRF] Token inválido en ' . ($_SERVER['REQUEST_URI'] ?? 'desconocido'));
        header("Location: ../../../administradores/admin.php?error=Token+de+seguridad+inválido");
        exit;
    }

    // Regenerar token después de uso exitoso (previene replay)
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}

// Alias para uso en AJAX
function generarCSRF() {
    if (empty($_SESSION['csrf_token'])) {
        $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
    }
    return $_SESSION['csrf_token'];
}
