import dagre from '@dagrejs/dagre'
import { Edge, Node, Position } from '@xyflow/react'

import { NODE_WIDTH } from './Nodes'

const NODE_SEP = 0
const NODE_ROW_HEIGHT = 200

export const getDagreGraphLayout = (nodes: Node[], edges: Edge[]) => {
  const dagreGraph = new dagre.graphlib.Graph()
  dagreGraph.setDefaultEdgeLabel(() => ({}))
  dagreGraph.setGraph({
    rankdir: 'LR',
    ranksep: 200,
    nodesep: NODE_SEP,
    align: nodes.length <= 2 ? 'UL' : undefined,
  })

  nodes.forEach((node) => {
    dagreGraph.setNode(node.id, {
      width: NODE_WIDTH / 2,
      height: NODE_ROW_HEIGHT / 2,
    })
  })

  edges.forEach((edge) => dagreGraph.setEdge(edge.source, edge.target))

  dagre.layout(dagreGraph)

  nodes.forEach((node) => {
    const nodeWithPosition = dagreGraph.node(node.id)
    node.sourcePosition = Position.Right
    node.targetPosition = Position.Left
    // We are shifting the dagre node position (anchor=center center) to the top left
    // so it matches the React Flow node anchor point (top left).
    node.position = {
      x: nodeWithPosition.x - nodeWithPosition.width / 2,
      y: nodeWithPosition.y - nodeWithPosition.height / 2,
    }

    return node
  })

  return { nodes, edges }
}
