<?php

declare(strict_types=1);

namespace ServerManager\Middleware;

use ServerManager\Core\Session;
use ServerManager\Core\Database;
use ServerManager\Core\App;

class RateLimitMiddleware
{
    public function handle(): mixed
    {
        $config = App::getConfig()['rate_limit'];
        $maxAttempts = $config['max_attempts'] ?? 5;
        $decayMinutes = $config['decay_minutes'] ?? 15;

        $ip = $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1';
        $key = 'rate_limit_' . $ip . '_' . ($_SERVER['REQUEST_URI'] ?? '/');

        $attempts = Session::get($key, ['count' => 0, 'first_attempt' => 0]);

        if ($attempts['first_attempt'] && (time() - $attempts['first_attempt']) > ($decayMinutes * 60)) {
            $attempts = ['count' => 0, 'first_attempt' => 0];
        }

        $attempts['count']++;

        if ($attempts['first_attempt'] === 0) {
            $attempts['first_attempt'] = time();
        }

        Session::set($key, $attempts);

        if ($attempts['count'] > $maxAttempts) {
            $retryAfter = ($decayMinutes * 60) - (time() - $attempts['first_attempt']);

            if ($this->isApiRequest()) {
                http_response_code(429);
                header('Content-Type: application/json');
                header("Retry-After: {$retryAfter}");
                echo json_encode([
                    'error' => 'Too many requests. Please try again later.',
                    'retry_after' => $retryAfter,
                ]);
                exit;
            }

            http_response_code(429);
            header("Retry-After: {$retryAfter}");
            echo '<h1>429 Too Many Requests</h1><p>Please wait ' . ceil($retryAfter / 60) . ' minutes before trying again.</p>';
            exit;
        }

        return null;
    }

    private function isApiRequest(): bool
    {
        return str_starts_with($_SERVER['REQUEST_URI'] ?? '', '/api/');
    }
}
