'use client';

/**
 * Slash-command types — public surface for the composer's `/` UI.
 *
 * Pure type module — no React, no DOM, no side effects. Safe to import
 * from anywhere (including the pure state machine in `state.ts`).
 */
import type { ReactNode } from 'react';

/** One slash verb the composer exposes in the dropdown. */
export interface SlashCommand {
  /** Stable id — verb without the leading slash (e.g. `"clear"`). */
  id: string;
  /** Display token incl. the slash (e.g. `"/clear"`). */
  token: string;
  /** Row label — short, action-style ("Clear conversation"). */
  label: string;
  /** Optional one-line description shown beneath the label. */
  description?: string;
  /**
   * Display-only hint rendered next to the label in the menu (e.g.
   * `<text>`, `<host>`). Does NOT affect selection behavior — use
   * `autoExecute` to control whether picking runs immediately.
   */
  argHint?: string;
  /** Optional row icon — host-supplied so this module ships zero icon deps. */
  icon?: ReactNode;
  /** Extra match terms beyond `id` (aliases used by `filterCommands`). */
  keywords?: readonly string[];
  /**
   * Optional executor. When `autoExecute: true`, the composer invokes
   * this on selection (with `''` as args) and clears the buffer. For
   * insert-style commands (the default) hosts typically call this
   * themselves on submit, with the user-typed arguments.
   */
  onExecute?: (args: string) => void | Promise<void>;
  /**
   * When true, picking this command runs `onExecute()` immediately and
   * clears the composer buffer (no `/verb` is inserted). Default false —
   * commands are inserted as `/verb ` with the cursor positioned for
   * argument entry, and submitted by the user as a normal message.
   *
   * Set to `true` for action commands that should not produce a message
   * (e.g. `/clear`, `/settings`, `/help`).
   */
  autoExecute?: boolean;
}

/**
 * Three states of the slash machine — the editor either has no leading
 * slash (`none`), is typing a verb (`composing`, menu open), or has
 * resolved a known verb followed by free-text args (`command`).
 */
export type SlashState =
  | { kind: 'none' }
  | { kind: 'composing'; filter: string }
  | { kind: 'command'; command: SlashCommand; argument: string };

/** Per-composer slash config — currently just the verb list. */
export interface SlashConfig {
  /** The verbs available in this composer instance. */
  commands: SlashCommand[];
}
