<?php

declare(strict_types=1);

namespace BotGuard\Middleware;

use BotGuard\Core\Cache\CacheInterface;
use BotGuard\Core\Exceptions\HttpException;
use BotGuard\Core\Request;
use BotGuard\Core\Response;
use Closure;

/**
 * Fixed-window per-IP rate limiter.
 *
 * Guards sensitive endpoints (verification, login) against floods and
 * brute-force. Limits are configurable via config('app.rate_limit'). Emits a
 * 429 with a Retry-After header once the window budget is exceeded. This is the
 * HTTP gatekeeper; the RateLimit *detection module* separately scores traffic.
 */
final class RateLimitMiddleware implements MiddlewareInterface
{
    public function __construct(private CacheInterface $cache)
    {
    }

    public function handle(Request $request, Closure $next): Response
    {
        $maxPerMinute = (int) config('app.rate_limit.per_minute', 60);
        $window = 60;

        $key = 'ratelimit:' . sha1($request->ip() . '|' . $request->path());
        $hits = $this->cache->increment($key, $window);

        if ($hits > $maxPerMinute) {
            if ($request->wantsJson()) {
                return Response::json(['error' => 'Too many requests. Slow down.'], 429)
                    ->withHeader('Retry-After', (string) $window);
            }

            throw new HttpException(429, 'Too many requests. Please slow down.');
        }

        $response = $next($request);

        return $response
            ->withHeader('X-RateLimit-Limit', (string) $maxPerMinute)
            ->withHeader('X-RateLimit-Remaining', (string) max(0, $maxPerMinute - $hits));
    }
}
