<?php

namespace App\Http\Middleware;

use App\Services\Captcha\CaptchaService;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class VerifyCaptcha
{
    protected CaptchaService $captchaService;

    public function __construct(CaptchaService $captchaService)
    {
        $this->captchaService = $captchaService;
    }

    /**
     * Handle an incoming request.
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next, string $location = 'unknown'): Response
    {
        // Skip if CAPTCHA is not enabled for this location
        if (!$this->captchaService->isEnabled($location)) {
            return $next($request);
        }

        // Skip if IP is whitelisted
        if ($this->captchaService->isWhitelisted()) {
            return $next($request);
        }

        // Get CAPTCHA response from request
        $response = $this->getCaptchaResponse($request);

        if (empty($response)) {
            return $this->failedValidation('CAPTCHA verification required.');
        }

        // Verify CAPTCHA
        $result = $this->captchaService->verify($response, $location, $request->ip());

        if (!$result['success']) {
            $errorMessage = $result['error'] ?? 'CAPTCHA verification failed.';

            if (isset($result['rate_limited']) && $result['rate_limited']) {
                $errorMessage = 'Too many failed attempts. Please try again later.';
            }

            return $this->failedValidation($errorMessage);
        }

        // Store verification result in request for later use
        $request->merge(['captcha_verified' => true]);
        $request->attributes->set('captcha_result', $result);

        return $next($request);
    }

    /**
     * Get CAPTCHA response from request
     */
    protected function getCaptchaResponse(Request $request): ?string
    {
        $provider = $this->captchaService->getProviderName();

        return match ($provider) {
            'hcaptcha' => $request->input('h-captcha-response'),
            'recaptcha_v2', 'recaptcha_v2_invisible', 'recaptcha_v3' => $request->input('g-recaptcha-response'),
            'turnstile' => $request->input('cf-turnstile-response'),
            'trustip' => $request->input('trustip-token'),
            default => null,
        };
    }

    /**
     * Handle failed validation
     */
    protected function failedValidation(string $message): Response
    {
        if (request()->expectsJson()) {
            return response()->json([
                'success' => false,
                'message' => $message,
                'errors' => [
                    'captcha' => [$message]
                ]
            ], 422);
        }

        return redirect()->back()
            ->withInput()
            ->withErrors(['captcha' => $message]);
    }
}
