/**
 * Automation2 Flow Editor - Data flow context for Data Picker and DynamicValueField.
 * Extended with portTypeCatalog and systemVariables for the Typed Port System.
 */

import React, { createContext, useContext, useMemo } from 'react';
import type { CanvasNode, CanvasConnection } from '../editor/FlowCanvas';
import { getAvailableSources } from '../nodes/shared/dataFlowGraph';
import type { NodeType, PortSchema, SystemVariable } from '../../../api/workflowApi';

export interface Automation2DataFlowContextValue {
  currentNodeId: string;
  nodes: CanvasNode[];
  connections: CanvasConnection[];
  nodeOutputsPreview: Record<string, unknown>;
  nodeTypes: NodeType[];
  language: string;
  portTypeCatalog: Record<string, PortSchema>;
  systemVariables: Record<string, SystemVariable>;
  getNodeLabel: (node: { id: string; title?: string; label?: string; type?: string }) => string;
  getAvailableSourceIds: () => string[];
}

const Automation2DataFlowContext = createContext<Automation2DataFlowContextValue | null>(null);

export function useAutomation2DataFlow(): Automation2DataFlowContextValue | null {
  return useContext(Automation2DataFlowContext);
}

interface Automation2DataFlowProviderProps {
  node: CanvasNode | null;
  nodes: CanvasNode[];
  connections: CanvasConnection[];
  nodeOutputsPreview: Record<string, unknown>;
  nodeTypes: NodeType[];
  language: string;
  portTypeCatalog?: Record<string, PortSchema>;
  systemVariables?: Record<string, SystemVariable>;
  children: React.ReactNode;
}

export const Automation2DataFlowProvider: React.FC<Automation2DataFlowProviderProps> = ({
  node,
  nodes,
  connections,
  nodeOutputsPreview,
  nodeTypes,
  language,
  portTypeCatalog = {},
  systemVariables = {},
  children,
}) => {
  const value = useMemo((): Automation2DataFlowContextValue | null => {
    if (!node) return null;
    return {
      currentNodeId: node.id,
      nodes,
      connections,
      nodeOutputsPreview,
      nodeTypes,
      language,
      portTypeCatalog,
      systemVariables,
      getNodeLabel: (n: { id: string; title?: string; label?: string; type?: string }) =>
        n.title ?? n.label ?? n.type ?? n.id,
      getAvailableSourceIds: () => getAvailableSources(node.id, nodes, connections),
    };
  }, [node?.id, nodes, connections, nodeOutputsPreview, nodeTypes, language, portTypeCatalog, systemVariables]);

  return (
    <Automation2DataFlowContext.Provider value={value}>
      {children}
    </Automation2DataFlowContext.Provider>
  );
};
