// 命令面板（⌘K）纯逻辑：命令清单组装 + 模糊过滤 + 键盘选择状态机。
// 对齐 UX §7（快速导航/动作）。纯逻辑，便于 node 环境单测（不依赖 DOM）。

export type CommandKind = "navigate" | "action";

export interface Command {
  id: string;
  // 展示标题（如「写本章」「跳转伏笔」）。
  title: string;
  // 用于匹配的关键词（拼音/别名），与 title 一起参与过滤。
  keywords: string[];
  kind: CommandKind;
  // navigate：跳转路径；action：交由调用方按 id 分派。
  href?: string;
  group: string;
}

// 工具箱生成器的最小描述（命令面板按此生成 action-gen-<key>，无需整份 descriptor）。
export interface ToolCommandInfo {
  key: string;
  title: string;
  genre?: string | null;
}

// 项目内可用命令（projectId 已知）。导航项给 href；动作项（生成角色等）给 id。
// tools：工具箱生成器列表（可空）→ 每个生成一条 action-gen-<key> 深链命令（命令面板发现性）。
export function projectCommands(
  projectId: string,
  tools: readonly ToolCommandInfo[] = [],
): Command[] {
  const p = `/projects/${projectId}`;
  const toolCommands: Command[] = tools.map((tool) => ({
    id: `action-gen-${tool.key}`,
    title: tool.title,
    keywords: ["生成器", "工具箱", "generator", tool.key, tool.genre ?? ""].filter(
      (k) => k.length > 0,
    ),
    kind: "action",
    href: `${p}/toolbox?open=${tool.key}`,
    group: "动作",
  }));
  return [
    {
      id: "nav-write",
      title: "写本章",
      keywords: ["write", "写作", "工作台", "起草"],
      kind: "navigate",
      href: `${p}/write`,
      group: "导航",
    },
    {
      id: "nav-review",
      title: "审稿",
      keywords: ["review", "质检", "冲突", "裁决"],
      kind: "navigate",
      href: `${p}/review`,
      group: "导航",
    },
    {
      id: "nav-outline",
      title: "大纲",
      keywords: ["outline", "节拍", "beats"],
      kind: "navigate",
      href: `${p}/outline`,
      group: "导航",
    },
    {
      id: "nav-foreshadow",
      title: "跳转伏笔",
      keywords: ["foreshadow", "伏笔", "看板", "线索"],
      kind: "navigate",
      href: `${p}/foreshadow`,
      group: "导航",
    },
    {
      id: "nav-style",
      title: "文风",
      keywords: ["style", "文风", "指纹", "漂移"],
      kind: "navigate",
      href: `${p}/style`,
      group: "导航",
    },
    {
      id: "nav-codex",
      title: "搜设定",
      keywords: ["codex", "设定库", "人物", "世界观", "角色"],
      kind: "navigate",
      href: `${p}/codex`,
      group: "导航",
    },
    {
      id: "nav-toolbox",
      title: "工具箱",
      keywords: ["toolbox", "工具箱", "生成器", "脑洞", "书名", "金手指"],
      kind: "navigate",
      href: `${p}/toolbox`,
      group: "导航",
    },
    {
      id: "nav-rules",
      title: "规则",
      keywords: ["rules", "规则", "硬规则"],
      kind: "navigate",
      href: `${p}/rules`,
      group: "导航",
    },
    {
      id: "nav-skills",
      title: "技能库",
      keywords: ["skills", "技能", "注册表"],
      kind: "navigate",
      href: `${p}/skills`,
      group: "导航",
    },
    {
      id: "action-gen-character",
      title: "生成角色",
      keywords: ["character", "角色", "生成器", "群像"],
      kind: "action",
      href: `${p}/codex?gen=character`,
      group: "动作",
    },
    {
      id: "action-gen-world",
      title: "生成世界观",
      keywords: ["world", "世界观", "设定", "设计器"],
      kind: "action",
      href: `${p}/codex?gen=world`,
      group: "动作",
    },
    ...toolCommands,
  ];
}

// 全局命令（无 projectId 时；如作品库/设置）。
export function globalCommands(): Command[] {
  return [
    {
      id: "nav-home",
      title: "作品库",
      keywords: ["home", "作品", "library", "projects"],
      kind: "navigate",
      href: "/",
      group: "导航",
    },
    {
      id: "nav-settings",
      title: "设置",
      keywords: ["settings", "设置", "凭据", "provider", "档位"],
      kind: "navigate",
      href: "/settings/providers",
      group: "导航",
    },
  ];
}

// 模糊过滤：空查询返回全部；否则在 title + keywords 上做大小写无关子串匹配（保持原顺序）。
export function filterCommands(
  commands: readonly Command[],
  query: string,
): Command[] {
  const q = query.trim().toLowerCase();
  if (!q) return [...commands];
  return commands.filter((cmd) => {
    if (cmd.title.toLowerCase().includes(q)) return true;
    return cmd.keywords.some((kw) => kw.toLowerCase().includes(q));
  });
}

// 键盘高亮索引在 [0, len) 内循环（空列表归 0）。
export function clampHighlight(index: number, length: number): number {
  if (length <= 0) return 0;
  const wrapped = index % length;
  return wrapped < 0 ? wrapped + length : wrapped;
}

// 上/下方向移动高亮（循环）。
export function moveHighlight(
  index: number,
  delta: number,
  length: number,
): number {
  return clampHighlight(index + delta, length);
}
