<?php
/**
 * Zajednički završetak lokalne i Microsoft Entra prijave.
 * Autorizacija se i dalje zasniva isključivo na users/user_roles podacima.
 */

function auth_audit_event(string $event, ?int $userId, string $provider, array $context = []): void
{
    security_log_event($event, array_merge([
        'user_id' => $userId,
        'timestamp' => now_app_datetime_sql(),
        'source_ip' => request_client_ip(),
        'auth_provider' => $provider,
    ], $context));
}

function establish_authenticated_session(int $userId, string $provider): array
{
    if ($userId <= 0 || !in_array($provider, ['local', 'entra'], true)) {
        throw new InvalidArgumentException('Nevalidan zahtev za kreiranje sesije.');
    }

    $stmt = db()->prepare('SELECT id, is_active, must_change_password FROM users WHERE id = ? LIMIT 1');
    $stmt->execute([$userId]);
    $user = $stmt->fetch();
    if (!$user || (int)$user['is_active'] !== 1) {
        throw new RuntimeException('Korisnički nalog nije aktivan.');
    }

    // Menjanje ID-a i CSRF tokena sprečava session fixation i vezivanje nove
    // autentifikovane sesije za anonimnu sesiju korišćenu tokom login toka.
    session_regenerate_id(true);
    unset(
        $_SESSION['csrf_token'],
        $_SESSION['session_expiry_notice_queued'],
        $_SESSION['openid_connect_state'],
        $_SESSION['openid_connect_nonce'],
        $_SESSION['openid_connect_code_verifier'],
        $_SESSION['entra_auth_started_at']
    );
    $_SESSION['user_id'] = (int)$user['id'];
    $_SESSION['auth_provider'] = $provider;
    $_SESSION['session_started_at'] = (int)round(microtime(true) * 1000);
    $_SESSION['last_activity'] = time();

    try {
        $updateLogin = db()->prepare('UPDATE users SET last_login_at = ? WHERE id = ?');
        $updateLogin->execute([now_app_datetime_sql(), (int)$user['id']]);
    } catch (Throwable $e) {
        // last_login_at je pomoćna informacija i ne sme oboriti validnu prijavu.
    }

    return $user;
}
