import type { DiagramNode as DiagramNodeType } from '../../api/queries/diagrams';
import type { NodeConfig } from './types';
import type { NodeExecutionState } from '../ExecutionDiagram/types';
import { colorForType, iconForType } from './node-colors';
import { ConfigBadge } from './ConfigBadge';

const TOP_BAR_HEIGHT = 6;
const TEXT_LEFT = 32;
const TEXT_RIGHT_PAD = 24;
const CORNER_RADIUS = 4;

interface DiagramNodeProps {
  node: DiagramNodeType;
  isHovered: boolean;
  isSelected: boolean;
  config?: NodeConfig;
  executionState?: NodeExecutionState;
  overlayActive?: boolean;
  onClick: () => void;
  onDoubleClick?: () => void;
  onMouseEnter: () => void;
  onMouseLeave: () => void;
}

function formatDuration(ms: number): string {
  if (ms < 1000) return `${ms}ms`;
  return `${(ms / 1000).toFixed(1)}s`;
}

export function DiagramNode({
  node, isHovered, isSelected, config,
  executionState, overlayActive,
  onClick, onDoubleClick, onMouseEnter, onMouseLeave,
}: DiagramNodeProps) {
  const x = node.x ?? 0;
  const y = node.y ?? 0;
  const w = node.width ?? 120;
  const h = node.height ?? 40;
  const color = colorForType(node.type);
  const icon = iconForType(node.type);

  // Extract label parts: type name and detail
  const typeName = node.type?.replace(/^EIP_/, '').replace(/_/g, ' ') ?? '';
  const detail = node.label || '';

  // Overlay state derivation
  const isCompleted = executionState?.status === 'COMPLETED';
  const isFailed = executionState?.status === 'FAILED';
  const isSkipped = overlayActive && !executionState;

  // Colors based on execution state
  let cardFill = isHovered ? '#F5F0EA' : 'white';
  let borderStroke = isHovered || isSelected ? color : '#E4DFD8';
  let borderWidth = isHovered || isSelected ? 1.5 : 1;
  let topBarColor = color;
  let labelColor = '#1A1612';

  if (isCompleted) {
    cardFill = isHovered ? '#E4F5E6' : '#F0F9F1';
    borderStroke = '#3D7C47';
    borderWidth = 1.5;
    topBarColor = '#3D7C47';
  } else if (isFailed) {
    cardFill = isHovered ? '#F9E4E1' : '#FDF2F0';
    borderStroke = '#C0392B';
    borderWidth = 2;
    topBarColor = '#C0392B';
    labelColor = '#C0392B';
  }

  const statusColor = isCompleted ? '#3D7C47' : isFailed ? '#C0392B' : undefined;

  return (
    <g
      data-node-id={node.id}
      transform={`translate(${x}, ${y})`}
      onClick={(e) => { e.stopPropagation(); onClick(); }}
      onDoubleClick={(e) => { e.stopPropagation(); onDoubleClick?.(); }}
      onMouseEnter={onMouseEnter}
      onMouseLeave={onMouseLeave}
      style={{ cursor: 'pointer' }}
      opacity={isSkipped ? 0.35 : undefined}
    >
      {/* Selection ring */}
      {isSelected && (
        <rect
          x={-2}
          y={-2}
          width={w + 4}
          height={h + 4}
          rx={CORNER_RADIUS + 2}
          fill="none"
          stroke="#C6820E"
          strokeWidth={2.5}
        />
      )}

      {/* Card background */}
      <rect
        x={0}
        y={0}
        width={w}
        height={h}
        rx={CORNER_RADIUS}
        fill={cardFill}
        stroke={borderStroke}
        strokeWidth={borderWidth}
      />

      {/* Colored top bar */}
      <rect x={0} y={0} width={w} height={TOP_BAR_HEIGHT} rx={CORNER_RADIUS} fill={topBarColor} />
      <rect x={CORNER_RADIUS} y={0} width={w - CORNER_RADIUS * 2} height={TOP_BAR_HEIGHT} fill={topBarColor} />

      {/* Clip path for text area */}
      <clipPath id={`clip-${node.id}`}>
        <rect x={TEXT_LEFT} y={TOP_BAR_HEIGHT} width={w - TEXT_LEFT - TEXT_RIGHT_PAD} height={h - TOP_BAR_HEIGHT} />
      </clipPath>

      {/* Icon */}
      <text x={14} y={h / 2 + 4} fill={statusColor ?? color} fontSize={14}>
        {icon}
      </text>

      {/* Type name + detail (clipped to available width) */}
      <g clipPath={`url(#clip-${node.id})`}>
        <text x={TEXT_LEFT} y={h / 2 - 1} fill={labelColor} fontSize={11} fontWeight={600}>
          {typeName}
        </text>
        {detail && detail !== typeName && (
          <text x={TEXT_LEFT} y={h / 2 + 12} fill={isFailed ? '#C0392B' : '#5C5347'} fontSize={10}>
            {detail}
          </text>
        )}
      </g>

      {/* Config badges */}
      {config && <ConfigBadge nodeWidth={w} config={config} />}

      {/* Execution overlay: status badge inside card, top-right corner */}
      {isCompleted && (
        <>
          <circle cx={w - 10} cy={TOP_BAR_HEIGHT + 8} r={6} fill="#3D7C47" />
          <path
            d={`M${w - 13} ${TOP_BAR_HEIGHT + 8} l2 2 4-4`}
            fill="none" stroke="white" strokeWidth={1.5} strokeLinecap="round" strokeLinejoin="round"
          />
        </>
      )}
      {isFailed && (
        <>
          <circle cx={w - 10} cy={TOP_BAR_HEIGHT + 8} r={6} fill="#C0392B" />
          <path
            d={`M${w - 10} ${TOP_BAR_HEIGHT + 5} v4 M${w - 10} ${TOP_BAR_HEIGHT + 10.5} v0.5`}
            fill="none" stroke="white" strokeWidth={1.5} strokeLinecap="round"
          />
        </>
      )}

      {/* Execution overlay: duration text at bottom-right */}
      {executionState && statusColor && (
        <text
          x={w - 6}
          y={h - 4}
          textAnchor="end"
          fill={statusColor}
          fontSize={9}
          fontWeight={500}
        >
          {formatDuration(executionState.durationMs)}
        </text>
      )}

      {/* Sub-route failure: drill-down arrow at bottom-left */}
      {isFailed && executionState?.subRouteFailed && (
        <g transform={`translate(4, ${h - 14})`}>
          <path
            d="M2 2 v5 a3 3 0 003 3 h5"
            fill="none" stroke="#C0392B" strokeWidth={1.5} strokeLinecap="round" strokeLinejoin="round"
          />
          <path d="M8 8 l2 2 -2 2" fill="none" stroke="#C0392B" strokeWidth={1.5} strokeLinecap="round" strokeLinejoin="round" />
        </g>
      )}
    </g>
  );
}
