'use client';

/**
 * V3RuleNode — v3 시안 v3-canvas.jsx 의 V3RuleNode 정확 포팅
 * cat-color stripe + validation dot + comment avatar + cat-chip header + label + summary + stats + ports
 */

import { CTRL_NODE_TYPES } from '../hooks/useControlMode';
import { getNodeIcon } from '../schemas';
import type { NodeStats, NodeComment } from '@/lib/api/control';

interface V3RuleNodeProps {
  node: Record<string, any> & { cx: number; cy: number };
  scale: number;
  selected: boolean;
  dim: boolean;
  stats?: NodeStats;
  comments?: NodeComment[];
  onSelect: () => void;
  onDrag: (dx: number, dy: number) => void;
  onContextMenu: (canvasX: number, canvasY: number) => void;
}

export function V3RuleNode({
  node, scale, selected, dim, stats, comments,
  onSelect, onDrag, onContextMenu,
}: V3RuleNodeProps) {
  const def = CTRL_NODE_TYPES[node.type];
  if (!def) return null;
  const rgb = def.rgb;
  const Ic = getNodeIcon(node.type);

  // Pointer Events + setPointerCapture — transform/scale 안에서도 mouse 이벤트 안정적으로 받음
  const onPointerDown = (e: React.PointerEvent) => {
    if (e.button !== 0) return;
    if ((e.target as HTMLElement).closest('button, input, select, textarea')) return;
    e.stopPropagation();
    const el = e.currentTarget as HTMLDivElement;
    const pointerId = e.pointerId;
    try { el.setPointerCapture(pointerId); } catch { /* unsupported */ }
    const start = { x: e.clientX, y: e.clientY };
    let moved = false;
    const onMove = (ev: Event) => {
      const pe = ev as PointerEvent;
      const dx = (pe.clientX - start.x) / (scale || 1);
      const dy = (pe.clientY - start.y) / (scale || 1);
      if (!moved && Math.abs(dx) + Math.abs(dy) < 2) return;
      moved = true;
      onDrag(dx, dy);
      start.x = pe.clientX;
      start.y = pe.clientY;
    };
    const onUp = () => {
      try { el.releasePointerCapture(pointerId); } catch { /* */ }
      el.removeEventListener('pointermove', onMove);
      el.removeEventListener('pointerup', onUp);
      el.removeEventListener('pointercancel', onUp);
      if (!moved) onSelect();
    };
    el.addEventListener('pointermove', onMove);
    el.addEventListener('pointerup', onUp);
    el.addEventListener('pointercancel', onUp);
  };

  const onCtx = (e: React.MouseEvent) => {
    e.preventDefault();
    e.stopPropagation();
    onContextMenu(node.cx, node.cy + 70);
  };

  const lastMs = stats?.lastMs ?? null;
  const latColor =
    lastMs == null ? undefined :
    lastMs < 30   ? 'var(--v5-green)' :
    lastMs < 100  ? 'var(--v5-text-sec)' :
                    'var(--v5-amber)';
  const summary = node.summary?.[0]
    ?? (node.config ? Object.entries(node.config).slice(0, 1).map(([k, v]) => `${k}: ${v}`)[0] : null);
  const firstComment = comments?.[0];

  return (
    <div
      data-pz-node="true"
      draggable={false}
      className={`v3-rule-node${selected ? ' is-selected' : ''}${dim ? ' is-dim' : ''}`}
      onPointerDown={onPointerDown}
      onContextMenu={onCtx}
      style={{
        left: node.cx, top: node.cy,
        borderColor: `rgba(${rgb}, ${selected ? 0.85 : 0.4})`,
        boxShadow: selected
          ? `0 0 0 4px rgba(${rgb}, .14), 0 0 24px rgba(${rgb}, .22)`
          : '0 4px 12px -4px rgba(0, 0, 0, .08)',
        touchAction: 'none',
      }}
    >
      {/* cat-color stripe */}
      <div className="v3-rule-node-stripe" style={{ background: `rgb(${rgb})` }} />

      {/* validation dot */}
      {stats && (
        <span
          className="v3-rule-node-vdot"
          style={{
            background: stats.valid
              ? (stats.alert ? 'var(--v5-amber)' : 'var(--v5-green)')
              : 'var(--v5-red)',
            boxShadow: stats.valid
              ? (stats.alert ? '0 0 5px var(--v5-amber)' : '0 0 5px var(--v5-green)')
              : '0 0 5px var(--v5-red)',
          }}
          title={stats.alert || (stats.valid ? '정상' : '검증 실패')}
        />
      )}

      {/* comment avatar */}
      {firstComment && (
        <span
          className="v3-rule-node-comment"
          title={firstComment.text}
          style={{ background: `rgb(${firstComment.color})` }}
        >
          {firstComment.short}
        </span>
      )}

      {/* body */}
      <div className="v3-rule-node-body">
        <div className="v3-rule-node-cat">
          <div
            className="v3-rule-node-cat-ico"
            style={{ background: `rgba(${rgb}, .14)`, color: `rgb(${rgb})` }}
          >
            <Ic size={11} />
          </div>
          <span className="v3-rule-node-cat-label" style={{ color: `rgb(${rgb})` }}>
            {def.label}
          </span>
        </div>
        <div className="v3-rule-node-label">{node.label ?? def.label}</div>
        {summary && <div className="v3-rule-node-summary">{summary}</div>}
        {stats && (
          <div className="v3-rule-node-stats">
            <span>{stats.runs.toLocaleString()} runs</span>
            {lastMs != null && (
              <span style={{ fontWeight: 700, color: latColor }}>{lastMs}ms</span>
            )}
          </div>
        )}
      </div>

      {/* ports */}
      <div className="v3-rule-node-port v3-rule-node-port-in"
        style={{ borderColor: `rgb(${rgb})` }} />
      <div className="v3-rule-node-port v3-rule-node-port-out"
        style={{ background: `rgb(${rgb})` }} />
    </div>
  );
}
