import {
  CalendarClock,
  CheckCircle2,
  CirclePlay,
  CircleX,
  ClipboardCheck,
  GitFork,
  PlugZap,
  Radio,
  Split,
  SquareCheckBig,
  Timer,
  Waypoints,
  type LucideIcon
} from "lucide-react";
import {
  Handle,
  Position,
  type Node,
  type NodeProps
} from "@xyflow/react";
import type { WorkflowNodeType } from "../../api/workflow";

export type WorkflowFlowNodeData = {
  label: string;
  workflowType: string;
  definition: WorkflowNodeType;
  hasError: boolean;
};

export type WorkflowFlowNode = Node<WorkflowFlowNodeData, "workflow">;

const iconByName: Record<string, LucideIcon> = {
  "calendar-clock": CalendarClock,
  "circle-check-big": CheckCircle2,
  "circle-play": CirclePlay,
  "circle-x": CircleX,
  "clipboard-check": ClipboardCheck,
  "plug-zap": PlugZap,
  radio: Radio,
  split: Split,
  "square-check-big": SquareCheckBig,
  timer: Timer,
  waypoints: Waypoints
};

export default function WorkflowNode({
  data,
  selected,
  isConnectable
}: NodeProps<WorkflowFlowNode>) {
  const Icon = iconByName[data.definition.icon] ?? GitFork;
  const inputPorts = data.definition.input_ports;
  const outputPorts = data.definition.output_ports;
  return (
    <div
      className={[
        "workflow-node",
        `workflow-node-${data.definition.category}`,
        selected ? "is-selected" : "",
        data.hasError ? "has-error" : ""
      ].filter(Boolean).join(" ")}
    >
      {inputPorts.map((port, index) => (
        <Handle
          key={port.id}
          id={port.id}
          type="target"
          position={Position.Left}
          className="workflow-node-handle"
          style={{ top: portPosition(index, inputPorts.length) }}
          isConnectable={isConnectable}
          title={port.label}
        />
      ))}
      <span className="workflow-node-icon"><Icon size={17} /></span>
      <span className="workflow-node-copy">
        <strong>{data.label}</strong>
        <small>{data.definition.label}</small>
      </span>
      {outputPorts.map((port, index) => (
        <Handle
          key={port.id}
          id={port.id}
          type="source"
          position={Position.Right}
          className="workflow-node-handle"
          style={{ top: portPosition(index, outputPorts.length) }}
          isConnectable={isConnectable}
          title={port.label}
        />
      ))}
    </div>
  );
}

function portPosition(index: number, count: number): string {
  return `${((index + 1) / (count + 1)) * 100}%`;
}
