<?php

namespace App\Http\Middleware;

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

class BruteForceProtection
{
    /**
     * حداکثر تعداد تلاش‌های مجاز
     */
    protected $maxAttempts = 5;

    /**
     * زمان مسدود شدن (به دقیقه)
     */
    protected $lockoutTime = 30;

    /**
     * زمان ذخیره‌سازی تلاش‌ها (به دقیقه)
     */
    protected $decayMinutes = 60;

    public function handle(Request $request, Closure $next): Response
    {
        // فقط برای مسیرهای ورود به سیستم اعمال می‌شود
        if (! $this->isLoginRoute($request)) {
            return $next($request);
        }

        $key = $this->getCacheKey($request);

        // بررسی تعداد تلاش‌های قبلی
        $attempts = Cache::get($key, 0);

        if ($attempts >= $this->maxAttempts) {
            $this->logBruteForceAttempt($request);

            return response()->json([
                'message' => 'تعداد تلاش‌های شما بیش از حد مجاز است. لطفاً '.$this->lockoutTime.' دقیقه دیگر مجدداً تلاش کنید.',
                'retry_after' => $this->lockoutTime * 60,
            ], 429);
        }

        $response = $next($request);

        // اگر درخواست ناموفق بود، تعداد تلاش‌ها را افزایش می‌دهیم
        if ($response->getStatusCode() === 401 || $response->getStatusCode() === 403) {
            $this->incrementAttempts($key);
        } else {
            // اگر موفق بود، تلاش‌ها را پاک می‌کنیم
            Cache::forget($key);
        }

        return $response;
    }

    protected function isLoginRoute(Request $request): bool
    {
        return $request->is('api/login') ||
               $request->is('login') ||
               $request->is('admin/login');
    }

    protected function getCacheKey(Request $request): string
    {
        return 'brute_force_'.md5($request->ip().$request->input('email'));
    }

    protected function incrementAttempts(string $key): void
    {
        Cache::add($key, 1, $this->decayMinutes * 60);
        Cache::increment($key);
    }

    protected function logBruteForceAttempt(Request $request): void
    {
        Log::warning('تلاش Brute Force شناسایی شد', [
            'ip' => $request->ip(),
            'email' => $request->input('email'),
            'user_agent' => $request->userAgent(),
            'attempts' => Cache::get($this->getCacheKey($request)),
        ]);
    }
}
