import { describe, expect, it } from "vitest";
import fs from "node:fs";
import path from "node:path";

const SIDEBAR_SOURCE = path.join(process.cwd(), "src/components/sidebar/sidebar.tsx");
const TREE_SHELL_DOM_HOST_SOURCE = path.join(process.cwd(), "src/components/sidebar/tree-shell-dom-host.tsx");

describe("sidebar file tree delete preflight source", () => {
  it("rust_family 删除链应走 Rust delete preflight，而不是本地 delete target helper", () => {
    const source = fs.readFileSync(SIDEBAR_SOURCE, "utf8");

    expect(source).toContain("preflightFileTreeDelete(");
    expect(source).toContain("buildFileTreeShellDeletePreflightPayload(");
    expect(source).not.toContain("computeFileTreeShellDeleteTargets(");
  });

  it("filetree DOM host 删除回调应直连 sidebar 删除入口", () => {
    const source = fs.readFileSync(SIDEBAR_SOURCE, "utf8");

    expect(source).toContain("const handleFileTreeShellDeleteSelection = useCallback(");
    expect(source).toContain("void handleDeleteResourceSelection(payload);");
    expect(source).toContain("onFileTreeDeleteSelection={handleFileTreeShellDeleteSelection}");
  });

  it("附件右键菜单删除应复用当前文件树 selection 删除入口", () => {
    const source = fs.readFileSync(SIDEBAR_SOURCE, "utf8");

    expect(source).toContain("const handleDeleteFromAssetContextMenu = useCallback(");
    expect(source).toContain('if (viewMode === "filesystem") {');
    expect(source).toContain("await handleDeleteResourceSelection();");
  });

  it("页面新建/删除成功后应本地更新 Sidebar，不再同步等待整树刷新", () => {
    const source = fs.readFileSync(SIDEBAR_SOURCE, "utf8");
    const createStart = source.indexOf("const handleCreate = useCallback(");
    const createEnd = source.indexOf("const handleRename = useCallback(");
    const deleteSelectionStart = source.indexOf("const handleDeleteResourceSelection = useCallback(");
    const deleteSelectionEnd = source.indexOf("const handleFileTreeShellDeleteSelection = useCallback(");
    const deleteStart = source.indexOf("const handleDelete = useCallback(");
    const deleteEnd = source.indexOf("const handleDeleteFromContextMenuNode = useCallback(");

    expect(createStart).toBeGreaterThanOrEqual(0);
    expect(createEnd).toBeGreaterThan(createStart);
    expect(deleteSelectionStart).toBeGreaterThanOrEqual(0);
    expect(deleteSelectionEnd).toBeGreaterThan(deleteSelectionStart);
    expect(deleteStart).toBeGreaterThanOrEqual(0);
    expect(deleteEnd).toBeGreaterThan(deleteStart);

    const createBody = source.slice(createStart, createEnd);
    const deleteSelectionBody = source.slice(deleteSelectionStart, deleteSelectionEnd);
    const deleteBody = source.slice(deleteStart, deleteEnd);

    expect(createBody).not.toContain("await refreshTree();");
    expect(createBody).toContain("upsertSidebarDocumentRecord(");
    expect(createBody).toContain("emitDocumentsChanged(nextNode.id);");
    expect(deleteSelectionBody).toContain("removeDocumentsFromTree(docIds);");
    expect(deleteSelectionBody).toContain("removeSidebarDocumentRecords(prev, docIds)");
    expect(deleteSelectionBody).not.toContain("await refreshTree();");
    expect(deleteBody).toContain("removeDocumentsFromTree([documentId]);");
    expect(deleteBody).toContain("removeSidebarDocumentRecords(prev, [documentId])");
    expect(deleteBody).not.toContain("await refreshTree();");
  });

  it("Rust-family tree shell mutation 成功后应本地 apply，不再默认整树刷新", () => {
    const source = fs.readFileSync(SIDEBAR_SOURCE, "utf8");
    const domHostSource = fs.readFileSync(TREE_SHELL_DOM_HOST_SOURCE, "utf8");
    const mutationStart = source.indexOf("const handleTreeShellMutation = useCallback(");
    const mutationEnd = source.indexOf("useEffect(() => {", mutationStart);

    expect(mutationStart).toBeGreaterThanOrEqual(0);
    expect(mutationEnd).toBeGreaterThan(mutationStart);

    const mutationBody = source.slice(mutationStart, mutationEnd);
    expect(mutationBody).toContain('payload.type === "tree.node.created"');
    expect(mutationBody).toContain('payload.type === "tree.node.renamed"');
    expect(mutationBody).toContain('payload.type === "tree.subtree.moved"');
    expect(mutationBody).toContain("insertNode(prev, parentId, Number.MAX_SAFE_INTEGER, nextNode)");
    expect(mutationBody).toContain("renameDocumentInTree(prev, documentId, title, payload.updatedAt ?? null)");
    expect(mutationBody).toContain("moveLocalNode(prev, documentId, parentId, sortOrder)");
    expect(mutationBody).not.toMatch(
      /const handleTreeShellMutation = useCallback\(\(\) => \{\s*void refreshTree\(\);\s*\}, \[refreshTree\]\);/,
    );

    expect(domHostSource).toContain("onTreeMutation?.({");
    expect(domHostSource).toContain('type: "tree.node.created"');
    expect(domHostSource).toContain("parentId: commandParentId");
    expect(domHostSource).toContain("title: commandTitle");
    expect(domHostSource).toContain("sortOrder: commandSortOrder");
  });
});
