<?php

declare(strict_types=1);

namespace Plugin\tnt_mcp\src\Mcp\Tools;

use Closure;
use Plugin\tnt_mcp\src\Mcp\Commerce\ShippingMethodReader;
use Plugin\tnt_mcp\src\Mcp\Contracts\Tool;
use Plugin\tnt_mcp\src\Mcp\Mode\EndpointClass;

/**
 * READ tool: the shipping methods, one compact row each.
 *
 * Deliberately counts rather than contents for tiers, ZIP surcharges and payment methods — the full
 * object is `get_shipping_method`, and a shop with a dozen methods and per-ZIP surcharges would
 * otherwise answer with thousands of tokens nobody asked for.
 */
final class ListShippingMethods implements Tool
{
    /** @param Closure(): ShippingMethodReader $readerFactory must not touch the DB until run() */
    public function __construct(private readonly Closure $readerFactory)
    {
    }

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

    public function description(): string
    {
        return 'List shipping methods: calculation type, countries, customer groups, and how many '
            . 'tiers and ZIP surcharges each has.';
    }

    /** @return array<string,mixed> */
    public function inputSchema(): array
    {
        return [
            'type'       => 'object',
            'properties' => [
                // The connector rejects an empty `properties` object, and the tool genuinely takes
                // no arguments — so it takes the one argument that is honest: none, opted into.
                'all' => [
                    'type'        => 'boolean',
                    'description' => 'Ignored. This tool always returns every shipping method.',
                ],
            ],
            'additionalProperties' => false,
        ];
    }

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

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

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

    /**
     * @param array<string,mixed> $args
     * @return array<string,mixed>
     */
    public function run(array $args): array
    {
        return ($this->readerFactory)()->methods();
    }
}
