import type { Edge } from '@xyflow/react';

/**
 * Analyzes edges connected to a deleted node and determines if reconnection is possible.
 *
 * Reconnection is only performed for the simple linear case:
 * - Exactly 1 incoming edge (predecessor → deleted node)
 * - Exactly 1 outgoing edge (deleted node → successor)
 *
 * For branching workflows (multiple edges), returns null to avoid incorrect connections.
 *
 * @param deletedNodeId - ID of the node being deleted
 * @param edges - Current array of edges
 * @returns New edge connecting predecessor to successor, or null if reconnection not applicable
 */
export function getReconnectionEdge(deletedNodeId: string, edges: Edge[]): Edge | null {
  // Find edges connected to the deleted node
  const incomingEdges = edges.filter((edge) => edge.target === deletedNodeId);
  const outgoingEdges = edges.filter((edge) => edge.source === deletedNodeId);

  // Only reconnect for simple linear case (exactly 1 in, 1 out)
  if (incomingEdges.length !== 1 || outgoingEdges.length !== 1) {
    return null;
  }

  const predecessor = incomingEdges[0].source;
  const successor = outgoingEdges[0].target;

  // Create reconnection edge
  return {
    id: `${predecessor}-${successor}`,
    source: predecessor,
    target: successor,
    type: 'smoothstep',
  };
}

/**
 * Removes edges connected to a deleted node and adds a reconnection edge if applicable.
 *
 * This is the main function used during node deletion to update the edge array.
 *
 * @param deletedNodeId - ID of the node being deleted
 * @param edges - Current array of edges
 * @returns Updated array of edges with reconnection applied
 */
export function reconnectEdgesAfterDeletion(deletedNodeId: string, edges: Edge[]): Edge[] {
  // Get reconnection edge (if applicable)
  const reconnectionEdge = getReconnectionEdge(deletedNodeId, edges);

  // Remove all edges connected to the deleted node
  const filteredEdges = edges.filter(
    (edge) => edge.source !== deletedNodeId && edge.target !== deletedNodeId,
  );

  // Add reconnection edge if we have one
  if (reconnectionEdge) {
    return [...filteredEdges, reconnectionEdge];
  }

  return filteredEdges;
}
