import { useCallback, useEffect, useState } from 'react';
import type { IterationInfo, ProcessorNode } from './types';

/** Map container processorType to iteration display type. */
function inferIterationType(processorType: string | undefined): IterationInfo['type'] {
  switch (processorType) {
    case 'loop': return 'loop';
    case 'multicast': return 'multicast';
    default: return 'split'; // split, recipientList, and any future iterating EIP
  }
}

/**
 * Walks the processor tree and detects iteration containers —
 * any node with a non-null iterationSize.
 */
function detectIterations(
  processors: ProcessorNode[],
  result: Map<string, IterationInfo>,
): void {
  for (const proc of processors) {
    if (!proc.processorId) continue;

    if (proc.iterationSize != null) {
      result.set(proc.processorId, {
        current: 0,
        total: proc.iterationSize,
        type: inferIterationType(proc.processorType),
      });
    }

    if (proc.children?.length) {
      detectIterations(proc.children, result);
    }
  }
}

/**
 * Manages per-compound iteration state for the execution overlay.
 *
 * Scans the processor tree to detect containers with iterationSize
 * and tracks which iteration index is currently selected.
 */
export function useIterationState(processors: ProcessorNode[] | undefined) {
  const [state, setState] = useState<Map<string, IterationInfo>>(new Map());

  useEffect(() => {
    if (!processors) return;
    const newState = new Map<string, IterationInfo>();
    detectIterations(processors, newState);
    setState(newState);
  }, [processors]);

  const setIteration = useCallback((compoundId: string, index: number) => {
    setState((prev) => {
      const next = new Map(prev);
      const info = next.get(compoundId);
      if (info && index >= 0 && index < info.total) {
        next.set(compoundId, { ...info, current: index });
      }
      return next;
    });
  }, []);

  return { iterationState: state, setIteration };
}
