<?php declare(strict_types=1);
/*
 * This file is part of the SplendidBear Websites' projects.
 *
 * Copyright (c) 2026 @ www.splendidbear.org
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace App\Service;

use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Contracts\HttpClient\HttpClientInterface;

/**
 * Class RecaptchaService
 *
 * @package  App\Service
 * @author   Lang <https://www.splendidbear.org>
 * @category Class
 * @license  https://www.gnu.org/licenses/lgpl-3.0.en.html GNU Lesser General Public License
 * @link     www.splendidbear.org
 * @since    2026. 04. 12.
 */
readonly final class RecaptchaService
{
    private const string SITEVERIFY_URL = 'https://www.google.com/recaptcha/api/siteverify';

    /**
     * Minimum score to accept a request (0.0 = bot, 1.0 = human).
     * 0.5 is Google's recommended default threshold.
     */
    private const float SCORE_THRESHOLD = 0.5;

    public function __construct(
        private HttpClientInterface $httpClient,
        private LoggerInterface $logger,
        #[Autowire(env: 'RECAPTCHA_SECRET_KEY')]
        private string $secretKey,
    ) {}

    public function verify(string $token, string $remoteIp = ''): bool
    {
        if ($token === '') {
            return false;
        }

        try {
            $body = ['secret' => $this->secretKey, 'response' => $token];

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

            $data = $this->httpClient
                ->request('POST', self::SITEVERIFY_URL, ['body' => $body])
                ->toArray();

            $this->logger->info('reCAPTCHA verify response', [
                'success'       => $data['success'] ?? null,
                'score'         => $data['score'] ?? null,
                'hostname'      => $data['hostname'] ?? null,
                'error-codes'   => $data['error-codes'] ?? [],
                'token_length'  => strlen($token),
            ]);

            return ($data['success'] ?? false) === true
                && ($data['score'] ?? 0.0) >= self::SCORE_THRESHOLD;
        } catch (\Throwable $e) {
            $this->logger->error('reCAPTCHA verification failed: ' . $e->getMessage());

            return false;
        }
    }
}
