<?php
declare(strict_types=1);

require_once __DIR__ . '/../config/database.php';
require_once __DIR__ . '/helpers.php';
require_once __DIR__ . '/csrf.php';

if (session_status() !== PHP_SESSION_ACTIVE) {
    session_set_cookie_params([
        'lifetime' => 0,
        'path' => '/',
        'httponly' => true,
        'samesite' => 'Strict',
        'secure' => APP_SESSION_SECURE,
    ]);
    session_start();
}
ob_start();

const SESSION_TIMEOUT = 1800;

function current_user(): ?array
{
    return $_SESSION['user'] ?? null;
}

function login_user(array $user): void
{
    session_regenerate_id(true);
    $_SESSION['user'] = [
        'id' => (int)$user['id'],
        'name' => $user['name'],
        'email' => $user['email'],
        'role' => $user['role'],
        'must_change_password' => (int)($user['must_change_password'] ?? 0),
    ];
    $_SESSION['last_activity'] = time();
}

function logout_user(): void
{
    $_SESSION = [];
    if (ini_get('session.use_cookies')) {
        $params = session_get_cookie_params();
        setcookie(session_name(), '', time() - 42000, $params['path'], $params['domain'], $params['secure'], $params['httponly']);
    }
    session_destroy();
}

function require_auth(): void
{
    if (!current_user()) {
        redirect('/login.php');
    }
    if (time() - (int)($_SESSION['last_activity'] ?? 0) > SESSION_TIMEOUT) {
        logout_user();
        session_start();
        flash('error', 'Session expired. Please log in again.');
        redirect('/login.php');
    }
    refresh_current_user();
    if (!current_user()) {
        flash('error', 'Your account has been deactivated. Please contact the administrator.');
        redirect('/login.php');
    }
    $_SESSION['last_activity'] = time();
    $script = str_replace('\\', '/', $_SERVER['SCRIPT_NAME'] ?? '');
    if (!empty($_SESSION['user']['must_change_password']) && !str_ends_with($script, '/profile.php') && !str_ends_with($script, '/logout.php')) {
        flash('error', 'Please change the default password before continuing.');
        redirect('/profile.php');
    }
}

function can(string $ability): bool
{
    $role = trim(strtolower((string)(current_user()['role'] ?? 'visitor')));
    $rules = [
        'admin' => ['*'],
        'engineer' => ['quote:create', 'quote:read', 'quote:update', 'product:view', 'customer:view', 'customer:create'],
        'sales' => ['quote:create', 'quote:read', 'quote:update', 'customer:view', 'customer:create'],
        'visitor' => ['quote:create', 'quote:read_own', 'quote:update_own', 'customer:view', 'customer:create', 'customer:update'],
    ];
    return in_array('*', $rules[$role] ?? [], true) || in_array($ability, $rules[$role] ?? [], true);
}

function require_admin(): void
{
    require_role_access('*');
}

function refresh_current_user(): void
{
    if (empty($_SESSION['user']['id'])) {
        return;
    }
    $stmt = db()->prepare('SELECT id, name, email, role, must_change_password FROM users WHERE id = ? AND status = "active"');
    $stmt->execute([$_SESSION['user']['id']]);
    $user = $stmt->fetch();
    if ($user) {
        $_SESSION['user'] = [
            'id' => (int)$user['id'],
            'name' => $user['name'],
            'email' => $user['email'],
            'role' => $user['role'],
            'must_change_password' => (int)$user['must_change_password'],
        ];
    } else {
        logout_user();
        session_start();
    }
}

function require_role_access(string $ability): void
{
    if (!can($ability)) {
        http_response_code(403);
        exit('Forbidden');
    }
}
