import { describe, expect, it } from "vitest";
import {
  MINDMAP_TOOLBAR_MORE_ACTION_ID,
  MINDMAP_DEBUG_CHROME_QUERY_PARAM,
  isMindmapDebugChromeEnabled,
  mindmapDefaultUiSchema,
  mindmapToolbarFileActionOrder,
  mindmapToolbarPrimaryActionOrder,
} from "./mindmap-ui-schema";
import { getMindmapActionMapping } from "./mindmap-action-map";

describe("mindmap UI schema", () => {
  it("默认 schema 暴露第一阶段 UI shell 分区", () => {
    expect(mindmapDefaultUiSchema.toolbarGroups.map((group) => group.id)).toEqual([
      "history",
      "node",
      "insert",
      "file",
      "view",
    ]);
    expect(mindmapDefaultUiSchema.sidebarPanels.map((panel) => panel.id)).toEqual([
      "nodeStyle",
      "baseStyle",
      "theme",
      "structure",
      "outline",
      "shortcutKey",
      "settings",
    ]);
    expect(mindmapDefaultUiSchema.navigatorItems.map((item) => item.id)).toEqual([
      "stats",
      "centerRoot",
      "search",
      "zoomOut",
      "zoom",
      "zoomIn",
      "fullscreen",
      "readonly",
    ]);
  });

  it("默认不启用旧手写 chrome，只有显式 debug 参数才启用", () => {
    expect(MINDMAP_DEBUG_CHROME_QUERY_PARAM).toBe("mnoteMindmapDebugChrome");
    expect(isMindmapDebugChromeEnabled("http://127.0.0.1:3000/documents/doc_1")).toBe(false);
    expect(
      isMindmapDebugChromeEnabled("http://127.0.0.1:3000/documents/doc_1?mnoteMindmapDebugChrome=1"),
    ).toBe(true);
    expect(
      isMindmapDebugChromeEnabled("http://127.0.0.1:3000/documents/doc_1?mnoteMindmapDebugChrome=true"),
    ).toBe(true);
  });

  it("toolbar action id 不重复", () => {
    const actionIds = mindmapDefaultUiSchema.toolbarGroups.flatMap((group) => group.actions);
    expect(new Set(actionIds).size).toBe(actionIds.length);
  });

  it("单行 toolbar 主按钮顺序对齐 lx-doc/KMind", () => {
    expect([...mindmapToolbarPrimaryActionOrder, MINDMAP_TOOLBAR_MORE_ACTION_ID]).toEqual([
      "undo",
      "redo",
      "editNode",
      "insertSiblingAfter",
      "deleteNode",
      "insertChild",
      "tag",
      "hyperlink",
      "note",
      "image",
      "icon",
      "summary",
      "associativeLine",
      "formula",
      "more",
    ]);
  });

  it("toolbar 元信息包含图标、短标签、长标签、优先级和溢出归类", () => {
    const primaryMeta = mindmapToolbarPrimaryActionOrder.map((actionId) => mindmapDefaultUiSchema.toolbarActionMeta[actionId]);
    expect(primaryMeta.map((meta) => meta.priority)).toEqual([...primaryMeta.map((meta) => meta.priority)].sort((a, b) => a - b));
    expect(primaryMeta.every((meta) => meta.cluster === "main")).toBe(true);
    expect(primaryMeta.every((meta) => meta.iconKey && meta.shortLabel && meta.longLabel && meta.overflowGroup)).toBe(true);
  });

  it("导入导出属于右侧独立 toolbar cluster", () => {
    expect([...mindmapToolbarFileActionOrder]).toEqual(["import", "export"]);
    expect(mindmapToolbarFileActionOrder.map((actionId) => mindmapDefaultUiSchema.toolbarActionMeta[actionId].cluster)).toEqual([
      "file",
      "file",
    ]);
  });

  it("默认 schema 中所有 action 都有 action map 映射", () => {
    const actionIds = [
      ...mindmapDefaultUiSchema.toolbarGroups.flatMap((group) => group.actions),
      ...mindmapDefaultUiSchema.navigatorItems.flatMap((item) => (item.actionId ? [item.actionId] : [])),
      ...mindmapDefaultUiSchema.contextMenuItems.map((item) => item.actionId),
    ];

    expect(actionIds.filter((actionId) => getMindmapActionMapping(actionId) === null)).toEqual([]);
  });

  it("toolbar 真实可见 action 都有 action map，more 仅作为 shell 虚拟按钮", () => {
    const visibleActionIds = [
      ...mindmapToolbarPrimaryActionOrder,
      ...mindmapToolbarFileActionOrder,
    ];

    expect(visibleActionIds.filter((actionId) => getMindmapActionMapping(actionId) === null)).toEqual([]);
    expect(mindmapDefaultUiSchema.toolbarActionMeta).not.toHaveProperty(MINDMAP_TOOLBAR_MORE_ACTION_ID);
  });

  it("第一阶段 context menu 覆盖节点和画布动作", () => {
    expect(mindmapDefaultUiSchema.contextMenuItems.filter((item) => item.requiresNode).map((item) => item.actionId)).toEqual([
      "insertChild",
      "insertSiblingAfter",
      "deleteNode",
      "summary",
      "associativeLine",
      "expandCollapse",
      "copyNodeText",
    ]);
    expect(mindmapDefaultUiSchema.contextMenuItems.filter((item) => !item.requiresNode).map((item) => item.actionId)).toEqual([
      "centerRoot",
      "fitView",
      "search",
      "readonly",
      "showMenu",
    ]);
  });

  it("第一阶段 sidebar panel 数量受控", () => {
    expect(mindmapDefaultUiSchema.sidebarPanels).toHaveLength(7);
  });

  it("第一阶段 sidebar 暴露主题、结构和 compat patch 选项", () => {
    const themePanel = mindmapDefaultUiSchema.sidebarPanels.find((panel) => panel.id === "theme");
    expect(themePanel?.options.map((option) => option.value)).toEqual(["classic", "classic4", "simple", "dark"]);

    const structurePanel = mindmapDefaultUiSchema.sidebarPanels.find((panel) => panel.id === "structure");
    expect(structurePanel?.options.map((option) => option.value)).toEqual([
      "logicalStructure",
      "mindMap",
      "organizationStructure",
      "catalogOrganization",
      "timeline",
      "fishbone",
    ]);
    expect(structurePanel?.options.every((option) => option.controlType === "layoutCard")).toBe(true);

    const nodeStylePanel = mindmapDefaultUiSchema.sidebarPanels.find((panel) => panel.id === "nodeStyle");
    const baseStylePanel = mindmapDefaultUiSchema.sidebarPanels.find((panel) => panel.id === "baseStyle");
    expect(nodeStylePanel?.options.every((option) => Boolean(option.compatPath))).toBe(true);
    expect(baseStylePanel?.options.every((option) => Boolean(option.compatPath))).toBe(true);
  });

  it("每个 sidebar option 要么可写，要么显式标记只读", () => {
    const options = mindmapDefaultUiSchema.sidebarPanels.flatMap((panel) => panel.options);
    expect(options.length).toBeGreaterThan(0);
    expect(options.every((option) => option.actionId !== null || option.readonly === true)).toBe(true);
  });

  it("可写 sidebar option 必须能映射到 compat patch 或 kernel command", () => {
    const writableOptions = mindmapDefaultUiSchema.sidebarPanels.flatMap((panel) =>
      panel.options.filter((option) => option.readonly !== true),
    );
    expect(writableOptions.length).toBeGreaterThan(0);
    expect(
      writableOptions.every((option) => {
        if (option.compatPath) return true;
        if (!option.actionId) return false;
        const mapping = getMindmapActionMapping(option.actionId);
        return mapping?.target === "kernelCommand" || mapping?.target === "compatPatch";
      }),
    ).toBe(true);
  });
});
