import type { OrgNode } from '@/types/org' export interface FlowNode { id: string type: 'orgNode' position: { x: number; y: number } data: { node: OrgNode level: number } } export interface FlowEdge { id: string source: string target: string sourceHandle?: string targetHandle?: string type: 'straight' | 'smoothstep' } export function generateNodeLayout(nodes: OrgNode[]): { nodes: FlowNode[]; edges: FlowEdge[] } { const flowNodes: FlowNode[] = [] const flowEdges: FlowEdge[] = [] let nodeCounter = 0 const levelPositions: Map = new Map() // Track position within each level function processNode( node: OrgNode, level: number, parentId: string | null, parentX: number = 400, parentY: number = 100 ): string { const nodeId = `node-${nodeCounter++}` // Hierarchical positioning: levels go top to bottom const yPosition = 100 + (level - 1) * 200 // 200px between levels // Get current position for this level let xPosition: number if (level === 1) { // Root nodes: center them horizontally const rootIndex = flowNodes.filter(n => n.data.level === 1).length const rootSpacing = 350 const totalRootWidth = (nodes.length - 1) * rootSpacing xPosition = 400 + rootIndex * rootSpacing - totalRootWidth / 2 } else { // Child nodes: position relative to parent const currentLevelCount = levelPositions.get(level) || 0 levelPositions.set(level, currentLevelCount + 1) // Calculate children positions spread around parent const parentNode = flowNodes.find(n => n.id === parentId) if (parentNode) { const siblingCount = node.children?.length || 1 const parentChildren = flowNodes.filter(n => flowEdges.some(e => e.source === parentId && e.target === n.id) ).length const childSpacing = Math.max(250, 400 / Math.max(siblingCount, 1)) const totalWidth = (siblingCount - 1) * childSpacing xPosition = parentX + (parentChildren * childSpacing) - (totalWidth / 2) } else { xPosition = parentX + (currentLevelCount * 300) } } flowNodes.push({ id: nodeId, type: 'orgNode', position: { x: xPosition, y: yPosition }, data: { node, level } }) // Add edge from parent - center to center diagonal if (parentId) { flowEdges.push({ id: `edge-${parentId}-${nodeId}`, source: parentId, target: nodeId, type: 'straight' }) } // Process children node.children.forEach((child, index) => { processNode(child, level + 1, nodeId, xPosition, yPosition) }) return nodeId } // Process all root nodes nodes.forEach((node, index) => { processNode(node, 1, null) }) return { nodes: flowNodes, edges: flowEdges } }