<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Symfony\Component\HttpFoundation\Response;

class WebhookRateLimit
{
    /**
     * Handle an incoming request.
     *
     * @param  Closure(Request):Response  $next
     */
    public function handle(Request $request, Closure $next): Response
    {
        $provider = $request->route('provider');
        $clientIp = $request->ip();

        // Rate limits per provider (requests per minute)
        $rateLimits = [
            'polar' => 60,        // Polar: 60 requests per minute
            'stripe' => 100,      // Stripe: 100 requests per minute
            'lemon_squeezy' => 60, // Lemon Squeezy: 60 requests per minute
            'oxapay' => 30,       // OxaPay: 30 requests per minute
            'crypto' => 20,       // Crypto: 20 requests per minute
        ];

        $rateLimit = $rateLimits[$provider] ?? 30; // Default: 30 requests per minute

        // Cache key for rate limiting
        $key = "webhook_rate_limit:{$provider}:{$clientIp}";

        // Use Laravel's Cache atomic increment for rate limiting
        $current = Cache::increment($key, 1, now()->addMinutes(1));

        // Check if rate limit exceeded
        if ($current > $rateLimit) {
            // Log rate limit violation
            \Log::warning('Webhook rate limit exceeded', [
                'provider' => $provider,
                'ip' => $clientIp,
                'current' => $current,
                'limit' => $rateLimit,
                'user_agent' => $request->userAgent(),
                'request_size' => strlen($request->getContent()),
            ]);

            return response()->json([
                'error' => 'Rate limit exceeded',
                'message' => 'Too many webhook requests. Please try again later.',
                'retry_after' => 60,
            ], 429)->header('Retry-After', 60);
        }

        // Add rate limit headers
        $response = $next($request);
        $response->headers->set('X-RateLimit-Limit', $rateLimit);
        $response->headers->set('X-RateLimit-Remaining', max(0, $rateLimit - $current));

        return $response;
    }
}
