import { describe, expect, it } from "vitest";
import { buildPageTreeProjectionItems } from "@/lib/tree-projection";
import { buildVisibleRows } from "./rows";
import { parseFileTreeRowId } from "./types";

describe("buildVisibleRows", () => {
  it("按展开状态稳定生成可见行", () => {
    const a = {
      access_scope: "private" as const,
      id: "a",
      workspace_id: "w",
      title: "A",
      parent_id: null,
      sort_order: 0,
      is_starred: null,
      is_template: false,
      created_at: "",
      updated_at: null,
      children: [
        {
          access_scope: "private" as const,
          id: "b",
          workspace_id: "w",
          title: "B",
          parent_id: "a",
          sort_order: 0,
          is_starred: null,
          is_template: false,
          created_at: "",
          updated_at: null,
          children: [],
        },
      ],
    };

    const rows = buildVisibleRows({
      pageRows: buildPageTreeProjectionItems([a]),
      expanded: new Set(["a"]),
      assetsByDoc: {
        a: [
          {
            id: "x",
            workspace_id: "w",
            document_id: "a",
            asset_type: "file",
            file_url: null,
            thumbnail_url: null,
            bucket: "workspace",
            storage_path: "x",
            file_name: "x.png",
            file_size: null,
            mime_type: "image/png",
            ocr_payload: undefined,
            ocr_strategy: null,
            ocr_text: null,
            ocr_status: null,
            signed_url: null,
            created_at: "",
            updated_at: "",
          },
          {
            id: "y",
            workspace_id: "w",
            document_id: "a",
            asset_type: "file",
            file_url: null,
            thumbnail_url: null,
            bucket: "workspace",
            storage_path: "y",
            file_name: "y.pdf",
            file_size: null,
            mime_type: "application/pdf",
            ocr_payload: undefined,
            ocr_strategy: null,
            ocr_text: null,
            ocr_status: null,
            signed_url: null,
            created_at: "",
            updated_at: "",
          },
        ],
      },
    });

    expect(rows.map((r) => `${r.kind}:${r.depth}:${r.rowId}`)).toEqual([
      "doc:0:doc:a",
      "index:1:index:a",
      "asset:1:asset:x",
      "asset:1:asset:y",
      "doc:1:doc:b",
    ]);

    expect(new Set(rows.map((r) => r.rowId)).size).toBe(rows.length);
  });

  it("输入树包含重复 docId 时应自动去重", () => {
    const a = {
      access_scope: "private" as const,
      id: "a",
      workspace_id: "w",
      title: "A",
      parent_id: null,
      sort_order: 0,
      is_starred: null,
      is_template: false,
      created_at: "",
      updated_at: null,
      children: [],
    };

    const rows = buildVisibleRows({
      pageRows: buildPageTreeProjectionItems([a, a]),
      expanded: new Set(["a"]),
      assetsByDoc: {},
    });

    expect(rows.filter((r) => r.rowId === "doc:a").length).toBe(1);
    expect(new Set(rows.map((r) => r.rowId)).size).toBe(rows.length);
  });

  it("优先消费 Rust file_tree projection 并保留 index 与资源文件夹语义", () => {
    const rows = buildVisibleRows({
      fileTreeItems: [
        {
          rowId: "doc:page_root",
          rowKind: "document",
          nodeId: "page_root",
          parentNodeId: null,
          nodeType: "page",
          projectionKind: "file_tree",
          title: "根页面",
          depth: 0,
          position: 0,
          childCount: 4,
          expandable: true,
          expandedByDefault: true,
          capabilities: ["expand", "open", "select"],
          resourceMeta: {
            resourceKind: "document",
            documentId: "page_root",
            workspaceId: "ws_1",
            iconHint: "page",
          },
          iconHint: "page",
        },
        {
          rowId: "index:page_root",
          rowKind: "index",
          nodeId: "index:page_root",
          parentNodeId: "page_root",
          nodeType: "index",
          projectionKind: "file_tree",
          title: "index.md",
          depth: 1,
          position: 0,
          childCount: 0,
          expandable: false,
          expandedByDefault: false,
          capabilities: ["open", "select"],
          resourceMeta: {
            resourceKind: "index",
            documentId: "page_root",
            workspaceId: "ws_1",
            iconHint: "index",
          },
          iconHint: "index",
        },
        {
          rowId: "asset-folder:mind_1",
          rowKind: "asset_folder",
          nodeId: "asset-folder:mind_1",
          parentNodeId: "page_root",
          nodeType: "mindmap",
          projectionKind: "file_tree",
          title: "头脑风暴",
          depth: 1,
          position: 1,
          childCount: 1,
          expandable: true,
          expandedByDefault: false,
          capabilities: ["expand", "open-asset", "select"],
          resourceMeta: {
            resourceKind: "mindmap",
            documentId: "page_root",
            assetId: "mind_1",
            workspaceId: "ws_1",
            assetKind: "mindmap",
            iconHint: "mindmap",
          },
          iconHint: "mindmap",
        },
        {
          rowId: "asset:asset_child_1",
          rowKind: "asset",
          nodeId: "asset:asset_child_1",
          parentNodeId: "asset-folder:mind_1",
          nodeType: "asset",
          projectionKind: "file_tree",
          title: "节点图片.png",
          depth: 2,
          position: 0,
          childCount: 0,
          expandable: false,
          expandedByDefault: false,
          capabilities: ["open-asset", "select"],
          resourceMeta: {
            resourceKind: "asset",
            documentId: "page_root",
            assetId: "asset_child_1",
            workspaceId: "ws_1",
            assetKind: "image",
            iconHint: "image",
          },
          iconHint: "image",
        },
        {
          rowId: "asset:table_1",
          rowKind: "asset",
          nodeId: "asset:table_1",
          parentNodeId: "page_root",
          nodeType: "table",
          projectionKind: "file_tree",
          title: "预算.luckysheet",
          depth: 1,
          position: 2,
          childCount: 0,
          expandable: false,
          expandedByDefault: false,
          capabilities: ["open-asset", "select"],
          resourceMeta: {
            resourceKind: "table",
            documentId: "page_root",
            assetId: "table_1",
            workspaceId: "ws_1",
            assetKind: "table",
            iconHint: "table",
          },
          iconHint: "table",
        },
      ],
      expanded: new Set(["page_root"]),
      expandedAssetFolderIds: new Set(["mind_1"]),
    });

    expect(rows.map((row) => `${row.kind}:${row.depth}:${row.rowId}`)).toEqual([
      "doc:0:doc:page_root",
      "index:1:index:page_root",
      "asset-folder:1:asset-folder:mind_1",
      "asset:2:asset:asset_child_1",
      "asset:1:asset:table_1",
    ]);
    expect(rows[0]).toMatchObject({
      kind: "doc",
      docId: "page_root",
      hasChildren: true,
      isExpanded: true,
    });
    expect(rows[2]).toMatchObject({
      kind: "asset-folder",
      docId: "page_root",
      asset: {
        id: "mind_1",
        asset_type: "mindmap",
        file_name: "头脑风暴",
      },
      hasChildren: true,
      isExpanded: true,
    });
    expect(rows[3]).toMatchObject({
      kind: "asset",
      asset: {
        id: "asset_child_1",
        asset_type: "image",
        file_name: "节点图片.png",
      },
    });
    expect(rows[4]).toMatchObject({
      kind: "asset",
      asset: {
        id: "table_1",
        asset_type: "luckysheet",
        file_name: "预算.luckysheet",
      },
    });
  });
});

describe("parseFileTreeRowId", () => {
  it("可逆解析 rowId", () => {
    expect(parseFileTreeRowId("doc:abc")).toEqual({ kind: "doc", docId: "abc" });
    expect(parseFileTreeRowId("index:abc")).toEqual({ kind: "index", docId: "abc" });
    expect(parseFileTreeRowId("asset:xyz")).toEqual({ kind: "asset", assetId: "xyz" });
    expect(parseFileTreeRowId("bad")).toBeNull();
    expect(parseFileTreeRowId("doc:")).toBeNull();
  });
});
