<?php

declare(strict_types=1);

namespace Plugin\tnt_mcp\src\Mcp\Tools;

use Closure;
use Plugin\tnt_mcp\src\Mcp\Analytics\AnalyticsQuery;
use Plugin\tnt_mcp\src\Mcp\Analytics\StatsReader;
use Plugin\tnt_mcp\src\Mcp\Contracts\Tool;
use Plugin\tnt_mcp\src\Mcp\Mode\EndpointClass;

/**
 * READ tool: traffic — visits, bots, conversions, referrers, entry pages.
 *
 * The shop keeps visitors in two tables at once (`tbesucher` for the live sessions,
 * `tbesucherarchiv` for the history, with a cron moving rows across), so any single-table query is
 * wrong in one direction or the other. This merges and de-duplicates them, and counts bots
 * separately instead of letting them inflate a conversion rate.
 *
 * @see \Plugin\tnt_mcp\src\Mcp\Analytics\StatsReader
 */
final class VisitorStatistics implements Tool
{
    private const ARGS = ['since', 'until'];

    /** @param Closure(): StatsReader $readerFactory must not touch the DB until run() */
    public function __construct(private readonly Closure $readerFactory)
    {
    }

    public function name(): string
    {
        return 'visitor_statistics';
    }

    public function description(): string
    {
        return 'Shop traffic for a window: visits, bots, unique IPs, conversion rate, top referrers '
            . 'and entry pages, plus a time series.';
    }

    /** @return array<string,mixed> */
    public function inputSchema(): array
    {
        return [
            'type'                 => 'object',
            'properties'           => AnalyticsQuery::schemaFor(self::ARGS),
            'additionalProperties' => false,
        ];
    }

    public function isWrite(): bool
    {
        return false;
    }

    public function scope(): string
    {
        return 'analytics:read';
    }

    public function endpointClass(): EndpointClass
    {
        return EndpointClass::Reversible;
    }

    /**
     * @param array<string,mixed> $args
     * @return array<string,mixed>
     */
    public function run(array $args): array
    {
        $query  = AnalyticsQuery::fromArgs($this->name(), $args, self::ARGS);
        $result = ($this->readerFactory)()->visitors($query);

        $result['notes'] = \array_merge($query->notes, $result['notes']);

        return $result;
    }
}
