import { describe, expect, it, vi } from "vitest";
import { buildParentById } from "@/lib/file-tree/dnd";

vi.mock("next/server", () => ({
  NextResponse: {
    json: (body: unknown, init?: { status?: number }) => ({
      body,
      status: init?.status ?? 200,
    }),
  },
}), { virtual: true });

vi.mock("@/lib/convex/api", () => ({
  api: {
    documents: { getMeta: "documents:getMeta" },
    workspaces: { ensureDefaultWorkspace: "workspaces:ensureDefaultWorkspace" },
  },
}));

vi.mock("@/lib/convex/route", () => ({
  getAuthedConvexClient: vi.fn(),
}));

vi.mock("@/lib/documents/bridge", () => ({
  buildDocumentBridgeContextWithActor: vi.fn(),
  buildDocumentCommandEnvelope: vi.fn(),
  documentBridgeErrorResponse: vi.fn(),
}));

vi.mock("@/lib/documents/bridge-log", () => ({
  recordBridgeCommandArtifacts: vi.fn(),
  recordBridgeCommandFailureArtifacts: vi.fn(),
}));

vi.mock("@/lib/documents/rust-runtime", () => ({
  executeRustBridgeMutationTransport: vi.fn(),
  resolveRustBridgeCommandPlan: vi.fn(),
}));

vi.mock("@/lib/server/local-paths", () => ({
  getDocumentsBaseDir: () => "/tmp/mnote-vitest-documents",
}));

const {
  normalizeDocumentCopyTreePayload,
  normalizeDocumentMovePayload,
  resolveSubtreeMoveLegality,
} = await import("./page-lifecycle-command-adapter");

describe("page-lifecycle-command-adapter", () => {
  it("归一化 move payload 的 targetParentId 与 sortOrder", () => {
    expect(
      normalizeDocumentMovePayload({
        documentId: "  doc_1 ",
        parentId: " parent_1 ",
        position: 2.8,
      }),
    ).toEqual({
      documentId: "doc_1",
      parentId: "parent_1",
      sortOrder: 2,
    });

    expect(
      normalizeDocumentMovePayload({
        documentId: "doc_1",
        parentId: " ",
        position: Number.NaN,
      }),
    ).toEqual({
      documentId: "doc_1",
      parentId: null,
      sortOrder: 0,
    });
  });

  it("归一化 copy_tree payload 并去重 source ids", () => {
    expect(
      normalizeDocumentCopyTreePayload({
        targetParentId: " parent_1 ",
        items: [
          { documentId: " doc_a ", recursive: true },
          { documentId: "doc_b", recursive: false },
          { documentId: "doc_a", recursive: false },
          { documentId: " ", recursive: true },
        ],
      }),
    ).toEqual({
      targetParentId: "parent_1",
      items: [
        { documentId: "doc_a", recursive: true },
        { documentId: "doc_b", recursive: false },
        { documentId: "doc_a", recursive: false },
      ],
      sourceIds: ["doc_a", "doc_b"],
    });
  });

  it("在 subtree move legality 中先收敛顶层 source，再拦截自拖拽/拖入后代", () => {
    const parentById = buildParentById([
      { id: "a", parentId: null },
      { id: "b", parentId: "a" },
      { id: "c", parentId: "b" },
      { id: "d", parentId: null },
    ]);

    expect(
      resolveSubtreeMoveLegality({
        sourceDocIds: ["a", "b", "c", "d"],
        targetParentId: "b",
        parentById,
      }),
    ).toEqual({
      sourceDocIds: ["a", "d"],
      targetParentId: "b",
      isInvalid: true,
    });

    expect(
      resolveSubtreeMoveLegality({
        sourceDocIds: ["b", "c"],
        targetParentId: "a",
        parentById,
      }),
    ).toEqual({
      sourceDocIds: ["b"],
      targetParentId: "a",
      isInvalid: false,
    });
  });
});
