import { describe, expect, it } from "vitest";
import {
  createCompatPayloadPatch,
  createLayoutCommand,
  createThemeCommand,
  createToolbarKernelCommand,
  createViewPatchCommand,
  diffMindmapRuntimeDataToKernelCommands,
} from "./mindmap-command-diff";

describe("mindmap command bridge mapping", () => {
  it("把明确 toolbar 动作映射到 kernel command", () => {
    expect(
      createToolbarKernelCommand({
        mindmapId: "mind_1",
        runtimeCommand: "INSERT_CHILD_NODE",
        activeNodeId: "node_1",
      }),
    ).toEqual({
      type: "insertChild",
      mindmapId: "mind_1",
      parentNodeId: "node_1",
      node: { text: "新节点" },
    });

    expect(
      createToolbarKernelCommand({
        mindmapId: "mind_1",
        runtimeCommand: "REMOVE_NODE",
        activeNodeId: "node_2",
      }),
    ).toEqual({
      type: "deleteNode",
      mindmapId: "mind_1",
      nodeId: "node_2",
    });
  });

  it("把暂未语义化的 toolbar 动作落入 compatPayload patch", () => {
    expect(
      createToolbarKernelCommand({
        mindmapId: "mind_1",
        runtimeCommand: "ADD_GENERALIZATION",
        activeNodeId: "node_1",
      }),
    ).toEqual({
      type: "compatPayloadPatch",
      mindmapId: "mind_1",
      path: "root.data.generalization",
      value: { text: "概要" },
      source: "toolbar",
    });
  });

  it("构建 view/theme/layout 和通用 compat patch command", () => {
    expect(createViewPatchCommand("mind_1", { scale: 0.9 })).toEqual({
      type: "patchView",
      mindmapId: "mind_1",
      patch: { scale: 0.9 },
    });
    expect(createThemeCommand("mind_1", "classic4", { root: true })).toEqual({
      type: "setTheme",
      mindmapId: "mind_1",
      theme: "classic4",
      themeConfig: { root: true },
    });
    expect(createLayoutCommand("mind_1", "logicalStructure")).toEqual({
      type: "setLayout",
      mindmapId: "mind_1",
      layout: "logicalStructure",
    });
    expect(
      createCompatPayloadPatch({
        mindmapId: "mind_1",
        path: "root.data.image",
        value: "asset:img_1",
      source: "sidebar",
      actionId: "image",
      runtimeRevision: 7,
      kernelRevision: 3,
    }),
  ).toEqual({
      type: "compatPayloadPatch",
      mindmapId: "mind_1",
      path: "root.data.image",
      value: "asset:img_1",
      source: "sidebar",
      actionId: "image",
      runtimeRevision: 7,
      kernelRevision: 3,
    });
  });

  it("从 data_change diff 识别文本、插入、删除、移动和 compat 字段", () => {
    const previous = {
      data: { uid: "root", text: "KMIND" },
      children: [
        { data: { uid: "a", text: "A", image: "asset:old" }, children: [] },
        { data: { uid: "b", text: "B" }, children: [] },
      ],
    };
    const next = {
      data: { uid: "root", text: "KMIND" },
      children: [
        {
          data: { uid: "a", text: "A2", image: "asset:new" },
          children: [{ data: { uid: "c", text: "C" }, children: [] }],
        },
      ],
    };

    expect(
      diffMindmapRuntimeDataToKernelCommands({
        mindmapId: "mind_1",
        previous,
        next,
      }),
    ).toEqual({
      commands: [
        { type: "updateText", mindmapId: "mind_1", nodeId: "a", text: "A2" },
        {
          type: "insertChild",
          mindmapId: "mind_1",
          parentNodeId: "a",
          node: { uid: "c", text: "C" },
        },
        { type: "deleteNode", mindmapId: "mind_1", nodeId: "b" },
      ],
      compatPatches: [
        {
          type: "compatPayloadPatch",
          mindmapId: "mind_1",
          path: "nodes.a.data.image",
          value: "asset:new",
          source: "adapter-diff",
        },
      ],
    });
  });

  it("从 data_change diff 识别节点移动", () => {
    const previous = {
      data: { uid: "root", text: "KMIND" },
      children: [
        { data: { uid: "a", text: "A" }, children: [] },
        { data: { uid: "b", text: "B" }, children: [] },
      ],
    };
    const next = {
      data: { uid: "root", text: "KMIND" },
      children: [{ data: { uid: "a", text: "A" }, children: [{ data: { uid: "b", text: "B" }, children: [] }] }],
    };

    expect(
      diffMindmapRuntimeDataToKernelCommands({
        mindmapId: "mind_1",
        previous,
        next,
      }).commands,
    ).toContainEqual({
      type: "moveNode",
      mindmapId: "mind_1",
      nodeId: "b",
      newParentNodeId: "a",
      order: 0,
    });
  });
});
