<?php

declare(strict_types=1);

namespace BotGuard\Services\Detection\Modules;

use BotGuard\Services\Detection\ModuleResult;
use BotGuard\Services\Detection\SignalBag;

/**
 * CAPTCHA / puzzle verification module.
 *
 * The actual challenge verification (puzzle answer match or provider
 * siteverify) is performed by the API controller via a CaptchaProvider; its
 * boolean result plus solve metrics are injected into the signal bag under
 * "captcha.*". This module converts that into a score, additionally penalising
 * implausibly fast solves and excessive retries.
 */
final class CaptchaModule extends AbstractModule
{
    public function key(): string
    {
        return 'captcha';
    }

    public function analyze(SignalBag $signals): ModuleResult
    {
        $captcha = $signals->clientArray('captcha');

        $verified = (bool) ($captcha['verified'] ?? false);
        $provider = (string) ($captcha['provider'] ?? 'puzzle');
        $solveTime = (int) ($captcha['solve_time_ms'] ?? 0);
        $retries = (int) ($captcha['retries'] ?? 0);

        $minSolve = (int) config('captcha.puzzle.min_solve_ms', 350);
        $maxRetries = (int) config('captcha.puzzle.max_retries', 3);

        $this->detail('provider', $provider);
        $this->detail('verified', $verified);
        $this->detail('solve_time_ms', $solveTime);
        $this->detail('retries', $retries);

        // Passing the challenge is the dominant factor.
        $this->check('Challenge verified', $verified, 4.0);

        // A solve faster than a human reaction time is bot-like.
        $this->check('Human-plausible solve time', $solveTime === 0 || $solveTime >= $minSolve, 1.5);

        // Endless retries suggest brute-forcing.
        $this->check('Retry count within limit', $retries <= $maxRetries, 1.0);

        return $this->result();
    }
}
