<?php

namespace App\Http\Middleware;

use App\Models\Setting;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpFoundation\Response;

class VerifyRecaptcha
{
    /**
     * Handle an incoming request.
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next, float $minimumScore = 0.5): Response
    {
        // Skip if reCAPTCHA is disabled
        if (!$this->isRecaptchaEnabled()) {
            return $next($request);
        }

        // Skip for authenticated users (optional - reduces friction for logged in users)
        if ($request->user()) {
            return $next($request);
        }

        $token = $request->input('recaptcha_token') ?? $request->header('X-Recaptcha-Token');

        if (!$token) {
            Log::warning('reCAPTCHA: No token provided', [
                'ip' => $request->ip(),
                'url' => $request->url(),
            ]);
            
            return $this->failResponse($request, 'Verificación de seguridad requerida.');
        }

        $verification = $this->verifyToken($token, $request->ip());

        if (!$verification['success']) {
            Log::warning('reCAPTCHA: Verification failed', [
                'ip' => $request->ip(),
                'url' => $request->url(),
                'errors' => $verification['error-codes'] ?? [],
            ]);
            
            return $this->failResponse($request, 'Verificación de seguridad fallida.');
        }

        // Check score for v3
        if (isset($verification['score']) && $verification['score'] < $minimumScore) {
            Log::warning('reCAPTCHA: Low score', [
                'ip' => $request->ip(),
                'url' => $request->url(),
                'score' => $verification['score'],
                'minimum' => $minimumScore,
            ]);
            
            return $this->failResponse($request, 'Actividad sospechosa detectada.');
        }

        return $next($request);
    }

    /**
     * Check if reCAPTCHA is enabled in settings.
     */
    protected function isRecaptchaEnabled(): bool
    {
        try {
            return (bool) Setting::get('recaptcha_enabled', false);
        } catch (\Exception $e) {
            return false;
        }
    }

    /**
     * Verify the reCAPTCHA token with Google.
     */
    protected function verifyToken(string $token, string $ip): array
    {
        try {
            $secret = Setting::get('recaptcha_secret');
            
            if (!$secret) {
                Log::error('reCAPTCHA: No secret key configured');
                return ['success' => false, 'error-codes' => ['missing-secret']];
            }

            $response = Http::asForm()->post('https://www.google.com/recaptcha/api/siteverify', [
                'secret' => $secret,
                'response' => $token,
                'remoteip' => $ip,
            ]);

            if (!$response->successful()) {
                return ['success' => false, 'error-codes' => ['api-error']];
            }

            return $response->json();

        } catch (\Exception $e) {
            Log::error('reCAPTCHA: Verification error', ['error' => $e->getMessage()]);
            return ['success' => false, 'error-codes' => ['exception']];
        }
    }

    /**
     * Return appropriate fail response based on request type.
     */
    protected function failResponse(Request $request, string $message): Response
    {
        if ($request->expectsJson() || $request->ajax()) {
            return response()->json([
                'success' => false,
                'message' => $message,
                'error' => 'recaptcha_failed',
            ], 422);
        }

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