<?php
/**
 * Admin authentication: opaque Bearer token sessions (stored hashed in
 * admin_sessions table). Simpler and just as secure as hand-rolled JWT
 * without needing a Composer package.
 */

require_once __DIR__ . '/../config/database.php';
require_once __DIR__ . '/../config/constants.php';
require_once __DIR__ . '/functions.php';

/**
 * Creates a new admin session and returns the plaintext token to send to the client.
 */
function create_admin_session(int $adminId): string
{
    $pdo = getDbConnection();
    $token = generate_token(32);
    $tokenHash = hash('sha256', $token);
    $expiresAt = date('Y-m-d H:i:s', time() + ADMIN_SESSION_LIFETIME);

    $stmt = $pdo->prepare(
        'INSERT INTO admin_sessions (admin_id, token_hash, ip_address, user_agent, expires_at)
         VALUES (:admin_id, :token_hash, :ip_address, :user_agent, :expires_at)'
    );
    $stmt->execute([
        ':admin_id'   => $adminId,
        ':token_hash' => $tokenHash,
        ':ip_address' => get_client_ip(),
        ':user_agent' => substr($_SERVER['HTTP_USER_AGENT'] ?? '', 0, 250),
        ':expires_at' => $expiresAt,
    ]);

    return $token;
}

/**
 * Validates the Bearer token from the request. Returns the admin row on success,
 * or sends a 401 JSON error and terminates the request on failure.
 */
function require_admin(): array
{
    $token = get_bearer_token();
    if (!$token) {
        send_error('Admin authentication required.', 401);
    }

    $pdo = getDbConnection();
    $tokenHash = hash('sha256', $token);

    $stmt = $pdo->prepare(
        'SELECT s.admin_id, s.expires_at, u.id, u.full_name, u.email, u.role, u.is_blocked
         FROM admin_sessions s
         JOIN users u ON u.id = s.admin_id
         WHERE s.token_hash = :token_hash LIMIT 1'
    );
    $stmt->execute([':token_hash' => $tokenHash]);
    $row = $stmt->fetch();

    if (!$row) {
        send_error('Invalid or expired admin session.', 401);
    }
    if (strtotime($row['expires_at']) < time()) {
        send_error('Admin session expired. Please log in again.', 401);
    }
    if ((int) $row['is_blocked'] === 1) {
        send_error('This admin account has been blocked.', 403);
    }
    if (!in_array($row['role'], ['ADMIN', 'SUPER_ADMIN'], true)) {
        send_error('Admin privileges required.', 403);
    }

    return [
        'id'        => (int) $row['id'],
        'full_name' => $row['full_name'],
        'email'     => $row['email'],
        'role'      => $row['role'],
    ];
}

function require_super_admin(): array
{
    $admin = require_admin();
    if ($admin['role'] !== 'SUPER_ADMIN') {
        send_error('This action requires SUPER_ADMIN privileges.', 403);
    }
    return $admin;
}

function destroy_admin_session(string $token): void
{
    $pdo = getDbConnection();
    $stmt = $pdo->prepare('DELETE FROM admin_sessions WHERE token_hash = :hash');
    $stmt->execute([':hash' => hash('sha256', $token)]);
}
