'use client';

import { useCallback, useRef } from 'react';
import { useControlMode, genNodeId, CTRL_NODE_TYPES } from './hooks/useControlMode';
import { usePortDrag } from './hooks/usePortDrag';
import { ControlNode } from './ControlNode';
import { TableNode } from './TableNode';
import { PortHandle } from './PortHandle';
import { NodeConfigPopover } from './NodeConfigPopover';
import { bezierPath } from './ConnectionLine';
import { getMetaFields } from '@/lib/api/meta';
import type { FieldConfig } from '@/types/invyone-component';

interface RuleBuilderProps {
  canvasRef: React.RefObject<HTMLDivElement | null>;
}

/** 테이블 필드 캐시 */
const fieldCache: Record<string, FieldConfig[]> = {};

/**
 * 규칙 빌더 — 편집 모드
 * mockup initRuleBuilder/dropTable/dropControl 포팅
 */
export function RuleBuilder({ canvasRef }: RuleBuilderProps) {
  const {
    ruleNodes,
    ruleConnections,
    addRuleNode,
    moveRuleNode,
  } = useControlMode();

  const { startDrag, finishDrag } = usePortDrag(canvasRef);

  // 캔버스 드롭 처리
  const handleDrop = useCallback(async (e: React.DragEvent) => {
    e.preventDefault();
    let d: Record<string, any>;
    try { d = JSON.parse(e.dataTransfer.getData('text/plain')); } catch { return; }
    if (!d?.kind) return;

    const cv = canvasRef.current;
    if (!cv) return;
    const r = cv.getBoundingClientRect();
    const x = e.clientX - r.left + cv.scrollLeft;
    const y = e.clientY - r.top + cv.scrollTop;

    if (d.kind === 'table') {
      // 중복 방지
      if (ruleNodes.find((n) => n.type === 'table' && n.table_name === d.name)) return;

      // 필드 로드
      let cols: FieldConfig[] = [];
      if (fieldCache[d.name]) {
        cols = fieldCache[d.name];
      } else {
        try {
          const meta = await getMetaFields(d.name);
          cols = (meta.fields ?? []).filter((f: FieldConfig) => !f.system);  // 모든 컬럼 로드 (Phase 2 dropdown 용)
          fieldCache[d.name] = cols;
        } catch { /* 빈 필드 */ }
      }

      addRuleNode({
        id: genNodeId('tbl'),
        type: 'table',
        table_name: d.name,
        label: d.name,
        x: x - 100,
        y: y - 40,
        columns: cols,
      });
    } else if (d.kind === 'control' && CTRL_NODE_TYPES[d.type]) {
      addRuleNode({
        id: genNodeId('ctrl'),
        type: d.type,
        label: CTRL_NODE_TYPES[d.type].label,
        x: x - 80,
        y: y - 30,
        config: {},
      });
    }
  }, [canvasRef, ruleNodes, addRuleNode]);

  const handleDragOver = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    e.dataTransfer.dropEffect = 'copy';
  }, []);

  // 노드 좌표에서 포트 위치 계산
  // dir: 'from' (출력측, 우측) | 'to' (입력측, 좌측) — 컬럼별 port 의 좌/우 결정용
  const portPos = useCallback((nodeId: string, port: string, dir: 'from' | 'to' = 'from') => {
    const node = ruleNodes.find((n) => n.id === nodeId);
    if (!node) return null;

    if (node.type === 'table') {
      // 테이블 단위 단일 port — 카드 좌측(in) / 우측(out) 중앙
      // (Phase 1: 컬럼별 port 폐기. 컬럼 선택은 NodeConfigPopover dropdown 에서)
      void dir;
      const cardW = 180;
      const cardH = 70;  // stripe + head + stats
      const yMid = node.y + cardH / 2;
      if (port === 'in') return { x: node.x, y: yMid };
      return { x: node.x + cardW, y: yMid };
    }

    // 제어 노드
    if (port === 'in') return { x: node.x, y: node.y + 40 };

    // output 포트 — 타입별 위치
    const def = CTRL_NODE_TYPES[node.type];
    const outPorts = def?.out || [{ port: 'out', label: '→', cls: '' }];
    const idx = outPorts.findIndex((p) => p.port === port);
    const total = outPorts.length;
    const nodeH = 80;
    const centerY = node.y + nodeH / 2;
    const gap = 8;
    const startY = centerY - ((total - 1) * gap) / 2;

    return { x: node.x + 160, y: startY + idx * gap };
  }, [ruleNodes]);

  return (
    <div
      className="rule-builder-canvas"
      style={{ position: 'absolute', inset: 0, pointerEvents: 'auto' }}
      onDrop={handleDrop}
      onDragOver={handleDragOver}
    >
      {/* 연결선 SVG */}
      <svg className="ctrl-svg" id="rule-svg" width="100%" height="100%" style={{ overflow: 'visible' }}>
        <defs>
          <marker id="arr-rule" markerWidth="8" markerHeight="6" refX="8" refY="3" orient="auto">
            <polygon points="0 0,8 3,0 6" fill="var(--ctrl-cyan)" opacity=".8" />
          </marker>
          <marker id="arr-yes" markerWidth="8" markerHeight="6" refX="8" refY="3" orient="auto">
            <polygon points="0 0,8 3,0 6" fill="var(--ctrl-green)" opacity=".8" />
          </marker>
          <marker id="arr-no" markerWidth="8" markerHeight="6" refX="8" refY="3" orient="auto">
            <polygon points="0 0,8 3,0 6" fill="var(--v5-text-muted, #888)" opacity=".5" />
          </marker>
        </defs>

        {ruleConnections.map((c) => {
          const f = portPos(c.from_node_id, c.from_port, 'from');
          const t = portPos(c.to_node_id, c.to_port, 'to');
          if (!f || !t) return null;

          // Phase 3: edge_type 별 stroke 분기 (yes/no 우선, 그 다음 edge_type)
          const portCls = c.from_port === 'yes' ? 'conn-yes'
                        : c.from_port === 'no'  ? 'conn-no'  : '';
          const edgeCls = c.edge_type ? `edge-${c.edge_type}` : '';
          const cls = ['rule-conn-path', portCls, edgeCls].filter(Boolean).join(' ');

          // 선 중간 라벨 — yes/no 같은 분기 + edge_type 시각화 (mockup v3 EditCanvas style)
          const portLabel =
            c.label ??
            (c.from_port === 'yes'      ? '예'
            : c.from_port === 'no'      ? '아니오'
            : c.from_port === 'pass'    ? '통과'
            : c.from_port === 'fail'    ? '실패'
            : c.from_port === 'approved'? '승인'
            : c.from_port === 'rejected'? '반려'
            : c.from_port === 'each'    ? '반복'
            : c.from_port === 'done'    ? '완료'
            : null);
          const labelColor = c.from_port === 'yes'      ? 'var(--ctrl-green)'
                           : c.from_port === 'no'       ? 'var(--v5-text-muted, #888)'
                           : c.from_port === 'pass'     ? 'var(--ctrl-green)'
                           : c.from_port === 'fail'     ? 'rgb(255, 71, 87)'
                           : c.from_port === 'approved' ? 'var(--ctrl-green)'
                           : c.from_port === 'rejected' ? 'var(--v5-text-muted, #888)'
                           : c.edge_type === 'table-mutation' ? 'rgb(253, 121, 168)'
                           : c.edge_type === 'execution-flow' ? 'var(--ctrl-primary)'
                           : c.edge_type === 'lookup'         ? 'var(--ctrl-green)'
                           : 'var(--ctrl-cyan)';
          const mx = (f.x + t.x) / 2;
          const my = (f.y + t.y) / 2;
          const labelW = Math.max(36, (portLabel?.length ?? 0) * 8 + 14);

          return (
            <g key={c.id}>
              <path d={bezierPath(f.x, f.y, t.x, t.y)} className={cls} />
              {portLabel && (
                <g transform={`translate(${mx}, ${my - 11})`}>
                  <rect
                    x={-labelW / 2} y={-9}
                    width={labelW} height={18} rx={4}
                    fill="var(--v5-surface-solid)"
                    stroke={labelColor}
                    strokeWidth={1}
                    opacity={0.95}
                  />
                  <text
                    y={4}
                    textAnchor="middle"
                    fontSize={10}
                    fontWeight={700}
                    fill={labelColor}
                    fontFamily="var(--v5-font-mono)"
                  >
                    {portLabel}
                  </text>
                </g>
              )}
            </g>
          );
        })}
      </svg>

      {/* 연결 삭제 뱃지 */}
      {ruleConnections.map((c) => {
        const f = portPos(c.from_node_id, c.from_port, 'from');
        const t = portPos(c.to_node_id, c.to_port, 'to');
        if (!f || !t) return null;
        const mx = (f.x + t.x) / 2, my = (f.y + t.y) / 2;

        return (
          <div
            key={`badge-${c.id}`}
            className="rule-conn-badge"
            style={{ left: mx, top: my }}
          >
            <span
              className="conn-x"
              onClick={(e) => {
                e.stopPropagation();
                useControlMode.getState().removeRuleConnection(c.id);
              }}
            >
              ✕
            </span>
          </div>
        );
      })}

      {/* 노드 렌더 */}
      {ruleNodes.map((node) => {
        if (node.type === 'table') {
          return (
            <div key={node.id} style={{ position: 'absolute', left: 0, top: 0 }}>
              <TableNode
                tableName={node.table_name}
                label={node.label}
                icon="🏢"
                columns={node.columns ?? []}
                x={node.x}
                y={node.y}
                onMove={(_, x, y) => moveRuleNode(node.id, x, y)}
                style={{ overflow: 'visible' }}
                nodeId={node.id}
                onPortDragStart={startDrag}
                onPortDragEnd={finishDrag}
              />
            </div>
          );
        }

        return (
          <ControlNode
            key={node.id}
            node={node}
            onDragStart={startDrag}
            onDragEnd={finishDrag}
          />
        );
      })}

      {/* 설정 팝오버 */}
      <NodeConfigPopover />
    </div>
  );
}
