<?php

namespace App\Services;

use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

class RecaptchaService
{
    protected $secretKey;
    protected $siteKey;
    protected $verifyUrl = 'https://www.google.com/recaptcha/api/siteverify';

    public function __construct()
    {
        $this->secretKey = config('services.recaptcha.secret_key');
        $this->siteKey = config('services.recaptcha.site_key');
    }

    /**
     * Vérifie la réponse reCAPTCHA
     *
     * @param string $token Token reCAPTCHA depuis le formulaire
     * @param string $action Action attendue (optionnel pour v3)
     * @param float $scoreThreshold Score minimum requis pour v3 (0.0 à 1.0)
     * @return array ['success' => bool, 'score' => float, 'action' => string, 'errors' => array]
     */
    public function verify(string $token, string $action = null, float $scoreThreshold = 0.5): array
    {
        if (empty($this->secretKey)) {
            Log::warning('reCAPTCHA secret key non configurée');
            return [
                'success' => false,
                'errors' => ['reCAPTCHA non configuré']
            ];
        }

        if (empty($token)) {
            return [
                'success' => false,
                'errors' => ['Token reCAPTCHA manquant']
            ];
        }

        try {
            $response = Http::asForm()->post($this->verifyUrl, [
                'secret' => $this->secretKey,
                'response' => $token,
                'remoteip' => request()->ip()
            ]);

            if (!$response->successful()) {
                Log::error('Erreur API reCAPTCHA', [
                    'status' => $response->status(),
                    'body' => $response->body()
                ]);
                return [
                    'success' => false,
                    'errors' => ['Erreur de vérification reCAPTCHA']
                ];
            }

            $result = $response->json();

            // Pour reCAPTCHA v2
            if (!isset($result['score'])) {
                Log::info('Vérification reCAPTCHA v2', [
                    'success' => $result['success'],
                    'hostname' => $result['hostname'] ?? null
                ]);

                return [
                    'success' => $result['success'] ?? false,
                    'hostname' => $result['hostname'] ?? null,
                    'challenge_ts' => $result['challenge_ts'] ?? null,
                    'errors' => $result['error-codes'] ?? []
                ];
            }

            // Pour reCAPTCHA v3
            $score = $result['score'] ?? 0;
            $resultAction = $result['action'] ?? '';
            $success = $result['success'] && $score >= $scoreThreshold;

            // Vérifier l'action si fournie
            if ($action && $resultAction !== $action) {
                Log::warning('Action reCAPTCHA incorrecte', [
                    'expected' => $action,
                    'received' => $resultAction
                ]);
                $success = false;
            }

            Log::info('Vérification reCAPTCHA v3', [
                'success' => $success,
                'score' => $score,
                'action' => $resultAction,
                'threshold' => $scoreThreshold
            ]);

            return [
                'success' => $success,
                'score' => $score,
                'action' => $resultAction,
                'hostname' => $result['hostname'] ?? null,
                'challenge_ts' => $result['challenge_ts'] ?? null,
                'errors' => $result['error-codes'] ?? []
            ];

        } catch (\Exception $e) {
            Log::error('Exception vérification reCAPTCHA', [
                'message' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);

            return [
                'success' => false,
                'errors' => ['Erreur technique lors de la vérification']
            ];
        }
    }

    /**
     * Vérifie reCAPTCHA v2
     *
     * @param string $token
     * @return bool
     */
    public function verifyV2(string $token): bool
    {
        $result = $this->verify($token);
        return $result['success'] ?? false;
    }

    /**
     * Vérifie reCAPTCHA v3 avec action
     *
     * @param string $token
     * @param string $action
     * @param float $scoreThreshold
     * @return bool
     */
    public function verifyV3(string $token, string $action, float $scoreThreshold = 0.5): bool
    {
        $result = $this->verify($token, $action, $scoreThreshold);
        return $result['success'] ?? false;
    }

    /**
     * Récupère le site key pour le frontend
     *
     * @return string|null
     */
    public function getSiteKey(): ?string
    {
        return $this->siteKey;
    }

    /**
     * Vérifie si reCAPTCHA est activé
     *
     * @return bool
     */
    public function isEnabled(): bool
    {
        return !empty($this->secretKey) && !empty($this->siteKey);
    }

    /**
     * Génère le HTML pour reCAPTCHA v2
     *
     * @return string
     */
    public function renderV2(): string
    {
        if (!$this->isEnabled()) {
            return '';
        }

        return sprintf(
            '<div class="g-recaptcha" data-sitekey="%s"></div>',
            e($this->siteKey)
        );
    }

    /**
     * Génère le script pour reCAPTCHA v3
     *
     * @param string $action
     * @param string $inputName
     * @return string
     */
    public function renderV3Script(string $action = 'submit', string $inputName = 'g-recaptcha-response'): string
    {
        if (!$this->isEnabled()) {
            return '';
        }

        return sprintf(
            '<script src="https://www.google.com/recaptcha/api.js?render=%s"></script>
            <script>
                grecaptcha.ready(function() {
                    grecaptcha.execute("%s", {action: "%s"}).then(function(token) {
                        document.querySelector(\'input[name="%s"]\').value = token;
                    });
                });
            </script>',
            e($this->siteKey),
            e($this->siteKey),
            e($action),
            e($inputName)
        );
    }
}
