<?php

namespace App\Support;

use Illuminate\Support\Facades\Http;
use Illuminate\Validation\ValidationException;

class TurnstileVerifier
{
    public static function enabled(): bool
    {
        if (app()->isLocal()) {
            return false;
        }

        return filled(config('services.turnstile.secret_key'));
    }

    /**
     * @param  array<string, mixed>  $input
     */
    public static function assertValidFromInput(array $input, ?string $remoteIp = null): void
    {
        $token = $input['cf-turnstile-response'] ?? null;
        self::assertValidToken(is_string($token) ? $token : null, $remoteIp);
    }

    /**
     * @throws ValidationException
     */
    public static function assertValidToken(?string $token, ?string $remoteIp = null): void
    {
        if (! self::enabled()) {
            return;
        }

        if ($token === null || trim($token) === '') {
            throw ValidationException::withMessages([
                'cf-turnstile-response' => ['Completa la verificación de seguridad para continuar.'],
            ]);
        }

        $body = [
            'secret' => config('services.turnstile.secret_key'),
            'response' => $token,
        ];

        if (filled($remoteIp)) {
            $body['remoteip'] = $remoteIp;
        }

        $response = Http::asForm()
            ->timeout(10)
            ->post('https://challenges.cloudflare.com/turnstile/v0/siteverify', $body);

        /** @var array{success?: bool} $payload */
        $payload = $response->json();

        if (! ($payload['success'] ?? false)) {
            throw ValidationException::withMessages([
                'cf-turnstile-response' => ['La verificación de seguridad falló o expiró. Inténtalo de nuevo.'],
            ]);
        }
    }
}
