/**
 * Automation2 Flow Editor - Graph conversion utilities
 * Converts between API graph format and canvas internal format.
 */

import type {
  NodeType,
  Automation2Graph,
  Automation2GraphNode,
  Automation2Connection,
} from '../../../../api/workflowApi';
import type { CanvasNode, CanvasConnection } from '../../editor/FlowCanvas';

export function fromApiGraph(
  graph: Automation2Graph,
  nodeTypes: NodeType[]
): { nodes: CanvasNode[]; connections: CanvasConnection[] } {
  const nodeMap = new Map<string, { inputs: number; outputs: number }>();
  nodeTypes.forEach((nt) => {
    nodeMap.set(nt.id, { inputs: nt.inputs ?? 1, outputs: nt.outputs ?? 1 });
  });

  const nodes: CanvasNode[] = (graph.nodes || []).map((n: Automation2GraphNode) => {
    const io = nodeMap.get(n.type) ?? { inputs: 1, outputs: 1 };
    let outputs = io.outputs;
    if (n.type === 'flow.switch') {
      const cases = (n.parameters?.cases as unknown[]) ?? [];
      outputs = Math.max(1, cases.length);
    }
    const nt = nodeTypes.find((t) => t.id === n.type);
    return {
      id: n.id,
      type: n.type,
      x: (n as { x?: number }).x ?? 0,
      y: (n as { y?: number }).y ?? 0,
      title: (n as { title?: string }).title ?? (typeof n.type === 'string' ? n.type : ''),
      comment: (n as { comment?: string }).comment,
      inputs: io.inputs,
      outputs,
      parameters: n.parameters ?? {},
      inputPorts: nt?.inputPorts
        ? Object.entries(nt.inputPorts).map(([, v]) => ({ name: '', schema: '', accepts: (v as { accepts?: string[] }).accepts }))
        : undefined,
      outputPorts: nt?.outputPorts
        ? Object.entries(nt.outputPorts).map(([, v]) => ({ name: '', schema: (v as { schema?: string }).schema ?? '' }))
        : undefined,
    };
  });

  const connId = (s: string, t: string, so: number, ti: number) => `c_${s}_${so}_${t}_${ti}`;
  const connections: CanvasConnection[] = (graph.connections || []).map((c: Automation2Connection) => {
    const srcNode = nodes.find((n) => n.id === c.source);
    const sourceOutput = c.sourceOutput ?? 0;
    const sourceHandle = srcNode ? srcNode.inputs + sourceOutput : 0;
    return {
      id: connId(c.source, c.target, sourceOutput, c.targetInput ?? 0),
      sourceId: c.source,
      sourceHandle,
      targetId: c.target,
      targetHandle: c.targetInput ?? 0,
    };
  });

  return { nodes, connections };
}

export function toApiGraph(
  nodes: CanvasNode[],
  connections: CanvasConnection[]
): Automation2Graph {
  const nodeMap = new Map(nodes.map((n) => [n.id, n]));
  return {
    nodes: nodes.map((n) => ({
      id: n.id,
      type: n.type,
      x: n.x,
      y: n.y,
      title: n.title,
      comment: n.comment,
      parameters: n.parameters ?? {},
      inputPorts: n.inputPorts,
      outputPorts: n.outputPorts,
    })),
    connections: connections.map((c) => {
      const srcNode = nodeMap.get(c.sourceId);
      const sourceOutput =
        srcNode && c.sourceHandle >= srcNode.inputs ? c.sourceHandle - srcNode.inputs : 0;
      return {
        source: c.sourceId,
        target: c.targetId,
        sourceOutput,
        targetInput: c.targetHandle,
      };
    }),
  };
}
