"use client";

import React, { useMemo, useState, useEffect } from "react";
import { Handle, Position } from "@xyflow/react";
import {
  Monitor,
  Database,
  FormInput,
  Table2,
  LayoutDashboard,
  MousePointer2,
  Key,
  Link2,
} from "lucide-react";
import { ScreenLayoutSummary } from "@/lib/api/screenGroup";

// 글로우 펄스 애니메이션 CSS 주입
if (typeof document !== "undefined") {
  const styleId = "glow-pulse-animation";
  if (!document.getElementById(styleId)) {
    const style = document.createElement("style");
    style.id = styleId;
    style.textContent = `
      @keyframes glow-pulse {
        from { filter: drop-shadow(0 0 4px hsl(var(--primary) / 0.25)) drop-shadow(0 0 10px hsl(var(--primary) / 0.12)); }
        to { filter: drop-shadow(0 0 6px hsl(var(--primary) / 0.35)) drop-shadow(0 0 16px hsl(var(--primary) / 0.18)); }
      }
    `;
    document.head.appendChild(style);
  }
}

// ========== 타입 정의 ==========

// 화면 노드 데이터 인터페이스
export interface ScreenNodeData {
  label: string;
  subLabel?: string;
  type: "screen" | "table" | "action";
  tableName?: string;
  isMain?: boolean;
  // 레이아웃 요약 정보 (미리보기용)
  layoutSummary?: ScreenLayoutSummary;
  // 그룹 내 포커스 관련 속성
  isInGroup?: boolean;     // 그룹 모드인지
  isFocused?: boolean;     // 포커스된 화면인지
  isFaded?: boolean;       // 흑백 처리할지
  screenRole?: string;     // 화면 역할 (메인그리드, 등록폼 등)
}

// 필드 매핑 정보 (조인 관계 표시용)
export interface FieldMappingDisplay {
  sourceField: string;        // 메인 테이블 컬럼 (예: manager_id)
  targetField: string;        // 서브 테이블 컬럼 (예: user_id)
  sourceDisplayName?: string; // 메인 테이블 한글 컬럼명 (예: 담당자)
  targetDisplayName?: string; // 서브 테이블 한글 컬럼명 (예: 사용자ID)
  sourceTable?: string;       // 소스 테이블명 (필드 매핑에서 테이블 구분용)
}

// 참조 관계 정보 (다른 테이블에서 이 테이블을 참조하는 경우)
export interface ReferenceInfo {
  fromTable: string;        // 참조하는 테이블명 (영문)
  fromTableLabel?: string;  // 참조하는 테이블 한글명
  fromColumn: string;       // 참조하는 컬럼명 (영문)
  fromColumnLabel?: string; // 참조하는 컬럼 한글명
  toColumn: string;         // 참조되는 컬럼명 (이 테이블의 컬럼)
  toColumnLabel?: string;   // 참조되는 컬럼 한글명
  relationType: 'lookup' | 'join' | 'filter';  // 참조 유형
}

// 테이블 노드 데이터 인터페이스
export interface TableNodeData {
  label: string;
  subLabel?: string;
  isMain?: boolean;
  isFilterTable?: boolean;  // 마스터-디테일의 디테일 테이블인지 (보라색 테두리)
  isFocused?: boolean;     // 포커스된 테이블인지
  isFaded?: boolean;       // 흑백 처리할지
  columns?: Array<{
    name: string;           // 표시용 이름 (한글명)
    originalName?: string;  // 원본 컬럼명 (영문, 필터링용)
    type: string;
    isPrimaryKey?: boolean;
    isForeignKey?: boolean;
  }>;
  // 포커스 시 강조할 컬럼 정보
  highlightedColumns?: string[];  // 화면에서 사용하는 컬럼 (영문명)
  joinColumns?: string[];         // 조인에 사용되는 컬럼
  joinColumnRefs?: Array<{        // 조인 컬럼의 참조 정보
    column: string;               // FK 컬럼명 (예: 'customer_id')
    refTable: string;             // 참조 테이블 (예: 'customer_mng')
    refTableLabel?: string;       // 참조 테이블 한글명 (예: '거래처 관리')
    refColumn: string;            // 참조 컬럼 (예: 'customer_code')
  }>;
  filterColumns?: string[];       // 필터링에 사용되는 FK 컬럼 (마스터-디테일 관계)
  // 필드 매핑 정보 (조인 관계 표시용)
  fieldMappings?: FieldMappingDisplay[];  // 서브 테이블일 때 조인 관계 표시
  // 참조 관계 정보 (다른 테이블에서 이 테이블을 참조하는 경우)
  referencedBy?: ReferenceInfo[];  // 이 테이블을 참조하는 관계들
  // 저장 관계 정보
  saveInfos?: Array<{
    saveType: string;          // 'save' | 'edit' | 'delete' | 'transferData'
    componentType: string;     // 버튼 컴포넌트 타입
    isMainTable: boolean;      // 메인 테이블 저장인지
    sourceScreenId?: number;   // 어떤 화면에서 저장하는지
  }>;
}

// ========== 유틸리티 함수 ==========

// 화면 타입별 아이콘
const getScreenTypeIcon = (screenType?: string) => {
  switch (screenType) {
    case "grid":
      return <Table2 className="h-4 w-4" />;
    case "dashboard":
      return <LayoutDashboard className="h-4 w-4" />;
    case "action":
      return <MousePointer2 className="h-4 w-4" />;
    default:
      return <FormInput className="h-4 w-4" />;
  }
};

// 화면 타입별 색상 (헤더) - 더 이상 그라데이션 미사용
const getScreenTypeColor = (_screenType?: string, _isMain?: boolean) => {
  return "";
};

// 화면 역할(screenRole)에 따른 색상 - 더 이상 그라데이션 미사용
const getScreenRoleColor = (_screenRole?: string) => {
  return "";
};

// 화면 타입별 라벨
const getScreenTypeLabel = (screenType?: string) => {
  switch (screenType) {
    case "grid":
      return "그리드";
    case "dashboard":
      return "대시보드";
    case "action":
      return "액션";
    default:
      return "폼";
  }
};

// ========== 화면 노드 (상단) - 미리보기 표시 ==========
export const ScreenNode: React.FC<{ data: ScreenNodeData }> = ({ data }) => {
  const { label, isMain, tableName, layoutSummary, isFocused, isFaded } = data;
  const screenType = layoutSummary?.screenType || "form";

  return (
    <div 
      className={`group relative flex h-[240px] w-[240px] flex-col overflow-hidden rounded-[10px] border bg-card dark:bg-card/80 backdrop-blur-sm transition-all cursor-pointer ${
        isFocused 
          ? "border-primary/40 shadow-[0_0_0_1px_hsl(var(--primary)/0.4)] scale-[1.03]" 
          : isFaded
          ? "opacity-40 border-border/40 dark:border-border/10 shadow-[0_4px_24px_-8px_rgba(0,0,0,0.08)] dark:shadow-[0_4px_24px_-8px_rgba(0,0,0,0.5)]"
          : "border-border/40 dark:border-border/10 shadow-[0_4px_24px_-8px_rgba(0,0,0,0.08)] dark:shadow-[0_4px_24px_-8px_rgba(0,0,0,0.5)] hover:border-border/50 dark:hover:border-border/20 hover:shadow-[0_4px_24px_-8px_rgba(0,0,0,0.08)] dark:hover:shadow-[0_4px_24px_-8px_rgba(0,0,0,0.5)] hover:-translate-y-0.5"
      }`}
      style={{
        filter: isFaded 
          ? "grayscale(100%)" 
          : isFocused 
          ? "drop-shadow(0 0 8px hsl(var(--primary) / 0.5)) drop-shadow(0 0 20px hsl(var(--primary) / 0.25))"
          : "none",
        transition: "all 0.3s ease",
        animation: isFocused ? "glow-pulse 2s ease-in-out infinite alternate" : "none",
      }}
    >
      {/* Handles */}
      <Handle
        type="target"
        position={Position.Left}
        id="left"
        className="!h-2 !w-2 !border-[1.5px] !border-card !bg-muted-foreground/70 dark:!bg-muted-foreground/40 opacity-0 transition-all duration-300 group-hover:opacity-100 group-hover:shadow-[0_0_6px_hsl(var(--primary)/0.5)]"
      />
      <Handle
        type="source"
        position={Position.Right}
        id="right"
        className="!h-2 !w-2 !border-[1.5px] !border-card !bg-muted-foreground/70 dark:!bg-muted-foreground/40 opacity-0 transition-all duration-300 group-hover:opacity-100 group-hover:shadow-[0_0_6px_hsl(var(--primary)/0.5)]"
      />
      <Handle
        type="source"
        position={Position.Bottom}
        id="bottom"
        className="!h-2 !w-2 !border-[1.5px] !border-card !bg-muted-foreground/70 dark:!bg-muted-foreground/40 opacity-0 transition-all duration-300 group-hover:opacity-100 group-hover:shadow-[0_0_6px_hsl(var(--primary)/0.5)]"
      />

      {/* 헤더: 그라디언트 제거, 모노크롬 */}
      <div className="flex items-center gap-2 border-b border-border/40 dark:border-border/10 bg-muted/50 dark:bg-muted/30 px-3 py-2 transition-colors duration-300">
        <div className="flex h-6 w-6 items-center justify-center rounded bg-primary/10 text-primary">
          <Monitor className="h-3.5 w-3.5" />
        </div>
        <div className="flex-1 min-w-0">
          <div className="truncate text-xs font-bold text-foreground">{label}</div>
          {tableName && <div className="truncate text-[9px] text-muted-foreground font-mono">{tableName}</div>}
        </div>
        {(isMain || isFocused) && <span className="flex h-2 w-2 rounded-full bg-foreground/[0.12] dark:bg-foreground/8 animate-pulse" />}
      </div>

      {/* 화면 미리보기 영역 (컴팩트) */}
      <div className="h-[110px] overflow-hidden p-2.5">
        {layoutSummary ? (
          <ScreenPreview layoutSummary={layoutSummary} screenType={screenType} />
        ) : (
          <div className="flex h-full flex-col items-center justify-center text-muted-foreground/70 dark:text-muted-foreground/40">
            {getScreenTypeIcon(screenType)}
            <span className="mt-1 text-[10px]">화면: {label}</span>
          </div>
        )}
      </div>

      {/* 푸터 (타입 칩 + 컴포넌트 수) */}
      <div className="flex items-center justify-between border-t border-border/40 dark:border-border/10 bg-background dark:bg-background/50 px-3 py-1.5">
        <span className="text-[9px] font-medium px-[7px] py-[2px] rounded bg-primary/10 text-primary">{getScreenTypeLabel(screenType)}</span>
        <span className="text-[9px] text-muted-foreground">{layoutSummary?.totalComponents ?? 0}개 컴포넌트</span>
      </div>
    </div>
  );
};

// ========== 컴포넌트 종류별 미니어처 색상 ==========
// componentKind는 더 정확한 컴포넌트 타입 (table-list, button-primary 등)
const getComponentColor = (componentKind: string) => {
  // 테이블/그리드 관련
  if (componentKind === "table-list" || componentKind === "data-grid") {
    return "bg-primary/20 border-primary/40";
  }
  // 검색 필터
  if (componentKind === "table-search-widget" || componentKind === "search-filter") {
    return "bg-destructive/20 border-destructive/40";
  }
  // 버튼 관련
  if (componentKind?.includes("button")) {
    return "bg-primary/30 border-primary";
  }
  // 입력 필드
  if (componentKind?.includes("input") || componentKind?.includes("text")) {
    return "bg-muted border-border";
  }
  // 셀렉트/드롭다운
  if (componentKind?.includes("select") || componentKind?.includes("dropdown")) {
    return "bg-warning/20 border-warning/40";
  }
  // 차트
  if (componentKind?.includes("chart")) {
    return "bg-success/20 border-success/40";
  }
  // 커스텀 위젯
  if (componentKind === "custom") {
    return "bg-destructive/20 border-destructive/40";
  }
  return "bg-muted/50 border-border";
};

// ========== 화면 미리보기 컴포넌트 - 화면 타입별 간단한 일러스트 ==========
const ScreenPreview: React.FC<{ layoutSummary: ScreenLayoutSummary; screenType: string }> = ({
  layoutSummary,
  screenType,
}) => {
  const { totalComponents, widgetCounts } = layoutSummary;

  // 그리드 화면 일러스트 (모노크롬)
  if (screenType === "grid") {
    return (
      <div className="flex h-full flex-col gap-2 rounded-lg border border-border/30 dark:border-border/5 bg-muted/30 dark:bg-muted/10 p-3">
        {/* 상단 툴바 */}
        <div className="flex items-center gap-2">
          <div className="h-4 w-16 rounded bg-foreground/[0.15] dark:bg-foreground/10" />
          <div className="flex-1" />
          <div className="h-4 w-8 rounded bg-foreground/[0.18] dark:bg-foreground/12" />
          <div className="h-4 w-8 rounded bg-foreground/[0.18] dark:bg-foreground/12" />
          <div className="h-4 w-8 rounded bg-foreground/[0.12] dark:bg-foreground/8" />
        </div>
        {/* 테이블 헤더 */}
        <div className="flex gap-1 rounded-t-md bg-foreground/[0.18] dark:bg-foreground/12 px-2 py-2">
          {[...Array(5)].map((_, i) => (
            <div key={i} className="h-2.5 flex-1 rounded bg-foreground/[0.12] dark:bg-foreground/8" />
          ))}
        </div>
        {/* 테이블 행들 */}
        <div className="flex flex-1 flex-col gap-1 overflow-hidden">
          {[...Array(7)].map((_, i) => (
            <div key={i} className={`flex gap-1 rounded px-2 py-1.5 ${i % 2 === 0 ? "bg-muted/30 dark:bg-muted/10" : "bg-card"}`}>
              {[...Array(5)].map((_, j) => (
                <div key={j} className="h-2 flex-1 rounded bg-foreground/[0.1] dark:bg-foreground/6" />
              ))}
            </div>
          ))}
        </div>
        {/* 페이지네이션 */}
        <div className="flex items-center justify-center gap-2 pt-1">
          <div className="h-2.5 w-4 rounded bg-foreground/[0.12] dark:bg-foreground/8" />
          <div className="h-2.5 w-4 rounded bg-foreground/[0.18] dark:bg-foreground/12" />
          <div className="h-2.5 w-4 rounded bg-foreground/[0.12] dark:bg-foreground/8" />
          <div className="h-2.5 w-4 rounded bg-foreground/[0.12] dark:bg-foreground/8" />
        </div>
      </div>
    );
  }

  // 폼 화면 일러스트 (모노크롬)
  if (screenType === "form") {
    return (
      <div className="flex h-full flex-col gap-3 rounded-lg border border-border/30 dark:border-border/5 bg-muted/30 dark:bg-muted/10 p-3">
        {/* 폼 필드들 */}
        {[...Array(6)].map((_, i) => (
          <div key={i} className="flex items-center gap-3">
            <div className="h-2.5 w-14 rounded bg-foreground/[0.12] dark:bg-foreground/8" />
            <div className="h-5 flex-1 rounded-md border border-border/30 dark:border-border/5 bg-card" />
          </div>
        ))}
        {/* 버튼 영역 */}
        <div className="mt-auto flex justify-end gap-2 border-t border-border/30 dark:border-border/5 pt-3">
          <div className="h-5 w-14 rounded-md bg-foreground/[0.12] dark:bg-foreground/8" />
          <div className="h-5 w-14 rounded-md bg-foreground/[0.18] dark:bg-foreground/12" />
        </div>
      </div>
    );
  }

  // 대시보드 화면 일러스트 (모노크롬)
  if (screenType === "dashboard") {
    return (
      <div className="grid h-full grid-cols-2 gap-2 rounded-lg border border-border/30 dark:border-border/5 bg-muted/30 dark:bg-muted/10 p-3">
        {/* 카드/차트들 */}
        <div className="rounded-lg bg-foreground/[0.08] dark:bg-foreground/5 p-2">
          <div className="mb-2 h-2.5 w-10 rounded bg-foreground/[0.15] dark:bg-foreground/10" />
          <div className="h-10 rounded-md bg-foreground/[0.12] dark:bg-foreground/8" />
        </div>
        <div className="rounded-lg bg-foreground/[0.08] dark:bg-foreground/5 p-2">
          <div className="mb-2 h-2.5 w-10 rounded bg-foreground/[0.15] dark:bg-foreground/10" />
          <div className="h-10 rounded-md bg-foreground/[0.12] dark:bg-foreground/8" />
        </div>
        <div className="col-span-2 rounded-lg bg-foreground/[0.08] dark:bg-foreground/5 p-2">
          <div className="mb-2 h-2.5 w-12 rounded bg-foreground/[0.15] dark:bg-foreground/10" />
          <div className="flex h-14 items-end gap-1">
            {[...Array(10)].map((_, i) => (
              <div
                key={i}
                className="flex-1 rounded-t bg-foreground/[0.15] dark:bg-foreground/10"
                style={{ height: `${25 + Math.random() * 75}%` }}
              />
            ))}
          </div>
        </div>
      </div>
    );
  }

  // 액션 화면 일러스트 (모노크롬)
  if (screenType === "action") {
    return (
      <div className="flex h-full flex-col items-center justify-center gap-4 rounded-lg border border-border/30 dark:border-border/5 bg-muted/30 dark:bg-muted/10 p-3">
        <div className="rounded-full bg-foreground/[0.08] dark:bg-foreground/5 p-4 text-muted-foreground">
          <MousePointer2 className="h-10 w-10" />
        </div>
        <div className="flex gap-3">
          <div className="h-7 w-16 rounded-md bg-foreground/[0.18] dark:bg-foreground/12" />
          <div className="h-7 w-16 rounded-md bg-foreground/[0.12] dark:bg-foreground/8" />
        </div>
        <div className="text-xs font-medium text-muted-foreground">액션 화면</div>
      </div>
    );
  }

  // 기본 (알 수 없는 타입, 모노크롬)
  return (
    <div className="flex h-full flex-col items-center justify-center gap-3 rounded-lg border border-border/30 dark:border-border/5 bg-muted/30 dark:bg-muted/10 text-muted-foreground">
      <div className="rounded-full bg-foreground/[0.08] dark:bg-foreground/5 p-4">
        {getScreenTypeIcon(screenType)}
      </div>
      <span className="text-sm font-medium">{totalComponents}개 컴포넌트</span>
    </div>
  );
};

// ========== 테이블 노드 (하단) - 컬럼 목록 표시 (컴팩트) ==========
export const TableNode: React.FC<{ data: TableNodeData }> = ({ data }) => {
  const { label, subLabel, isMain, isFilterTable, isFocused, isFaded, columns, highlightedColumns, joinColumns, joinColumnRefs, filterColumns, fieldMappings, referencedBy, saveInfos } = data;
  
  // 강조할 컬럼 세트 (영문 컬럼명 기준)
  const highlightSet = new Set(highlightedColumns || []);
  const filterSet = new Set(filterColumns || []);  // 필터링에 사용되는 FK 컬럼
  const joinSet = new Set(joinColumns || []);
  
  // 조인 컬럼 참조 정보 맵 생성 (column → { refTable, refTableLabel, refColumn })
  const joinRefMap = new Map<string, { refTable: string; refTableLabel: string; refColumn: string }>();
  if (joinColumnRefs) {
    joinColumnRefs.forEach((ref) => {
      joinRefMap.set(ref.column, { 
        refTable: ref.refTable, 
        refTableLabel: ref.refTableLabel || ref.refTable, // 한글명 (없으면 영문명)
        refColumn: ref.refColumn 
      });
    });
  }
  
  // 필드 매핑 맵 생성 (targetField → { sourceField, sourceDisplayName })
  // 서브 테이블에서 targetField가 어떤 메인 테이블 컬럼(sourceField)과 연결되는지
  const fieldMappingMap = new Map<string, { sourceField: string; sourceDisplayName: string }>();
  if (fieldMappings) {
    fieldMappings.forEach(mapping => {
      fieldMappingMap.set(mapping.targetField, {
        sourceField: mapping.sourceField,
        // 한글명이 있으면 한글명, 없으면 영문명 사용
        sourceDisplayName: mapping.sourceDisplayName || mapping.sourceField,
      });
    });
  }
  
  // 필터 소스 컬럼 세트 (메인 테이블에서 필터에 사용되는 컬럼)
  const filterSourceSet = new Set(
    referencedBy?.filter(r => r.relationType === 'filter').map(r => r.fromColumn) || []
  );
  
  // 포커스 모드: 사용 컬럼만 필터링하여 표시
  // originalName (영문) 또는 name으로 매칭 시도
  // 필터 컬럼(filterSet) 및 필터 소스 컬럼(filterSourceSet)도 포함하여 보라색으로 표시
  const potentialFilteredColumns = columns?.filter(col => {
    const colOriginal = col.originalName || col.name;
    return highlightSet.has(colOriginal) || joinSet.has(colOriginal) || filterSet.has(colOriginal) || filterSourceSet.has(colOriginal);
  }) || [];
  
  // 정렬: 조인 컬럼 → 필터 컬럼/필터 소스 컬럼 → 사용 컬럼 순서
  const sortedFilteredColumns = [...potentialFilteredColumns].sort((a, b) => {
    const aOriginal = a.originalName || a.name;
    const bOriginal = b.originalName || b.name;
    
    const aIsJoin = joinSet.has(aOriginal);
    const bIsJoin = joinSet.has(bOriginal);
    const aIsFilter = filterSet.has(aOriginal) || filterSourceSet.has(aOriginal);
    const bIsFilter = filterSet.has(bOriginal) || filterSourceSet.has(bOriginal);
    
    // 조인 컬럼 우선
    if (aIsJoin && !bIsJoin) return -1;
    if (!aIsJoin && bIsJoin) return 1;
    // 필터 컬럼/필터 소스 다음
    if (aIsFilter && !bIsFilter) return -1;
    if (!aIsFilter && bIsFilter) return 1;
    // 나머지는 원래 순서 유지
    return 0;
  });
  
  const hasActiveColumns = sortedFilteredColumns.length > 0;
  
  // 필터 관계가 있는 테이블인지 확인 (마스터-디테일 필터링)
  // - hasFilterRelation: 디테일 테이블 (WHERE 조건 대상) - filterColumns에 FK 컬럼이 있음
  // - isFilterSource: 마스터 테이블 (필터 소스, WHERE 조건 제공) - 포커스된 화면의 메인 테이블이고 filterSourceSet에 컬럼이 있음
  // 디테일 테이블: filterColumns(filterSet)에 FK 컬럼이 있고, 포커스된 화면의 메인이 아님
  const hasFilterRelation = filterSet.size > 0 && !isFocused;
  // 마스터 테이블: 포커스된 화면의 메인 테이블(isFocused)이고 filterSourceSet에 컬럼이 있음
  const isFilterSource = isFocused && filterSourceSet.size > 0;
  
  // 표시할 컬럼:
  // - 포커스 시 (활성 컬럼 있음): 정렬된 컬럼만 표시
  // - 비포커스 시: 최대 8개만 표시
  const MAX_DEFAULT_COLUMNS = 8;
  const allColumns = columns || [];
  const displayColumns = hasActiveColumns 
    ? sortedFilteredColumns 
    : allColumns.slice(0, MAX_DEFAULT_COLUMNS);
  const remainingCount = hasActiveColumns 
    ? 0 
    : Math.max(0, allColumns.length - MAX_DEFAULT_COLUMNS);
  const totalCount = allColumns.length;

  // 컬럼 수 기반 높이 계산 (DOM 측정 없이)
  // - 각 컬럼 행 높이: 약 22px (py-0.5 + text + gap-px)
  // - 컨테이너 패딩: p-1.5 = 12px (상하 합계)
  // - 뱃지 높이: 약 26px (py-1 + text + gap)
  const COLUMN_ROW_HEIGHT = 22;
  const CONTAINER_PADDING = 12;
  const BADGE_HEIGHT = 26;
  const MAX_HEIGHT = 200; // 뱃지 포함 가능하도록 증가
  
  // 뱃지가 표시될지 미리 계산 (필터/참조만, 저장은 헤더에 표시)
  const hasFilterOrLookupBadge = referencedBy && referencedBy.some(r => r.relationType === 'filter' || r.relationType === 'lookup');
  const hasBadge = hasFilterOrLookupBadge;
  
  const calculatedHeight = useMemo(() => {
    const badgeHeight = hasBadge ? BADGE_HEIGHT : 0;
    const rawHeight = CONTAINER_PADDING + badgeHeight + (displayColumns.length * COLUMN_ROW_HEIGHT);
    return Math.min(rawHeight, MAX_HEIGHT);
  }, [displayColumns.length, hasBadge]);
  
  // Debounce된 높이: 중간 값(늘어났다가 줄어드는 현상)을 무시하고 최종 값만 사용
  // 듀얼 그리드에서 filterColumns와 joinColumns가 2단계로 업데이트되는 문제 해결
  const [debouncedHeight, setDebouncedHeight] = useState(calculatedHeight);
  
  useEffect(() => {
    // 50ms 내에 다시 변경되면 이전 값 무시
    const timer = setTimeout(() => {
      setDebouncedHeight(calculatedHeight);
    }, 50);
    
    return () => clearTimeout(timer);
  }, [calculatedHeight]);

  // 저장 대상 여부
  const hasSaveTarget = saveInfos && saveInfos.length > 0;

  return (
    <div 
      className={`group relative flex w-[260px] flex-col overflow-visible rounded-[10px] border bg-card dark:bg-card/80 backdrop-blur-sm shadow-[0_4px_24px_-8px_rgba(0,0,0,0.08)] dark:shadow-[0_4px_24px_-8px_rgba(0,0,0,0.5)] ${
        // 1. 필터 테이블 (마스터-디테일의 디테일 테이블)
        isFilterTable
          ? "border-primary/30 shadow-[0_0_0_1px_hsl(var(--primary)/0.3)]"
          // 2. 필터 관련 테이블 포커스 시
          : (hasFilterRelation || isFilterSource)
          ? "border-primary/30 shadow-[0_0_0_1px_hsl(var(--primary)/0.3),0_0_24px_-8px_hsl(var(--primary)/0.1)]"
          // 3. 순수 포커스
          : isFocused
          ? "border-primary/30 shadow-[0_0_0_1px_hsl(var(--primary)/0.3),0_0_24px_-8px_hsl(var(--primary)/0.1)] bg-card"
          // 4. 흐리게 처리
          : isFaded
          ? "opacity-60 bg-card border-border/40 dark:border-border/10"
          // 5. 기본
          : "border-border/40 dark:border-border/10 hover:border-border/50 dark:hover:border-border/20"
      }`}
      style={{
        filter: isFaded ? "grayscale(80%)" : "none",
        // 색상/테두리/그림자만 transition (높이 제외)
        transition: "background-color 0.7s ease, border-color 0.7s ease, box-shadow 0.7s ease, filter 0.3s ease, opacity 0.3s ease",
      }}
      title={hasSaveTarget ? "저장 대상 테이블" : undefined}
    >
      {/* 저장 대상: 테이블 바깥 왼쪽에 띄워진 막대기 (나타나기/사라지기 애니메이션) */}
      <div 
        className="absolute -left-1.5 top-1 bottom-1 w-0.5 z-20 rounded-full transition-all duration-500 ease-out"
        title={hasSaveTarget ? "저장 대상 테이블" : undefined}
        style={{
            background: `linear-gradient(to bottom, transparent 0%, hsl(var(--destructive)) 15%, hsl(var(--destructive)) 85%, transparent 100%)`,
          opacity: hasSaveTarget ? 1 : 0,
          transform: hasSaveTarget ? 'scaleY(1)' : 'scaleY(0)',
          transformOrigin: 'top',
          pointerEvents: hasSaveTarget ? 'auto' : 'none',
        }}
      />
      
      {/* Handles */}
      {/* top target: 화면 → 메인테이블 연결용 */}
      <Handle
        type="target"
        position={Position.Top}
        id="top"
        className="!h-2 !w-2 !border-[1.5px] !border-card !bg-muted-foreground/70 dark:!bg-muted-foreground/40 opacity-0 transition-opacity group-hover:opacity-100"
      />
      {/* top source: 메인테이블 → 메인테이블 연결용 (위쪽으로 나가는 선) */}
      <Handle
        type="source"
        position={Position.Top}
        id="top_source"
        style={{ top: -4 }}
        className="!h-2 !w-2 !border-[1.5px] !border-card !bg-muted-foreground/70 dark:!bg-muted-foreground/40 opacity-0 transition-opacity group-hover:opacity-100"
      />
      <Handle
        type="target"
        position={Position.Left}
        id="left"
        className="!h-2 !w-2 !border-[1.5px] !border-card !bg-muted-foreground/70 dark:!bg-muted-foreground/40 opacity-0 transition-opacity group-hover:opacity-100"
      />
      <Handle
        type="source"
        position={Position.Right}
        id="right"
        className="!h-2 !w-2 !border-[1.5px] !border-card !bg-muted-foreground/70 dark:!bg-muted-foreground/40 opacity-0 transition-opacity group-hover:opacity-100"
      />
      <Handle
        type="source"
        position={Position.Bottom}
        id="bottom"
        className="!h-2 !w-2 !border-[1.5px] !border-card !bg-muted-foreground/70 dark:!bg-muted-foreground/40 opacity-0 transition-opacity group-hover:opacity-100"
      />
      {/* bottom target: 메인테이블 ← 메인테이블 연결용 (아래에서 들어오는 선) */}
      <Handle
        type="target"
        position={Position.Bottom}
        id="bottom_target"
        style={{ bottom: -4 }}
        className="!h-2 !w-2 !border-[1.5px] !border-card !bg-muted-foreground/70 dark:!bg-muted-foreground/40 opacity-0 transition-opacity group-hover:opacity-100"
      />

      {/* 헤더: 그라디언트 제거, bg-muted/30 + 아이콘 박스 */}
      <div className="flex items-center gap-2.5 px-3.5 py-2.5 border-b border-border/40 dark:border-border/10 bg-muted/50 dark:bg-muted/30 rounded-t-[10px] transition-colors duration-700 ease-in-out">
        <div className="flex h-7 w-7 items-center justify-center rounded-[7px] bg-cyan-500/10 shrink-0">
          <Database className="h-3.5 w-3.5 text-cyan-400" />
        </div>
        <div className="flex-1 min-w-0">
          <div className="truncate text-[11px] font-semibold text-foreground font-mono">{label}</div>
          {/* 필터 관계에 따른 문구 변경 */}
          <div className="truncate text-[9px] font-mono text-muted-foreground/70 dark:text-muted-foreground/40 tracking-[-0.3px]">
            {isFilterSource 
              ? "마스터 테이블 (필터 소스)" 
              : hasFilterRelation 
              ? "디테일 테이블 (WHERE 조건)" 
              : subLabel}
          </div>
        </div>
        {hasActiveColumns && (
          <span className="text-[9px] font-mono text-muted-foreground/70 dark:text-muted-foreground/40 px-1.5 py-0.5 rounded bg-foreground/[0.08] dark:bg-foreground/5 border border-border/40 dark:border-border/10 tracking-[-0.3px] shrink-0">
            {displayColumns.length} ref
          </span>
        )}
      </div>

      {/* 컬럼 목록 - 컴팩트하게 (부드러운 높이 전환 + 스크롤) */}
      {/* 뱃지도 이 영역 안에 포함되어 높이 계산에 반영됨 */}
      <div 
        className="p-1.5 overflow-y-auto scrollbar-thin scrollbar-thumb-border scrollbar-track-transparent"
        style={{
          height: `${debouncedHeight}px`,
          maxHeight: `${MAX_HEIGHT}px`,
          // Debounce로 중간 값이 무시되므로 항상 부드러운 transition 적용 가능
          transition: 'height 0.5s cubic-bezier(0.4, 0, 0.2, 1)',
        }}
      >
        {/* 필터링/참조 관계 뱃지 (컬럼 목록 영역 안에 포함, 저장은 헤더에 표시) */}
        {hasBadge && (() => {
          const filterRefs = referencedBy?.filter(r => r.relationType === 'filter') || [];
          const lookupRefs = referencedBy?.filter(r => r.relationType === 'lookup') || [];
          
          if (filterRefs.length === 0 && lookupRefs.length === 0) return null;
          
          return (
            <div className="flex items-center gap-1.5 px-2 py-1 mb-1.5 rounded border border-border bg-muted text-[9px]">
              {/* 필터 뱃지 */}
              {filterRefs.length > 0 && (
                <span 
                  className="flex items-center gap-1 rounded-full bg-primary px-2 py-px text-primary-foreground font-semibold shadow-sm"
                  title={`마스터-디테일 필터링\n${filterRefs.map(r => `${r.fromTable}.${r.fromColumn || 'id'} → ${r.toColumn}`).join('\n')}`}
                >
                  <Link2 className="h-3 w-3" />
                  <span>필터</span>
                </span>
              )}
              {filterRefs.length > 0 && (
                <span className="text-primary font-medium truncate">
                  {filterRefs.map(r => `${r.fromTableLabel || r.fromTable}.${r.fromColumnLabel || r.fromColumn || 'id'}`).join(', ')}
                </span>
              )}
              {/* 참조 뱃지 */}
              {lookupRefs.length > 0 && (
                <span 
                  className="flex items-center gap-1 rounded-full bg-warning px-2 py-px text-warning-foreground font-semibold shadow-sm"
                  title={`코드 참조 (lookup)\n${lookupRefs.map(r => `${r.fromTable} → ${r.toColumn}`).join('\n')}`}
                >
                  {lookupRefs.length}곳 참조
                </span>
              )}
            </div>
          );
        })()}
        
        {displayColumns.length > 0 ? (
          <div className="flex flex-col gap-px transition-all duration-700 ease-in-out">
            {displayColumns.map((col, idx) => {
              const colOriginal = col.originalName || col.name;
              const isJoinColumn = joinSet.has(colOriginal);
              const isFilterColumn = filterSet.has(colOriginal);  // 서브 테이블의 필터링 FK 컬럼
              const isHighlighted = highlightSet.has(colOriginal);
              
              // 필터링 참조 정보 (어떤 테이블의 어떤 컬럼에서 필터링되는지) - 서브 테이블용
              const filterRefInfo = referencedBy?.find(
                r => r.relationType === 'filter' && r.toColumn === colOriginal
              );
              
              // 메인 테이블에서 필터 소스로 사용되는 컬럼인지 (fromColumn과 일치)
              const isFilterSourceColumn = filterSourceSet.has(colOriginal);
              
              return (
                <div
                  key={col.name}
                  className={`flex items-center gap-1 rounded px-1.5 py-0.5 transition-all duration-300 ${
                    isJoinColumn 
                      ? "bg-warning/10 border border-warning/20 shadow-sm" 
                      : isFilterColumn || isFilterSourceColumn
                      ? "bg-primary/10 border border-primary/20 shadow-sm"  // 필터 컬럼/필터 소스
                      : isHighlighted 
                      ? "bg-primary/10 border border-primary/40 shadow-sm"
                      : hasActiveColumns
                      ? "bg-muted"
                      : "bg-muted/50 hover:bg-muted/80 transition-colors"
                  }`}
                  style={{
                    animation: hasActiveColumns ? `fadeIn 0.5s ease-out ${idx * 80}ms forwards` : undefined,
                    opacity: hasActiveColumns ? 0 : 1,
                  }}
                >
                  {/* 3px 세로 마커 (PK/FK/조인/필터) */}
                  <div
                    className={`w-[3px] h-[14px] rounded-sm flex-shrink-0 ${
                      isJoinColumn ? "bg-amber-400"
                      : (isFilterColumn || isFilterSourceColumn) ? "bg-primary opacity-80"
                      : col.isPrimaryKey ? "bg-amber-400"
                      : col.isForeignKey ? "bg-primary opacity-80"
                      : "bg-muted-foreground/20"
                    }`}
                  />

                  {/* 컬럼명 */}
                  <span className={`flex-1 truncate font-mono text-[9px] font-medium ${
                    isJoinColumn ? "text-amber-400"
                    : (isFilterColumn || isFilterSourceColumn) ? "text-primary"
                    : isHighlighted ? "text-primary"
                    : "text-foreground"
                  }`}>
                    {col.name}
                  </span>

                  {/* 역할 태그 + 참조 관계 표시 */}
                  {isJoinColumn && (
                    <>
                      {/* 조인 참조 테이블 표시 (joinColumnRefs에서) */}
                      {joinRefMap.has(colOriginal) && (
                        <span className="rounded bg-warning/20 px-1 text-[7px] text-warning">
                          ← {joinRefMap.get(colOriginal)?.refTableLabel}
                        </span>
                      )}
                      {/* 필드 매핑 참조 표시 (fieldMappingMap에서, joinRefMap에 없는 경우) */}
                      {!joinRefMap.has(colOriginal) && fieldMappingMap.has(colOriginal) && (
                        <span className="rounded bg-warning/20 px-1 text-[7px] text-warning">
                          ← {fieldMappingMap.get(colOriginal)?.sourceDisplayName}
                        </span>
                      )}
                      <span className="rounded bg-warning/20 px-1 text-[7px] text-warning">조인</span>
                    </>
                  )}
                  {isFilterColumn && !isJoinColumn && (
                    <span className="rounded bg-primary/20 px-1 text-[7px] text-primary">필터</span>
                  )}
                  {/* 메인 테이블에서 필터 소스로 사용되는 컬럼: "필터" + "사용" 둘 다 표시 */}
                  {isFilterSourceColumn && !isJoinColumn && !isFilterColumn && (
                    <>
                      <span className="rounded bg-primary/20 px-1 text-[7px] text-primary">필터</span>
                      {isHighlighted && (
                        <span className="rounded bg-primary/20 px-1 text-[7px] text-primary">사용</span>
                      )}
                    </>
                  )}
                  {isHighlighted && !isJoinColumn && !isFilterColumn && !isFilterSourceColumn && (
                    <span className="rounded bg-primary/20 px-1 text-[7px] text-primary">사용</span>
                  )}

                  {/* 타입 */}
                  <span className="text-[8px] text-muted-foreground/60 dark:text-muted-foreground/30 font-mono tracking-[-0.3px]">{col.type}</span>
                </div>
              );
            })}
            {/* 더 많은 컬럼이 있을 경우 표시 */}
            {remainingCount > 0 && (
              <div className="text-center text-[8px] text-muted-foreground py-0.5">
                + {remainingCount}개 더
              </div>
            )}
          </div>
        ) : (
          <div className="flex flex-col items-center justify-center py-2 text-muted-foreground">
            <Database className="h-4 w-4 text-muted-foreground" />
            <span className="mt-0.5 text-[8px] text-muted-foreground">컬럼 정보 없음</span>
          </div>
        )}
      </div>

      {/* 푸터: cols + PK/FK 카운트 */}
      <div className="flex items-center justify-between border-t border-border/40 dark:border-border/10 px-3.5 py-1.5 bg-background dark:bg-background/50">
        <span className="text-[9px] text-muted-foreground/70 dark:text-muted-foreground/40 font-mono tracking-[-0.3px]">
          {hasActiveColumns ? `${displayColumns.length}/${totalCount}` : totalCount} cols
        </span>
        <div className="flex gap-2.5 text-[9px] font-mono tracking-[-0.3px]">
          {columns?.some(c => c.isPrimaryKey) && (
            <span className="flex items-center gap-1">
              <span className="w-1 h-1 rounded-full bg-amber-400" />
              <span className="text-muted-foreground/70 dark:text-muted-foreground/40">PK {columns.filter(c => c.isPrimaryKey).length}</span>
            </span>
          )}
          {columns?.some(c => c.isForeignKey) && (
            <span className="flex items-center gap-1">
              <span className="w-1 h-1 rounded-full bg-primary" />
              <span className="text-muted-foreground/70 dark:text-muted-foreground/40">FK {columns.filter(c => c.isForeignKey).length}</span>
            </span>
          )}
        </div>
      </div>
      
      {/* CSS 애니메이션 정의 */}
      <style jsx>{`
        @keyframes fadeIn {
          from {
            opacity: 0;
            transform: translateY(-5px);
          }
          to {
            opacity: 1;
            transform: translateY(0);
          }
        }
      `}</style>
    </div>
  );
};

// ========== 기존 호환성 유지용 ==========
export const LegacyScreenNode = ScreenNode;
export const AggregateNode: React.FC<{ data: any }> = ({ data }) => {
  return (
    <div className="rounded-lg border-2 border-primary/40 bg-card p-3 shadow-lg">
      <Handle type="target" position={Position.Left} id="left" className="!h-3 !w-3 !bg-primary" />
      <Handle type="source" position={Position.Right} id="right" className="!h-3 !w-3 !bg-primary" />
      <div className="flex items-center gap-2 text-primary">
        <Table2 className="h-4 w-4" />
        <span className="text-sm font-semibold">{data.label || "Aggregate"}</span>
      </div>
    </div>
  );
};
