<?php

declare(strict_types=1);

namespace Plugin\tnt_mcp\src\Mcp\Action;

/**
 * "What usually comes after this one" — `multipass-tools.md` §4, the whole of gap G3.
 *
 * Setting up shipping is rarely one call, and the sequencing is knowledge that exists nowhere a
 * caller can read it: the catalog says what each action DOES, never that a new shipping method is
 * worthless until a payment method allows it. That edge was the only part of
 * discover → propose → validate → apply → verify with no shipped mechanism.
 *
 * It is declarative on purpose. A flow engine was rejected (§7, option C contradicts D15): the LLM
 * already sequences well when it knows the edges exist, so the edges ship as YAML next to the entry
 * they belong to — same file the e2e tests import, so §6's anti-drift mechanism covers them for
 * free — and `describe_admin_action` renders at most three of them, ~40 tokens.
 *
 * Exactly one of `action` / `guide` is set; the validator enforces that, so `target()` is total.
 */
final class NextStep
{
    private function __construct(
        public readonly ?string $action,
        public readonly ?string $guide,
        public readonly string $when,
    ) {
    }

    /**
     * @param array<mixed> $raw
     */
    public static function fromArray(array $raw): self
    {
        return new self(
            \is_string($raw['action'] ?? null) ? $raw['action'] : null,
            \is_string($raw['guide'] ?? null) ? $raw['guide'] : null,
            \is_string($raw['when'] ?? null) ? $raw['when'] : '',
        );
    }

    /**
     * The one line a caller can act on: the exact call, then the condition. Naming the call rather
     * than the topic is the same discipline as the `get_guide` pointer in
     * {@see ActionDescriber::describe()} — a model that is told "see the shipping-surcharge guide"
     * has to guess the tool; one that is told `get_guide({topic: "shipping-surcharge"})` does not.
     */
    public function line(): string
    {
        if ($this->action !== null) {
            return \sprintf('describe_admin_action({id: "%s"}) — when %s', $this->action, $this->when);
        }

        return \sprintf('get_guide({topic: "%s"}) — when %s', (string)$this->guide, $this->when);
    }
}
