<?php
require_once __DIR__ . '/db.php';
require_once __DIR__ . '/../config.php';

/**
 * Verifies a username/password against admin_users and, on success, creates a
 * new row in admin_sessions with a random 64-char token. That token is what
 * the browser sends back as "Authorization: Bearer <token>" on every
 * subsequent write request — this mirrors the Bearer-token contract the
 * front-end (assets/blog-client.js) already speaks, so no JS changes were
 * needed to support this real backend.
 */
function attempt_login(string $username, string $password): ?string {
    $stmt = db()->prepare('SELECT id, password_hash FROM admin_users WHERE username = ? LIMIT 1');
    $stmt->execute([$username]);
    $user = $stmt->fetch();
    if (!$user || !password_verify($password, $user['password_hash'])) {
        return null;
    }
    $token = bin2hex(random_bytes(32));
    $expires = (new DateTime())->modify('+' . SESSION_LIFETIME_HOURS . ' hours')->format('Y-m-d H:i:s');
    $ins = db()->prepare('INSERT INTO admin_sessions (token, user_id, expires_at) VALUES (?, ?, ?)');
    $ins->execute([$token, $user['id'], $expires]);
    return $token;
}

function current_bearer_token(): ?string {
    $header = $_SERVER['HTTP_AUTHORIZATION']
        ?? $_SERVER['REDIRECT_HTTP_AUTHORIZATION']
        ?? (function_exists('apache_request_headers') ? (apache_request_headers()['Authorization'] ?? null) : null);
    if (!$header) return null;
    if (preg_match('/^Bearer\s+(.+)$/i', trim($header), $m)) return $m[1];
    return null;
}

/** True if the request carries a currently-valid session token. */
function is_authed(): bool {
    $token = current_bearer_token();
    if (!$token || !preg_match('/^[a-f0-9]{64}$/', $token)) return false;
    $stmt = db()->prepare('SELECT 1 FROM admin_sessions WHERE token = ? AND expires_at > NOW() LIMIT 1');
    $stmt->execute([$token]);
    return (bool) $stmt->fetchColumn();
}

function require_auth(): void {
    if (!is_authed()) {
        json_response(['error' => 'Unauthorized — log in again'], 401);
    }
}

function logout_token(): void {
    $token = current_bearer_token();
    if ($token) {
        db()->prepare('DELETE FROM admin_sessions WHERE token = ?')->execute([$token]);
    }
}

/** Creates the first admin user. Only callable from the CLI setup script, never over HTTP. */
function create_admin_user(string $username, string $password): void {
    $hash = password_hash($password, PASSWORD_DEFAULT);
    $stmt = db()->prepare('INSERT INTO admin_users (username, password_hash) VALUES (?, ?)
        ON DUPLICATE KEY UPDATE password_hash = VALUES(password_hash)');
    $stmt->execute([$username, $hash]);
}

function json_response($data, int $status = 200): void {
    http_response_code($status);
    header('Content-Type: application/json');
    echo json_encode($data);
    exit;
}

function send_cors_headers(): void {
    header('Access-Control-Allow-Origin: ' . ALLOWED_ORIGIN);
    header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
    header('Access-Control-Allow-Headers: Content-Type, Authorization');
    if (($_SERVER['REQUEST_METHOD'] ?? '') === 'OPTIONS') {
        http_response_code(204);
        exit;
    }
}
