<?php
declare(strict_types=1);

require_once __DIR__ . '/includes/bootstrap.php';

header('Content-Type: application/json; charset=utf-8');
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
header('X-Content-Type-Options: nosniff');

if (request_method() !== 'POST') {
    http_response_code(405);
    header('Allow: POST');
    echo json_encode(['ok' => false], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    exit;
}

if ((int)($_SERVER['CONTENT_LENGTH'] ?? 0) > 4096) {
    http_response_code(413);
    echo json_encode(['ok' => false], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    exit;
}

$action = post_text('action', 'heartbeat');
$allowedActions = ['heartbeat', 'booking_open', 'anchor_click'];
if (!in_array($action, $allowedActions, true)) {
    $action = 'heartbeat';
}

// Prevent a broken script or a simple bot from filling the activity files rapidly.
$now = time();
$window = is_array($_SESSION['_track_window'] ?? null) ? $_SESSION['_track_window'] : [];
$window = array_values(array_filter($window, static fn($ts): bool => (int)$ts >= $now - 60));
if (count($window) >= 30) {
    http_response_code(429);
    echo json_encode(['ok' => false], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    exit;
}
$window[] = $now;
$_SESSION['_track_window'] = $window;

$truncate = static function (string $value, int $limit): string {
    return function_exists('mb_substr') ? mb_substr($value, 0, $limit, 'UTF-8') : substr($value, 0, $limit);
};
$page = $truncate(post_text('page'), 120);
$details = $truncate(post_text('details'), 300);
track_activity($action, [
    'page' => $page,
    'details' => $details,
    'referrer' => $truncate((string)($_SERVER['HTTP_REFERER'] ?? ''), 500),
]);

echo json_encode(['ok' => true], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
