import type { Graph } from '@api-client/graph/graph/Graph.js'
import type { DomainGraphEdge, DomainGraphNodeType } from './types.js'
import { DomainAssociationKind } from '../models/kinds.js'

/**
 * Recursively removes a node and all its children from the graph.
 * @param key The key of the node to remove.
 */
export function removeGraphNode(graph: Graph<unknown, DomainGraphNodeType, DomainGraphEdge>, key: string): void {
  if (!graph.hasNode(key)) {
    return
  }
  const node = graph.node(key)
  if (!node) {
    return
  }
  if (node.kind === DomainAssociationKind) {
    // If the node is an association, remove the association from the graph,
    // but do not follow its children, as it would remove entities associated with it.
    graph.removeNode(key)
    return
  }
  for (const child of graph.children(key)) {
    removeGraphNode(graph, child)
  }
  // Remove all edges from the node.
  for (const edge of graph.outEdges(key)) {
    const label = graph.edge(edge)
    if (!label) {
      continue
    }
    if (label.type === 'association') {
      removeGraphNode(graph, edge.w)
    } else if (label.type === 'property') {
      removeGraphNode(graph, edge.w)
    }
  }
  graph.removeNode(key)
}
