import dagre from 'dagre'

interface NodeInfo {
  id: string
  label: string
}

interface EdgeInfo {
  source: string
  target: string
}

const NODE_W = 180
const NODE_H = 60
const POSITIONS_KEY = 'editor_positions'

export function loadSavedPositions(): Record<string, { x: number; y: number }> {
  try {
    return JSON.parse(localStorage.getItem(POSITIONS_KEY) || '{}')
  } catch { return {} }
}

export function savePosition(nodeId: string, x: number, y: number) {
  const saved = loadSavedPositions()
  saved[nodeId] = { x, y }
  localStorage.setItem(POSITIONS_KEY, JSON.stringify(saved))
}

export function computePositions(
  nodes: NodeInfo[],
  edges: EdgeInfo[],
  _startScene: string,
): Map<string, { x: number; y: number }> {
  const saved = loadSavedPositions()
  const result = new Map<string, { x: number; y: number }>()

  const unsaved: NodeInfo[] = []
  for (const n of nodes) {
    if (saved[n.id]) {
      result.set(n.id, saved[n.id])
    } else {
      unsaved.push(n)
    }
  }

  if (unsaved.length === 0) return result

  const g = new dagre.graphlib.Graph()
  g.setGraph({
    rankdir: 'LR',
    nodesep: 100,
    ranksep: 200,
    marginx: 60,
    marginy: 60,
  })
  g.setDefaultEdgeLabel(() => ({}))

  for (const n of unsaved) {
    g.setNode(n.id, { width: NODE_W, height: NODE_H })
  }

  const nodeIds = new Set(unsaved.map((n) => n.id))
  for (const e of edges) {
    if (nodeIds.has(e.source) && nodeIds.has(e.target)) {
      g.setEdge(e.source, e.target)
    }
  }

  dagre.layout(g)

  for (const n of unsaved) {
    const node = g.node(n.id)
    if (node) {
      result.set(n.id, { x: node.x - NODE_W / 2, y: node.y - NODE_H / 2 })
    }
  }

  return result
}
