<?php
// ── File-based rate limiter ───────────────────────────────────────────────────
// Returns retry-after seconds when limited, null when allowed (and records hit).

function rate_limit_check(string $action, string $key, int $max, int $window): ?int {
    $dir = sys_get_temp_dir() . '/rl_perna';
    if (!is_dir($dir)) {
        mkdir($dir, 0700, true);
    }

    $safe = preg_replace('/[^a-zA-Z0-9_\-]/', '_', $key);
    $file = "$dir/{$action}_{$safe}.json";
    $now  = time();

    $data = [];
    if (file_exists($file)) {
        $raw  = file_get_contents($file);
        $data = $raw ? (json_decode($raw, true) ?? []) : [];
    }

    $data = array_values(array_filter($data, function ($t) use ($now, $window) {
        return ($now - $t) < $window;
    }));

    if (count($data) >= $max) {
        return max(1, $window - ($now - ($data[0] ?? $now)));
    }

    $data[] = $now;
    file_put_contents($file, json_encode($data), LOCK_EX);
    return null;
}

/** @param 'json'|'html' $format */
function rate_limit_respond(int $retryAfter, string $format = 'json'): void {
    http_response_code(429);
    header("Retry-After: $retryAfter");

    if ($format === 'html') {
        header('Content-Type: text/html; charset=utf-8');
        $mins = (int)ceil($retryAfter / 60);
        $timeMsg = $mins > 1 ? "about {$mins} minutes" : "{$retryAfter} seconds";
        echo '<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">'
            . '<title>Too many attempts</title></head><body style="font-family:system-ui,sans-serif;max-width:420px;margin:48px auto;padding:0 20px;text-align:center">'
            . '<h1 style="font-size:1.25rem">Too many attempts</h1>'
            . "<p>Please wait {$timeMsg} and try again.</p>"
            . '</body></html>';
        exit;
    }

    header('Content-Type: application/json');
    die(json_encode([
        'success'     => false,
        'error'       => "Too many requests. Try again in {$retryAfter}s.",
        'retry_after' => $retryAfter,
    ]));
}

/** @param 'json'|'html' $format */
function rate_limit(string $action, string $key, int $max, int $window, string $format = 'json'): void {
    $retry = rate_limit_check($action, $key, $max, $window);
    if ($retry !== null) {
        rate_limit_respond($retry, $format);
    }
}
