<?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\OrderReader;
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: one call, the whole picture — sales, traffic, carts and the top sellers.
 *
 * The entry point of the analytics family, for the same reason {@see ShopHealth} is the entry point
 * of the whole server: "how is the shop doing" is the question that comes before the caller knows
 * which tool to reach for, and answering it with four round trips wastes three turns.
 *
 * Deliberately headline numbers only — no order list, no time series, short top-N. Everything here
 * names the tool that expands it, so this stays a map and the drill-down stays optional. Each
 * section carries its own `notes`, because the caveats (gross vs net, lifetime search counters,
 * estimated cart value) do not stop applying just because the numbers were fetched together.
 */
final class AnalyticsSummary implements Tool
{
    private const ARGS = ['since', 'until'];

    /** Enough to see a pattern, short enough that this stays a summary. */
    private const TOP_N = 5;

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

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

    public function description(): string
    {
        return 'One-call shop overview for a window: sales, traffic, carts and top sellers, with '
            . 'pointers to the tool that expands each.';
    }

    /** @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);
        $top   = AnalyticsQuery::fromArgs(
            $this->name(),
            ['limit' => self::TOP_N] + $args,
            ['since', 'until', 'limit']
        );

        $orders = ($this->orderFactory)();
        $stats  = ($this->statsFactory)();

        $sales = $orders->salesSummary($query);
        unset($sales['series'], $sales['window']); // the series belongs to sales_summary, not here

        $visitors = $stats->visitors($query);
        unset($visitors['series'], $visitors['window'], $visitors['topBrowsers']);

        $carts = $stats->carts($query);
        unset($carts['window'], $carts['topCartProducts']);

        $products = $orders->topProducts($top, 'revenue');
        $searches = $stats->searches($top);

        return [
            'window'   => $query->window(),
            'sales'    => $sales + ['expandWith' => 'sales_summary'],
            'traffic'  => $visitors + ['expandWith' => 'visitor_statistics'],
            'carts'    => $carts + ['expandWith' => 'cart_statistics'],
            'products' => [
                'top'        => $products['products'],
                'currency'   => $products['currency'],
                'notes'      => $products['notes'],
                'expandWith' => 'top_products',
            ],
            'searches' => [
                'top'            => $searches['topSearches'],
                'withoutResults' => $searches['withoutResults'],
                'notes'          => $searches['notes'],
                'expandWith'     => 'top_searches',
            ],
            'notes'    => \array_merge($query->notes, [
                'Headline figures only. Every section names the tool that returns it in full; '
                . 'list_orders and get_order go from these numbers to the individual orders.',
            ]),
        ];
    }
}
