<?php

declare(strict_types=1);

namespace BotGuard\Services\Detection;

/**
 * The outcome of a single detection module.
 *
 * `score` is a human-likelihood in the range [0.0, 1.0] where 1.0 means
 * "certainly human" and 0.0 means "certainly automated". The engine multiplies
 * this by the module's configured weight. `passed` and `failed` list the
 * human-readable checks that contributed, and `detail` carries raw values for
 * the analytics UI.
 */
final class ModuleResult
{
    /**
     * @param string               $key    Module identifier (e.g. "user_agent").
     * @param float                $score  Human-likelihood in [0,1].
     * @param string[]             $passed Checks indicating a human.
     * @param string[]             $failed Checks indicating a bot.
     * @param array<string, mixed> $detail Raw values for display/debugging.
     */
    public function __construct(
        public readonly string $key,
        public readonly float $score,
        public readonly array $passed = [],
        public readonly array $failed = [],
        public readonly array $detail = [],
    ) {
    }

    /**
     * @param array<string, mixed> $detail
     */
    public static function make(
        string $key,
        float $score,
        array $passed = [],
        array $failed = [],
        array $detail = [],
    ): self {
        return new self($key, (float) clamp($score, 0.0, 1.0), $passed, $failed, $detail);
    }

    /**
     * @return array<string, mixed>
     */
    public function toArray(): array
    {
        return [
            'key'    => $this->key,
            'score'  => round($this->score, 4),
            'passed' => $this->passed,
            'failed' => $this->failed,
            'detail' => $this->detail,
        ];
    }
}
