import type { SidebarTreeNode } from "@/lib/kernel-sidebar";
import type {
  TreeProjectionCapability,
  TreeProjectionItemBase,
} from "@/lib/tree-protocol";

export type PageTreeProjectionItem = {
  rowId: `page:${string}`;
} & TreeProjectionItemBase & {
  node: SidebarTreeNode;
};

export type PickerTreeItem = {
  id: string;
  title: string;
  depth: number;
};

function buildPageCapabilities(childCount: number): TreeProjectionCapability[] {
  const capabilities: TreeProjectionCapability[] = [
    "open",
    "drag",
    "drop",
    "select",
    "create-child",
    "rename",
    "archive",
    "restore",
    "context-menu",
    "reorder",
  ];
  if (childCount > 0) {
    capabilities.unshift("expand");
  }
  return capabilities;
}

export function buildPageTreeProjectionItems(
  nodes: SidebarTreeNode[],
): PageTreeProjectionItem[] {
  const items: PageTreeProjectionItem[] = [];
  const visited = new Set<string>();

  const walk = (
    entries: SidebarTreeNode[],
    depth: number,
    parentNodeId: string | null,
  ) => {
    entries.forEach((node, index) => {
      if (visited.has(node.id)) {
        return;
      }
      visited.add(node.id);

      const childCount = node.children.length;
      items.push({
        rowId: `page:${node.id}`,
        nodeId: node.id,
        parentNodeId,
        nodeType: "page",
        projectionKind: "page_tree",
        depth,
        position: node.kernel?.position ?? node.sort_order ?? index,
        title: node.title ?? "无标题",
        childCount,
        expandable: childCount > 0,
        expandedByDefault: node.kernel?.expandedByDefault ?? true,
        capabilities: buildPageCapabilities(childCount),
        resourceMeta: {
          resourceKind: "document",
          documentId: node.id,
          workspaceId: node.workspace_id,
          iconHint: "page",
        },
        iconHint: "page",
        node: {
          ...node,
          parent_id: parentNodeId,
          kernel: node.kernel
            ? {
                ...node.kernel,
                depth,
                position: node.kernel.position ?? node.sort_order ?? index,
                childCount,
              }
            : {
                nodeType: "page",
                depth,
                position: node.sort_order ?? index,
                childCount,
                expandedByDefault: true,
              },
        },
      });
      if (childCount > 0) {
        walk(node.children, depth + 1, node.id);
      }
    });
  };

  walk(nodes, 0, null);
  return items;
}

export function filterVisiblePageTreeProjectionItems(
  items: PageTreeProjectionItem[],
  expanded: Set<string>,
): PageTreeProjectionItem[] {
  const visible: PageTreeProjectionItem[] = [];
  const visibleIds = new Set<string>();

  items.forEach((item) => {
    if (!item.parentNodeId) {
      visible.push(item);
      visibleIds.add(item.nodeId);
      return;
    }

    if (!visibleIds.has(item.parentNodeId)) {
      return;
    }

    if (!expanded.has(item.parentNodeId)) {
      return;
    }

    visible.push(item);
    visibleIds.add(item.nodeId);
  });

  return visible;
}

export function buildPickerTreeItems(
  items: PageTreeProjectionItem[],
  excludeIds: Iterable<string> = [],
): PickerTreeItem[] {
  const excluded = new Set(excludeIds);
  return items
    .filter((item) => !excluded.has(item.nodeId))
    .map((item) => ({
      id: item.nodeId,
      title: item.title,
      depth: item.depth,
    }));
}
