"use client";

import type { KernelFileTreeProjectionItem } from "@/lib/kernel-file-tree";
import {
  getDocIdFromFileTreeItem,
  resolveFileTreeRowAsset,
  resolveFileTreeRowNode,
} from "@/lib/kernel-file-tree";
import type { SidebarTreeNode } from "@/lib/kernel-sidebar";
import type { PageTreeProjectionItem } from "@/lib/tree-projection";
import type { MediaAsset } from "@/types/media";
import type { FileTreeRow } from "./types";
import { makeAssetFolderRowId, makeAssetRowId, makeDocRowId, makeIndexRowId } from "./types";

function buildRowsFromKernelFileTreeProjection(input: {
  fileTreeItems: KernelFileTreeProjectionItem[];
  expanded: Set<string>;
  expandedAssetFolderIds?: Set<string>;
  nodeById?: Map<string, SidebarTreeNode>;
  assetById?: Map<string, MediaAsset>;
}): FileTreeRow[] {
  const rows: FileTreeRow[] = [];
  const seen = new Set<string>();

  input.fileTreeItems.forEach((item) => {
    if (!item?.rowId || seen.has(item.rowId)) {
      return;
    }
    seen.add(item.rowId);
    const docId = getDocIdFromFileTreeItem(item);

    switch (item.rowKind) {
      case "document": {
        const node = resolveFileTreeRowNode(item, input.nodeById);
        rows.push({
          kind: "doc",
          rowId: makeDocRowId(docId),
          depth: item.depth,
          docId,
          parentDocId: item.parentNodeId,
          node,
          hasChildren: item.childCount > 0,
          isExpanded: input.expanded.has(docId),
        });
        return;
      }
      case "index": {
        const node = resolveFileTreeRowNode(item, input.nodeById);
        rows.push({
          kind: "index",
          rowId: makeIndexRowId(docId),
          depth: item.depth,
          docId,
          parentDocId: docId,
          node,
        });
        return;
      }
      case "asset_folder": {
        const asset = resolveFileTreeRowAsset(item, input.assetById);
        rows.push({
          kind: "asset-folder",
          rowId: makeAssetFolderRowId(asset.id),
          depth: item.depth,
          docId,
          parentDocId: docId,
          asset,
          hasChildren: item.childCount > 0,
          isExpanded: input.expandedAssetFolderIds?.has(asset.id) ?? false,
        });
        return;
      }
      case "asset": {
        const asset = resolveFileTreeRowAsset(item, input.assetById);
        rows.push({
          kind: "asset",
          rowId: makeAssetRowId(asset.id),
          depth: item.depth,
          docId,
          parentDocId: docId,
          asset,
        });
        return;
      }
    }
  });

  return rows;
}

export function buildVisibleRows({
  fileTreeItems,
  pageRows,
  expanded,
  assetsByDoc,
  assetChildrenByAssetId,
  expandedAssetFolderIds,
  nodeById,
  assetById,
}: {
  fileTreeItems?: KernelFileTreeProjectionItem[];
  // 只消费统一 page_tree projection；结构真相不再由文件树自行定义。
  pageRows?: PageTreeProjectionItem[];
  expanded: Set<string>;
  assetsByDoc?: Record<string, MediaAsset[]>;
  assetChildrenByAssetId?: Record<string, MediaAsset[]>;
  expandedAssetFolderIds?: Set<string>;
  nodeById?: Map<string, SidebarTreeNode>;
  assetById?: Map<string, MediaAsset>;
}): FileTreeRow[] {
  if (fileTreeItems && fileTreeItems.length > 0) {
    return buildRowsFromKernelFileTreeProjection({
      fileTreeItems,
      expanded,
      expandedAssetFolderIds,
      nodeById,
      assetById,
    });
  }

  const safePageRows = pageRows ?? [];
  const safeAssetsByDoc = assetsByDoc ?? {};
  const rows: FileTreeRow[] = [];

  safePageRows.forEach((item) => {
    const assets = safeAssetsByDoc[item.nodeId] ?? [];
    const hasChildren = item.childCount > 0 || assets.length > 0;
    const isExpanded = expanded.has(item.nodeId);
    rows.push({
      kind: "doc",
      rowId: makeDocRowId(item.nodeId),
      depth: item.depth,
      docId: item.nodeId,
      parentDocId: item.parentNodeId,
      node: item.node,
      hasChildren,
      isExpanded,
    });

    if (!isExpanded) {
      return;
    }

    rows.push({
      kind: "index",
      rowId: makeIndexRowId(item.nodeId),
      depth: item.depth + 1,
      docId: item.nodeId,
      parentDocId: item.nodeId,
      node: item.node,
    });

    assets.forEach((asset) => {
      if (asset.asset_type === "mindmap") {
        const children = assetChildrenByAssetId?.[asset.id] ?? [];
        const hasChildren = children.length > 0;
        const isExpanded = expandedAssetFolderIds?.has(asset.id) ?? false;
        rows.push({
          kind: "asset-folder",
          rowId: makeAssetFolderRowId(asset.id),
          depth: item.depth + 1,
          docId: item.nodeId,
          parentDocId: item.nodeId,
          asset,
          hasChildren,
          isExpanded,
        });
        if (hasChildren && isExpanded) {
          children.forEach((child) => {
            rows.push({
              kind: "asset",
              rowId: makeAssetRowId(child.id),
              depth: item.depth + 2,
              docId: item.nodeId,
              parentDocId: item.nodeId,
              asset: child,
            });
          });
        }
        return;
      }

      rows.push({
        kind: "asset",
        rowId: makeAssetRowId(asset.id),
        depth: item.depth + 1,
        docId: item.nodeId,
        parentDocId: item.nodeId,
        asset,
      });
    });
  });
  return rows;
}
