<?php

declare(strict_types=1);

namespace Plugin\tnt_mcp\src\Mcp\Tools;

use Plugin\tnt_mcp\src\Mcp\Contracts\Tool;
use Plugin\tnt_mcp\src\Mcp\Mode\EndpointClass;
use Plugin\tnt_mcp\src\Mcp\Settings\SettingsReader;
use Plugin\tnt_mcp\src\Mcp\Settings\SettingsRegistry;
use RuntimeException;

/** READ tool: current value of one setting, resolved generically via the settings registry. */
final class GetSetting implements Tool
{
    /**
     * @param \Closure(): SettingsReader $readerFactory built lazily — metadata methods (name(),
     *                                                   scope(), …) must stay cheap and never
     *                                                   touch the shop runtime; only run() does.
     */
    public function __construct(
        private readonly SettingsRegistry $registry,
        private readonly \Closure $readerFactory,
    ) {
    }

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

    public function description(): string
    {
        return 'Get the current value of one shop setting by its key (see list_settings).';
    }

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

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

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

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

    /**
     * @param array<string,mixed> $args
     * @return array<string,mixed>
     */
    public function run(array $args): array
    {
        $key = $args['key'] ?? null;
        if (!\is_string($key) || $key === '') {
            throw new RuntimeException('get_setting: "key" is required');
        }
        if (!$this->registry->has($key)) {
            throw new RuntimeException('get_setting: unknown setting "' . $key . '"');
        }

        $row = $this->registry->get($key);
        if (!$row->isReadable()) {
            throw new RuntimeException('get_setting: setting "' . $key . '" is not readable (mode=' . $row->mode . ')');
        }

        $reader = ($this->readerFactory)();

        return ['key' => $key, 'value' => $reader->read($row)];
    }
}
