<?php
// ============================================================
// API Bootstrap — required at top of every API endpoint
// ============================================================

define('BASE_PATH', dirname(__DIR__)); // Project root = one level up from /api/

require_once BASE_PATH . '/config/config.php';
require_once BASE_PATH . '/config/db.php';
require_once BASE_PATH . '/helpers/JWT.php';
require_once BASE_PATH . '/helpers/Response.php';
require_once BASE_PATH . '/helpers/RateLimit.php';
require_once BASE_PATH . '/middleware/AuthMiddleware.php';

// ─── CORS & Content-Type ─────────────────────────────────
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
header('Access-Control-Allow-Credentials: true');

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(204);
    exit;
}

// ─── Parse JSON body ─────────────────────────────────────
function getBody(): array {
    $raw = file_get_contents('php://input');
    if (empty($raw)) return [];
    $data = json_decode($raw, true);
    return is_array($data) ? $data : [];
}

// ─── Get client IP ───────────────────────────────────────
function clientIp(): string {
    return $_SERVER['HTTP_X_FORWARDED_FOR']
        ?? $_SERVER['HTTP_CLIENT_IP']
        ?? $_SERVER['REMOTE_ADDR']
        ?? '0.0.0.0';
}

// ─── Generate OTP ────────────────────────────────────────
function generateOTP(): string {
    return str_pad((string)random_int(0, 999999), OTP_LENGTH, '0', STR_PAD_LEFT);
}

// ─── Set refresh token cookie ─────────────────────────────
function setRefreshCookie(string $token, bool $rememberMe = false): void {
    $ttl     = $rememberMe ? JWT_REFRESH_TTL : JWT_REFRESH_TTL_SHORT;
    $expires = time() + $ttl;
    setcookie('refreshToken', $token, [
        'expires'  => $expires,
        'path'     => COOKIE_PATH,
        'secure'   => COOKIE_SECURE,
        'httponly' => true,
        'samesite' => COOKIE_SAMESITE,
    ]);
}

// ─── Clear refresh token cookie ──────────────────────────
function clearRefreshCookie(): void {
    setcookie('refreshToken', '', [
        'expires'  => time() - 3600,
        'path'     => COOKIE_PATH,
        'secure'   => COOKIE_SECURE,
        'httponly' => true,
        'samesite' => COOKIE_SAMESITE,
    ]);
}

// ─── Build user payload for JWT ──────────────────────────
function buildAccessToken(array $user): string {
    return JWT::encode([
        'id'       => (int)$user['id'],
        'username' => $user['username'],
        'role'     => $user['role'],
    ], JWT_ACCESS_SECRET, JWT_ACCESS_TTL);
}

function buildRefreshToken(array $user): string {
    return JWT::encode(['id' => (int)$user['id']], JWT_REFRESH_SECRET, JWT_REFRESH_TTL);
}

// ─── Save session to DB ───────────────────────────────────
function saveSession(int $userId, string $refreshToken, bool $rememberMe): void {
    $db       = DB::conn();
    $ttl      = $rememberMe ? JWT_REFRESH_TTL : JWT_REFRESH_TTL_SHORT;
    $expires  = date('Y-m-d H:i:s', time() + $ttl);
    $ip       = clientIp();
    $ua       = substr($_SERVER['HTTP_USER_AGENT'] ?? '', 0, 500);
    $stmt     = $db->prepare(
        'INSERT INTO user_sessions (user_id, refresh_token, user_agent, ip_address, expires_at, remember_me)
         VALUES (?, ?, ?, ?, ?, ?)'
    );
    $stmt->execute([$userId, $refreshToken, $ua, $ip, $expires, $rememberMe ? 1 : 0]);
}
