<?php
declare(strict_types=1);

require_once __DIR__ . '/csrf.php';

function apiStartSession(): void
{
    if (session_status() !== PHP_SESSION_ACTIVE) {
        if (!defined('SESSION_TIMEOUT_SECONDS')) {
            require_once __DIR__ . '/auth.php';
        }
        ini_set('session.gc_maxlifetime', (string)SESSION_TIMEOUT_SECONDS);
        session_set_cookie_params(SESSION_TIMEOUT_SECONDS, '/', '', false, true);
        session_start();
    }
}

function apiRespond(array $payload, int $statusCode = 200): void
{
    http_response_code($statusCode);
    echo json_encode($payload);
    exit;
}

function requireApiLogin(): void
{
    apiStartSession();
    if (empty($_SESSION['user_id'])) {
        apiRespond(['status' => 'error', 'message' => 'Unauthorized'], 401);
    }
    if (!defined('SESSION_TIMEOUT_SECONDS')) {
        require_once __DIR__ . '/auth.php';
    }
    $lastActivity = $_SESSION['_last_activity'] ?? 0;
    if ($lastActivity > 0 && (time() - $lastActivity) > SESSION_TIMEOUT_SECONDS) {
        $_SESSION = [];
        session_destroy();
        apiRespond(['status' => 'error', 'message' => 'Session expired'], 401);
    }
    $_SESSION['_last_activity'] = time();

    if (empty($_SESSION['role_name']) && !empty($_SESSION['role_id']) && isset($GLOBALS['pdo'])) {
        $stmt = $GLOBALS['pdo']->prepare("SELECT name FROM roles WHERE id = ?");
        $stmt->execute([(int)$_SESSION['role_id']]);
        $name = $stmt->fetchColumn();
        if ($name) {
            $_SESSION['role_name'] = $name;
        }
    }
}

function requireApiPermission(string $permission): void
{
    requireApiLogin();
    if (!function_exists('can') || (!can($permission) && !(function_exists('isAdmin') && isAdmin()))) {
        apiRespond(['status' => 'error', 'message' => 'Unauthorized'], 403);
    }
}

function enforceCsrfForUnsafeRequest(): void
{
    $method = strtoupper((string)($_SERVER['REQUEST_METHOD'] ?? 'GET'));
    if (in_array($method, ['GET', 'HEAD', 'OPTIONS'], true)) {
        return;
    }

    enforceCsrfToken();
}
