<?php

declare(strict_types=1);

namespace BotGuard\Services\Detection\Modules;

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

/**
 * Link / interactive-element interaction module.
 *
 * Humans tend to hover interactive elements (links, buttons) before acting, with
 * a measurable dwell, and rarely fire the exact double-click or zero-delay click
 * patterns of scripted clients. This module rewards natural hover/click behaviour
 * and stays neutral when there was simply nothing to interact with — absence of
 * link interaction is not, by itself, evidence of a bot.
 */
final class LinkInteractionModule extends AbstractModule
{
    public function key(): string
    {
        return 'link_interaction';
    }

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

        if ($links === []) {
            return $this->scored(0.8, [], [], ['present' => false]);
        }

        $hoverCount = (int) ($links['hover_count'] ?? 0);
        $avgHoverMs = (float) ($links['avg_hover_ms'] ?? 0);
        $instantClicks = (int) ($links['instant_clicks'] ?? 0);
        $doubleClicks = (int) ($links['double_clicks'] ?? 0);
        $touchEvents = (int) ($links['touch_events'] ?? 0);

        $this->detail('hover_count', $hoverCount);
        $this->detail('avg_hover_ms', $avgHoverMs);
        $this->detail('instant_clicks', $instantClicks);

        // Hovered an interactive element (pointer or focus) — natural on desktop.
        $this->check('Hovered interactive elements', $hoverCount >= 1 || $touchEvents >= 1, 1.0);

        // Hover dwell isn't impossibly short (a scripted pointer teleports).
        $this->check('Plausible hover dwell', $hoverCount === 0 || $avgHoverMs >= 40, 1.0);

        // No burst of zero-delay clicks (clicks the instant an element appears).
        $this->check('No instant-click pattern', $instantClicks === 0, 1.5);

        // Excessive double-clicking on links is unusual/automated.
        $this->check('No abnormal double-clicking', $doubleClicks <= 3, 0.5);

        return $this->result(0.8);
    }
}
