import { useMemo } from 'react';
import type { NodeExecutionState, IterationInfo, ProcessorNode } from './types';

/**
 * Recursively walks the ProcessorNode tree and populates an overlay map
 * keyed by processorId → NodeExecutionState.
 *
 * For iteration containers (nodes with iterationSize), only children
 * whose `iteration` matches the selected index are included.
 */
function buildOverlay(
  processors: ProcessorNode[],
  overlay: Map<string, NodeExecutionState>,
  iterationState: Map<string, IterationInfo>,
  parentId?: string,
): void {
  for (const proc of processors) {
    if (!proc.processorId) continue;

    // If this node's parent is an iteration container, filter by selected iteration
    if (parentId && iterationState.has(parentId)) {
      const info = iterationState.get(parentId)!;
      if (proc.iteration != null && proc.iteration !== info.current) {
        continue; // Different iteration than selected — skip this subtree
      }
    }

    // Regular processor: only include completed/failed nodes
    if (!proc.status || (proc.status !== 'COMPLETED' && proc.status !== 'FAILED')) continue;

    const subRouteFailed =
      proc.status === 'FAILED' &&
      (proc.processorType?.includes('DIRECT') || proc.processorType?.includes('SEDA'));

    overlay.set(proc.processorId, {
      status: proc.status as 'COMPLETED' | 'FAILED',
      durationMs: proc.durationMs ?? 0,
      subRouteFailed: subRouteFailed || undefined,
      hasTraceData: !!proc.hasTraceData,
      resolvedEndpointUri: proc.resolvedEndpointUri || undefined,
      filterMatched: proc.filterMatched ?? undefined,
      duplicateMessage: proc.duplicateMessage ?? undefined,
    });

    // Recurse into children
    if (proc.children?.length) {
      buildOverlay(proc.children, overlay, iterationState, proc.processorId);
    }
  }
}

/**
 * Maps execution data (processor tree) to diagram overlay state.
 *
 * Returns a Map<processorId, NodeExecutionState> that tells DiagramNode
 * and DiagramEdge how to render each element (success/failure colors,
 * traversed edges, etc.).
 */
export function useExecutionOverlay(
  processors: ProcessorNode[] | undefined,
  iterationState: Map<string, IterationInfo>,
): Map<string, NodeExecutionState> {
  return useMemo(() => {
    if (!processors) return new Map();
    const overlay = new Map<string, NodeExecutionState>();
    buildOverlay(processors, overlay, iterationState);
    return overlay;
  }, [processors, iterationState]);
}
