"use client";

/**
 * V2SplitPanelLayout 설정 패널
 * 토스식 단계별 UX: 관계타입 카드선택 -> 레이아웃 -> 좌측패널 -> 우측패널 -> 추가탭 -> 고급설정
 * 기존 SplitPanelLayoutConfigPanel의 모든 기능을 자체 UI로 완전 구현
 */

import React, { useState, useEffect, useMemo, useCallback } from "react";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Switch } from "@/components/ui/switch";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Checkbox } from "@/components/ui/checkbox";
import { Slider } from "@/components/ui/slider";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command";
import { Separator } from "@/components/ui/separator";
import {
  Database,
  Link2,
  GripVertical,
  X,
  Check,
  ChevronsUpDown,
  Settings,
  ChevronDown,
  Loader2,
  Columns3,
  PanelLeft,
  PanelRight,
  Layers,
  Plus,
  Trash2,
  ArrowRight,
  SplitSquareHorizontal,
  Eye,
  List,
  LayoutGrid,
  Search,
  Pencil,
  FileText,
} from "lucide-react";
import { cn } from "@/lib/utils";
import { entityJoinApi } from "@/lib/api/entityJoin";
import { tableTypeApi } from "@/lib/api/screen";
import { tableManagementApi } from "@/lib/api/tableManagement";
import { DataFilterConfigPanel } from "@/components/screen/config-panels/DataFilterConfigPanel";
import { DndContext, closestCenter, type DragEndEvent } from "@dnd-kit/core";
import { SortableContext, useSortable, verticalListSortingStrategy, arrayMove } from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
import {
  MAX_LOAD_ALL_SIZE,
  type SplitPanelLayoutConfig,
  type AdditionalTabConfig,
} from "@/lib/registry/components/v2-split-panel-layout/types";
import type { TableInfo, ColumnInfo } from "@/types/screen";

// ─── DnD 정렬 가능한 컬럼 행 ───
function SortableColumnRow({
  id,
  col,
  index,
  isNumeric,
  isEntityJoin,
  onLabelChange,
  onWidthChange,
  onFormatChange,
  onRemove,
}: {
  id: string;
  col: {
    name: string;
    label: string;
    width?: number;
    format?: any;
  };
  index: number;
  isNumeric: boolean;
  isEntityJoin?: boolean;
  onLabelChange: (value: string) => void;
  onWidthChange: (value: number) => void;
  onFormatChange: (checked: boolean) => void;
  onRemove: () => void;
}) {
  const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id });
  const style = { transform: CSS.Transform.toString(transform), transition };

  return (
    <div
      ref={setNodeRef}
      style={style}
      className={cn(
        "bg-card flex items-center gap-1.5 rounded-md border px-2 py-1.5",
        isDragging && "z-50 opacity-50 shadow-md",
        isEntityJoin && "border-primary/20 bg-primary/5",
      )}
    >
      <div
        {...attributes}
        {...listeners}
        className="text-muted-foreground hover:text-foreground cursor-grab touch-none"
      >
        <GripVertical className="h-3 w-3" />
      </div>
      {isEntityJoin ? (
        <Link2 className="text-primary h-3 w-3 shrink-0" />
      ) : (
        <span className="text-muted-foreground w-5 shrink-0 text-center text-[10px] font-medium">#{index + 1}</span>
      )}
      <Input
        value={col.label}
        onChange={(e) => onLabelChange(e.target.value)}
        placeholder="라벨"
        className="h-6 min-w-0 flex-1 text-xs"
      />
      <Input
        value={col.width || ""}
        onChange={(e) => onWidthChange(parseInt(e.target.value) || 20)}
        placeholder="20"
        className="h-6 w-14 shrink-0 text-xs"
        min={5}
        max={100}
      />
      <span className="text-muted-foreground shrink-0 text-[10px]">%</span>
      {isNumeric && (
        <label className="flex shrink-0 cursor-pointer items-center gap-1 text-[10px]" title="천 단위 구분자">
          <input
            type="checkbox"
            checked={col.format?.thousandSeparator ?? false}
            onChange={(e) => onFormatChange(e.target.checked)}
            className="h-3 w-3"
          />
          ,
        </label>
      )}
      <Button
        type="button"
        variant="ghost"
        size="sm"
        onClick={onRemove}
        className="text-muted-foreground hover:text-destructive h-5 w-5 shrink-0 p-0"
      >
        <X className="h-3 w-3" />
      </Button>
    </div>
  );
}

// ─── 섹션 헤더 컴포넌트 ───
function SectionHeader({
  icon: Icon,
  title,
  description,
}: {
  icon: React.ComponentType<{ className?: string }>;
  title: string;
  description?: string;
}) {
  return (
    <div className="space-y-1">
      <div className="flex items-center gap-2">
        <Icon className="text-muted-foreground h-4 w-4" />
        <h3 className="text-sm font-semibold">{title}</h3>
      </div>
      {description && <p className="text-muted-foreground text-[10px]">{description}</p>}
    </div>
  );
}

// ─── 수평 Switch Row (토스 패턴) ───
function SwitchRow({
  label,
  description,
  checked,
  onCheckedChange,
}: {
  label: string;
  description?: string;
  checked: boolean;
  onCheckedChange: (checked: boolean) => void;
}) {
  return (
    <div className="flex items-center justify-between py-1">
      <div className="space-y-0.5">
        <p className="text-sm">{label}</p>
        {description && <p className="text-muted-foreground text-[11px]">{description}</p>}
      </div>
      <Switch checked={checked} onCheckedChange={onCheckedChange} />
    </div>
  );
}

// ─── 관계 타입 카드 정의 ───
const RELATION_CARDS = [
  {
    value: "detail" as const,
    icon: Eye,
    title: "선택 시 표시",
    description: "좌측 선택 시에만 우측 데이터 표시",
  },
  {
    value: "join" as const,
    icon: Link2,
    title: "연관 목록",
    description: "미선택 시 전체 / 선택 시 필터링",
  },
] as const;

// ─── 표시 모드 카드 정의 ───
const DISPLAY_MODE_CARDS = [
  {
    value: "list" as const,
    icon: List,
    title: "목록",
    description: "리스트 형태로 표시",
  },
  {
    value: "table" as const,
    icon: LayoutGrid,
    title: "테이블",
    description: "테이블 그리드로 표시",
  },
  {
    value: "custom" as const,
    icon: FileText,
    title: "커스텀",
    description: "자유 배치 모드",
  },
] as const;

// ─── 패널 컬럼 설정 서브 컴포넌트 ───
const PanelColumnSection: React.FC<{
  panelKey: "leftPanel" | "rightPanel";
  columns: SplitPanelLayoutConfig["leftPanel"]["columns"];
  availableColumns: ColumnInfo[];
  entityJoinData: {
    availableColumns: Array<{
      tableName: string;
      columnName: string;
      columnLabel: string;
      dataType: string;
      joinAlias: string;
      suggestedLabel: string;
    }>;
    joinTables: Array<{
      tableName: string;
      currentDisplayColumn: string;
      joinConfig?: any;
      availableColumns: Array<{
        columnName: string;
        columnLabel: string;
        dataType: string;
        inputType?: string;
      }>;
    }>;
  };
  loadingEntityJoins: boolean;
  tableName: string;
  onColumnsChange: (columns: SplitPanelLayoutConfig["leftPanel"]["columns"]) => void;
}> = ({ columns, availableColumns, entityJoinData, loadingEntityJoins, tableName, onColumnsChange }) => {
  const currentColumns = columns || [];

  const addColumn = (colInfo: ColumnInfo) => {
    if (currentColumns.some((c) => c.name === colInfo.columnName)) return;
    onColumnsChange([
      ...currentColumns,
      {
        name: colInfo.columnName,
        label: colInfo.displayName || colInfo.columnName,
        width: 120,
      },
    ]);
  };

  const removeColumn = (name: string) => {
    onColumnsChange(currentColumns.filter((c) => c.name !== name));
  };

  const updateColumn = (name: string, updates: Partial<(typeof currentColumns)[0]>) => {
    onColumnsChange(currentColumns.map((c) => (c.name === name ? { ...c, ...updates } : c)));
  };

  const addEntityColumn = (joinCol: (typeof entityJoinData.availableColumns)[0]) => {
    if (currentColumns.some((c) => c.name === joinCol.joinAlias)) return;
    onColumnsChange([
      ...currentColumns,
      {
        name: joinCol.joinAlias,
        label: joinCol.columnLabel,
        width: 120,
        isEntityJoin: true,
        joinInfo: {
          sourceTable: tableName,
          sourceColumn: joinCol.joinAlias.split("_")[0] || "",
          referenceTable: joinCol.tableName,
          joinAlias: joinCol.joinAlias,
        },
      },
    ]);
  };

  const isNumericType = (name: string) => {
    const col = availableColumns.find((c) => c.columnName === name);
    if (!col) return false;
    const dt = (col.dataType || "").toLowerCase();
    return (
      dt.includes("int") ||
      dt.includes("numeric") ||
      dt.includes("decimal") ||
      dt.includes("float") ||
      dt.includes("double")
    );
  };

  return (
    <div className="space-y-3">
      {/* 컬럼 선택 체크박스 리스트 */}
      {availableColumns.length > 0 && (
        <div className="space-y-2">
          <div className="flex items-center gap-2">
            <Columns3 className="text-muted-foreground h-3.5 w-3.5" />
            <span className="text-xs font-medium">컬럼 선택</span>
          </div>
          <div className="max-h-40 space-y-0.5 overflow-y-auto rounded-md border p-2">
            {availableColumns.map((col) => {
              const isAdded = currentColumns.some((c) => c.name === col.columnName);
              return (
                <div
                  key={col.columnName}
                  className={cn(
                    "hover:bg-muted/50 flex cursor-pointer items-center gap-2 rounded px-2 py-1",
                    isAdded && "bg-primary/10",
                  )}
                  onClick={() => {
                    if (isAdded) removeColumn(col.columnName);
                    else addColumn(col);
                  }}
                >
                  <Checkbox checked={isAdded} className="pointer-events-none h-3.5 w-3.5" />
                  <Database className="text-muted-foreground h-3 w-3 flex-shrink-0" />
                  <span className="truncate text-xs">{col.displayName || col.columnName}</span>
                  <span className="text-muted-foreground/70 ml-auto text-[10px]">{col.input_type || col.dataType}</span>
                </div>
              );
            })}
          </div>
        </div>
      )}

      {/* Entity 조인 컬럼 */}
      {entityJoinData.joinTables.length > 0 && (
        <div className="space-y-2">
          <div className="flex items-center gap-2">
            <Link2 className="text-muted-foreground h-3.5 w-3.5" />
            <span className="text-xs font-medium">Entity 조인 컬럼</span>
            {loadingEntityJoins && <Loader2 className="text-muted-foreground h-3 w-3 animate-spin" />}
          </div>
          <div className="space-y-2">
            {entityJoinData.joinTables.map((joinTable, idx) => (
              <div key={idx} className="space-y-1">
                <div className="text-primary flex items-center gap-2 text-[10px] font-medium">
                  <Link2 className="h-3 w-3" />
                  <span>{joinTable.tableName}</span>
                  <Badge variant="outline" className="text-[10px]">
                    {joinTable.currentDisplayColumn}
                  </Badge>
                </div>
                <div className="border-primary/20 bg-primary/5 max-h-28 space-y-0.5 overflow-y-auto rounded-md border p-2">
                  {joinTable.availableColumns.map((jCol, jIdx) => {
                    const matchingJoinColumn = entityJoinData.availableColumns.find(
                      (jc) => jc.tableName === joinTable.tableName && jc.columnName === jCol.columnName,
                    );
                    if (!matchingJoinColumn) return null;
                    const isAdded = currentColumns.some((c) => c.name === matchingJoinColumn.joinAlias);
                    return (
                      <div
                        key={jIdx}
                        className={cn(
                          "hover:bg-primary/10 flex cursor-pointer items-center gap-2 rounded px-2 py-1",
                          isAdded && "bg-primary/10",
                        )}
                        onClick={() => {
                          if (isAdded) removeColumn(matchingJoinColumn.joinAlias);
                          else addEntityColumn(matchingJoinColumn);
                        }}
                      >
                        <Checkbox checked={isAdded} className="pointer-events-none h-3.5 w-3.5" />
                        <Link2 className="text-primary h-3 w-3 flex-shrink-0" />
                        <span className="truncate text-xs">{jCol.columnLabel}</span>
                        <span className="text-primary/80 ml-auto text-[10px]">{jCol.inputType || jCol.dataType}</span>
                      </div>
                    );
                  })}
                </div>
              </div>
            ))}
          </div>
        </div>
      )}

      {/* 선택된 컬럼 DnD 정렬 */}
      {currentColumns.length > 0 && (
        <div className="space-y-2">
          <div className="flex items-center gap-2">
            <GripVertical className="text-muted-foreground h-3.5 w-3.5" />
            <span className="text-xs font-medium">선택된 컬럼 ({currentColumns.length}개)</span>
          </div>
          <DndContext
            collisionDetection={closestCenter}
            onDragEnd={(event: DragEndEvent) => {
              const { active, over } = event;
              if (!over || active.id === over.id) return;
              const cols = [...currentColumns];
              const oldIdx = cols.findIndex((c) => c.name === active.id);
              const newIdx = cols.findIndex((c) => c.name === over.id);
              if (oldIdx !== -1 && newIdx !== -1) {
                onColumnsChange(arrayMove(cols, oldIdx, newIdx));
              }
            }}
          >
            <SortableContext items={currentColumns.map((c) => c.name)} strategy={verticalListSortingStrategy}>
              <div className="space-y-1">
                {currentColumns.map((col, idx) => (
                  <SortableColumnRow
                    key={col.name}
                    id={col.name}
                    col={col}
                    index={idx}
                    isNumeric={isNumericType(col.name)}
                    isEntityJoin={!!col.isEntityJoin}
                    onLabelChange={(v) => updateColumn(col.name, { label: v })}
                    onWidthChange={(v) => updateColumn(col.name, { width: v })}
                    onFormatChange={(checked) =>
                      updateColumn(col.name, {
                        format: {
                          ...col.format,
                          thousandSeparator: checked,
                        },
                      })
                    }
                    onRemove={() => removeColumn(col.name)}
                  />
                ))}
              </div>
            </SortableContext>
          </DndContext>
        </div>
      )}
    </div>
  );
};

// ─── 테이블 Combobox ───
const TableCombobox: React.FC<{
  value: string;
  allTables: Array<{ tableName: string; displayName: string }>;
  screenTableName?: string;
  loading: boolean;
  onChange: (tableName: string) => void;
}> = ({ value, allTables, screenTableName, loading, onChange }) => {
  const [open, setOpen] = useState(false);

  return (
    <Popover open={open} onOpenChange={setOpen}>
      <PopoverTrigger asChild>
        <Button
          variant="outline"
          role="combobox"
          aria-expanded={open}
          className="h-8 w-full justify-between text-xs"
          disabled={loading}
        >
          <div className="flex items-center gap-2 truncate">
            <Database className="h-3 w-3 shrink-0" />
            <span className="truncate">
              {loading
                ? "테이블 로딩 중..."
                : value
                  ? allTables.find((t) => t.tableName === value)?.displayName || value
                  : "테이블 선택"}
            </span>
          </div>
          <ChevronsUpDown className="ml-2 h-3 w-3 shrink-0 opacity-50" />
        </Button>
      </PopoverTrigger>
      <PopoverContent className="p-0" style={{ width: "var(--radix-popover-trigger-width)" }} align="start">
        <Command>
          <CommandInput placeholder="테이블 검색..." className="text-xs" />
          <CommandList>
            <CommandEmpty className="text-xs">테이블을 찾을 수 없습니다.</CommandEmpty>
            {screenTableName && (
              <CommandGroup heading="화면 기본 테이블">
                <CommandItem
                  value={`${screenTableName} screen-default`}
                  onSelect={() => {
                    onChange(screenTableName);
                    setOpen(false);
                  }}
                  className="text-xs"
                >
                  <Check className={cn("mr-2 h-3 w-3", value === screenTableName ? "opacity-100" : "opacity-0")} />
                  <Database className="text-primary mr-2 h-3.5 w-3.5" />
                  {allTables.find((t) => t.tableName === screenTableName)?.displayName || screenTableName}
                </CommandItem>
              </CommandGroup>
            )}
            <CommandGroup heading="전체 테이블">
              {allTables
                .filter((t) => t.tableName !== screenTableName)
                .map((table) => (
                  <CommandItem
                    key={table.tableName}
                    value={`${table.tableName} ${table.displayName}`}
                    onSelect={() => {
                      onChange(table.tableName);
                      setOpen(false);
                    }}
                    className="text-xs"
                  >
                    <Check className={cn("mr-2 h-3 w-3", value === table.tableName ? "opacity-100" : "opacity-0")} />
                    <div className="flex flex-col">
                      <span>{table.displayName}</span>
                      {table.displayName !== table.tableName && (
                        <span className="text-muted-foreground/70 text-[10px]">{table.tableName}</span>
                      )}
                    </div>
                  </CommandItem>
                ))}
            </CommandGroup>
          </CommandList>
        </Command>
      </PopoverContent>
    </Popover>
  );
};

// ─── 메인 컴포넌트 ───

interface V2SplitPanelLayoutConfigPanelProps {
  config: SplitPanelLayoutConfig;
  onChange: (config: SplitPanelLayoutConfig) => void;
  tables?: TableInfo[];
  screenTableName?: string;
  menuObjid?: number;
}

export const V2SplitPanelLayoutConfigPanel: React.FC<V2SplitPanelLayoutConfigPanelProps> = ({
  config,
  onChange,
  tables,
  screenTableName,
  menuObjid,
}) => {
  // ─── 상태 ───
  const [allTables, setAllTables] = useState<Array<{ tableName: string; displayName: string }>>([]);
  const [loadingTables, setLoadingTables] = useState(false);
  const [loadedTableColumns, setLoadedTableColumns] = useState<Record<string, ColumnInfo[]>>({});
  const [loadingColumns, setLoadingColumns] = useState<Record<string, boolean>>({});
  const [entityJoinColumns, setEntityJoinColumns] = useState<
    Record<
      string,
      {
        availableColumns: Array<{
          tableName: string;
          columnName: string;
          columnLabel: string;
          dataType: string;
          joinAlias: string;
          suggestedLabel: string;
        }>;
        joinTables: Array<{
          tableName: string;
          currentDisplayColumn: string;
          joinConfig?: any;
          availableColumns: Array<{
            columnName: string;
            columnLabel: string;
            dataType: string;
            inputType?: string;
          }>;
        }>;
      }
    >
  >({});
  const [loadingEntityJoins, setLoadingEntityJoins] = useState<Record<string, boolean>>({});

  // Collapsible 상태
  const [leftPanelOpen, setLeftPanelOpen] = useState(false);
  const [rightPanelOpen, setRightPanelOpen] = useState(false);
  const [tabsOpen, setTabsOpen] = useState(false);
  const [advancedOpen, setAdvancedOpen] = useState(false);
  const [leftColumnsOpen, setLeftColumnsOpen] = useState(false);
  const [rightColumnsOpen, setRightColumnsOpen] = useState(false);
  const [leftFilterOpen, setLeftFilterOpen] = useState(false);
  const [rightFilterOpen, setRightFilterOpen] = useState(false);

  // ─── 파생 값 ───
  const relationshipType = config.rightPanel?.relation?.type || "detail";
  const leftTableName = config.leftPanel?.tableName || screenTableName || "";
  const rightTableName = config.rightPanel?.tableName || "";

  const leftTableColumns = useMemo(
    () => (leftTableName ? loadedTableColumns[leftTableName] || [] : []),
    [loadedTableColumns, leftTableName],
  );
  const rightTableColumns = useMemo(
    () => (rightTableName ? loadedTableColumns[rightTableName] || [] : []),
    [loadedTableColumns, rightTableName],
  );

  const leftEntityJoins = useMemo(
    () =>
      entityJoinColumns[leftTableName] || {
        availableColumns: [],
        joinTables: [],
      },
    [entityJoinColumns, leftTableName],
  );
  const rightEntityJoins = useMemo(
    () =>
      entityJoinColumns[rightTableName] || {
        availableColumns: [],
        joinTables: [],
      },
    [entityJoinColumns, rightTableName],
  );

  // ─── 이벤트 발행 래퍼 ───
  const handleChange = useCallback(
    (newConfig: SplitPanelLayoutConfig) => {
      onChange(newConfig);
      if (typeof window !== "undefined") {
        window.dispatchEvent(
          new CustomEvent("componentConfigChanged", {
            detail: { config: newConfig },
          }),
        );
      }
    },
    [onChange],
  );

  const updateConfig = useCallback(
    (updates: Partial<SplitPanelLayoutConfig>) => {
      handleChange({ ...config, ...updates });
    },
    [handleChange, config],
  );

  const updateLeftPanel = useCallback(
    (updates: Partial<SplitPanelLayoutConfig["leftPanel"]>) => {
      handleChange({
        ...config,
        leftPanel: { ...config.leftPanel, ...updates },
      });
    },
    [handleChange, config],
  );

  const updateRightPanel = useCallback(
    (updates: Partial<SplitPanelLayoutConfig["rightPanel"]>) => {
      handleChange({
        ...config,
        rightPanel: { ...config.rightPanel, ...updates },
      });
    },
    [handleChange, config],
  );

  // ─── 테이블 목록 로드 ───
  useEffect(() => {
    const loadAllTables = async () => {
      setLoadingTables(true);
      try {
        const response = await tableManagementApi.getTableList();
        if (response.success && response.data) {
          setAllTables(
            response.data.map((t: any) => ({
              tableName: t.tableName || t.table_name,
              displayName: t.tableLabel || t.displayName || t.tableName || t.table_name,
            })),
          );
        }
      } catch (error) {
        console.error("테이블 목록 로드 실패:", error);
      } finally {
        setLoadingTables(false);
      }
    };
    loadAllTables();
  }, []);

  // 좌측 테이블 초기값 설정
  useEffect(() => {
    if (screenTableName && !config.leftPanel?.tableName) {
      updateLeftPanel({ tableName: screenTableName });
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [screenTableName]);

  // ─── 테이블 컬럼 로드 ───
  const loadTableColumns = useCallback(
    async (tableName: string) => {
      if (loadedTableColumns[tableName] || loadingColumns[tableName]) return;
      setLoadingColumns((prev) => ({ ...prev, [tableName]: true }));
      try {
        const columnsResponse = await tableTypeApi.getColumns(tableName);
        const cols = (columnsResponse || []).map((col: any) => ({
          tableName: col.tableName || tableName,
          columnName: col.columnName || col.column_name,
          displayName: col.displayName || col.columnLabel || col.column_label || col.columnName || col.column_name,
          dataType: col.dataType || col.data_type || col.dbType || "",
          dbType: col.dbType || col.dataType || col.data_type || "",
          webType: col.webType || col.web_type || "text",
          inputType: col.inputType || "direct",
          input_type: col.input_type || col.inputType,
          isNullable: col.isNullable === true || col.isNullable === "Y",
          isPrimaryKey: col.isPrimaryKey ?? false,
          referenceTable: col.referenceTable || col.reference_table,
        })) as ColumnInfo[];
        setLoadedTableColumns((prev) => ({ ...prev, [tableName]: cols }));
        await loadEntityJoinColumnsForTable(tableName);
      } catch (error) {
        console.error(`테이블 ${tableName} 컬럼 로드 실패:`, error);
        setLoadedTableColumns((prev) => ({ ...prev, [tableName]: [] }));
      } finally {
        setLoadingColumns((prev) => ({ ...prev, [tableName]: false }));
      }
    },
    [loadedTableColumns, loadingColumns],
  );

  const loadEntityJoinColumnsForTable = useCallback(
    async (tableName: string) => {
      if (entityJoinColumns[tableName] || loadingEntityJoins[tableName]) return;
      setLoadingEntityJoins((prev) => ({ ...prev, [tableName]: true }));
      try {
        const result = await entityJoinApi.getEntityJoinColumns(tableName);
        setEntityJoinColumns((prev) => ({
          ...prev,
          [tableName]: {
            availableColumns: result.availableColumns || [],
            joinTables: result.joinTables || [],
          },
        }));
      } catch (error) {
        console.error(`Entity 조인 컬럼 조회 실패 (${tableName}):`, error);
        setEntityJoinColumns((prev) => ({
          ...prev,
          [tableName]: { availableColumns: [], joinTables: [] },
        }));
      } finally {
        setLoadingEntityJoins((prev) => ({ ...prev, [tableName]: false }));
      }
    },
    [entityJoinColumns, loadingEntityJoins],
  );

  // 좌측/우측 테이블 변경 시 컬럼 로드
  useEffect(() => {
    if (leftTableName) loadTableColumns(leftTableName);
  }, [leftTableName, loadTableColumns]);

  useEffect(() => {
    if (rightTableName) loadTableColumns(rightTableName);
  }, [rightTableName, loadTableColumns]);

  // ─── 추가 탭 관리 ───
  const addTab = useCallback(() => {
    const currentTabs = config.rightPanel?.additionalTabs || [];
    const newTab: AdditionalTabConfig = {
      tabId: `tab_${Date.now()}`,
      label: `탭 ${currentTabs.length + 1}`,
      title: `탭 ${currentTabs.length + 1}`,
    };
    updateRightPanel({
      additionalTabs: [...currentTabs, newTab],
    });
  }, [config.rightPanel?.additionalTabs, updateRightPanel]);

  const updateTab = useCallback(
    (tabIndex: number, updates: Partial<AdditionalTabConfig>) => {
      const newTabs = [...(config.rightPanel?.additionalTabs || [])];
      newTabs[tabIndex] = { ...newTabs[tabIndex], ...updates };
      updateRightPanel({ additionalTabs: newTabs });
    },
    [config.rightPanel?.additionalTabs, updateRightPanel],
  );

  const removeTab = useCallback(
    (tabIndex: number) => {
      const newTabs = config.rightPanel?.additionalTabs?.filter((_, i) => i !== tabIndex) || [];
      updateRightPanel({ additionalTabs: newTabs });
    },
    [config.rightPanel?.additionalTabs, updateRightPanel],
  );

  // ─── 렌더링 ───
  return (
    <div className="space-y-4">
      {/* ═══════════════════════════════════════ */}
      {/* 1단계: 관계 타입 선택 (카드 UI)          */}
      {/* ═══════════════════════════════════════ */}
      <div className="space-y-3">
        <SectionHeader
          icon={SplitSquareHorizontal}
          title="패널 관계 타입"
          description="좌측 선택 시 우측에 어떻게 데이터를 보여줄지 결정합니다"
        />
        <Separator />
        <div className="grid grid-cols-2 gap-2">
          {RELATION_CARDS.map((card) => {
            const Icon = card.icon;
            const isSelected = relationshipType === card.value;
            return (
              <button
                key={card.value}
                type="button"
                onClick={() =>
                  updateRightPanel({
                    relation: { ...config.rightPanel?.relation, type: card.value },
                  })
                }
                className={cn(
                  "flex min-h-[80px] flex-col items-center justify-center rounded-lg border p-3 text-center transition-all",
                  isSelected
                    ? "border-primary bg-primary/5 ring-primary/20 ring-1"
                    : "border-border hover:border-primary/50 hover:bg-muted/50",
                )}
              >
                <Icon className="text-primary mb-1.5 h-5 w-5" />
                <span className="text-xs leading-tight font-medium">{card.title}</span>
                <span className="text-muted-foreground mt-0.5 text-[10px] leading-tight">{card.description}</span>
              </button>
            );
          })}
        </div>
      </div>

      {/* ═══════════════════════════════════════ */}
      {/* 2단계: 레이아웃 설정                     */}
      {/* ═══════════════════════════════════════ */}
      <div className="space-y-3">
        <SectionHeader icon={SplitSquareHorizontal} title="레이아웃" description="패널 비율과 크기 조절 옵션" />
        <Separator />

        <div className="space-y-2">
          <div className="flex items-center justify-between">
            <span className="text-muted-foreground text-xs">좌측 패널 너비</span>
            <span className="text-xs font-medium">{config.splitRatio || 30}%</span>
          </div>
          <Slider
            value={[config.splitRatio || 30]}
            onValueChange={(value) => updateConfig({ splitRatio: value[0] })}
            min={20}
            max={80}
            step={5}
          />
        </div>

        <SwitchRow
          label="크기 조절 가능"
          description="사용자가 드래그로 패널 크기를 변경"
          checked={config.resizable ?? true}
          onCheckedChange={(checked) => updateConfig({ resizable: checked })}
        />

        <SwitchRow
          label="자동 데이터 로드"
          description="화면 진입 시 자동으로 데이터 로드"
          checked={config.autoLoad ?? true}
          onCheckedChange={(checked) => updateConfig({ autoLoad: checked })}
        />
      </div>

      {/* ═══════════════════════════════════════ */}
      {/* 3단계: 좌측 패널 (접이식)                */}
      {/* ═══════════════════════════════════════ */}
      <Collapsible open={leftPanelOpen} onOpenChange={setLeftPanelOpen}>
        <CollapsibleTrigger asChild>
          <button
            type="button"
            className="bg-muted/30 hover:bg-muted/50 flex w-full items-center justify-between rounded-lg border px-4 py-2.5 text-left transition-colors"
          >
            <div className="flex items-center gap-2">
              <PanelLeft className="text-muted-foreground h-4 w-4" />
              <div>
                <span className="truncate text-sm font-medium">좌측 패널 (마스터)</span>
                <p className="text-muted-foreground truncate text-[10px]">{leftTableName || "미설정"}</p>
              </div>
              <Badge variant="secondary" className="h-5 text-[10px]">
                {config.leftPanel?.columns?.length || 0}개 컬럼
              </Badge>
            </div>
            <ChevronDown
              className={cn(
                "text-muted-foreground h-4 w-4 transition-transform duration-200",
                leftPanelOpen && "rotate-180",
              )}
            />
          </button>
        </CollapsibleTrigger>
        <CollapsibleContent>
          <div className="space-y-4 rounded-b-lg border border-t-0 p-4">
            {/* 좌측 패널 제목 */}
            <div className="space-y-1.5">
              <Label className="truncate text-xs">패널 제목</Label>
              <Input
                value={config.leftPanel?.title || ""}
                onChange={(e) => updateLeftPanel({ title: e.target.value })}
                placeholder="좌측 패널 제목"
                className="h-8 text-xs"
              />
            </div>

            {/* 좌측 테이블 선택 */}
            <div className="space-y-1.5">
              <Label className="truncate text-xs">데이터 테이블</Label>
              <TableCombobox
                value={leftTableName}
                allTables={allTables}
                screenTableName={screenTableName}
                loading={loadingTables}
                onChange={(tableName) => updateLeftPanel({ tableName, columns: [] })}
              />
              {screenTableName && leftTableName !== screenTableName && (
                <div className="flex items-center justify-between rounded bg-amber-50 px-2 py-1 dark:bg-amber-950/30">
                  <span className="text-[10px] text-amber-700 dark:text-amber-400">
                    기본 테이블({screenTableName})과 다름
                  </span>
                  <Button
                    variant="ghost"
                    size="sm"
                    className="h-5 px-1.5 text-[10px] text-amber-700"
                    onClick={() =>
                      updateLeftPanel({
                        tableName: screenTableName,
                        columns: [],
                      })
                    }
                  >
                    기본으로
                  </Button>
                </div>
              )}
            </div>

            {/* 표시 모드 */}
            <div className="space-y-1.5">
              <Label className="truncate text-xs">표시 모드</Label>
              <div className="grid grid-cols-3 gap-1.5">
                {DISPLAY_MODE_CARDS.map((card) => {
                  const Icon = card.icon;
                  const currentMode = config.leftPanel?.displayMode || "list";
                  const isSelected = currentMode === card.value;
                  return (
                    <button
                      key={card.value}
                      type="button"
                      onClick={() => updateLeftPanel({ displayMode: card.value })}
                      className={cn(
                        "flex flex-col items-center rounded-md border p-2 text-center transition-all",
                        isSelected
                          ? "border-primary bg-primary/5 ring-primary/20 ring-1"
                          : "border-border hover:border-primary/50",
                      )}
                    >
                      <Icon className="text-primary mb-1 h-4 w-4" />
                      <span className="text-[10px] font-medium">{card.title}</span>
                    </button>
                  );
                })}
              </div>
            </div>

            {/* 좌측 패널 기능 토글 */}
            <div className="space-y-1">
              <SwitchRow
                label="검색"
                checked={config.leftPanel?.showSearch ?? false}
                onCheckedChange={(checked) => updateLeftPanel({ showSearch: checked })}
              />
              <SwitchRow
                label="추가 버튼"
                checked={config.leftPanel?.showAdd ?? false}
                onCheckedChange={(checked) => updateLeftPanel({ showAdd: checked })}
              />
              <SwitchRow
                label="수정 버튼"
                checked={config.leftPanel?.showEdit ?? true}
                onCheckedChange={(checked) => updateLeftPanel({ showEdit: checked })}
              />
              <SwitchRow
                label="삭제 버튼"
                checked={config.leftPanel?.showDelete ?? true}
                onCheckedChange={(checked) => updateLeftPanel({ showDelete: checked })}
              />
              <SwitchRow
                label="하위 항목 추가 버튼"
                description="각 항목에 + 버튼 표시"
                checked={config.leftPanel?.showItemAddButton ?? false}
                onCheckedChange={(checked) => updateLeftPanel({ showItemAddButton: checked })}
              />
              <SwitchRow
                label="페이징 처리"
                description="서버 페이지 단위 조회 (필터/정렬/계층 비활성화)"
                checked={config.leftPanel?.pagination?.enabled ?? false}
                onCheckedChange={(checked) =>
                  updateLeftPanel({
                    pagination: {
                      ...config.leftPanel?.pagination,
                      enabled: checked,
                      pageSize: config.leftPanel?.pagination?.pageSize ?? 20,
                    },
                  })
                }
              />
              {config.leftPanel?.pagination?.enabled && (
                <div className="ml-4 space-y-1">
                  <Label className="text-[10px]">페이지 크기</Label>
                  <Input
                    type="number"
                    min={1}
                    max={MAX_LOAD_ALL_SIZE}
                    value={config.leftPanel?.pagination?.pageSize ?? 20}
                    onChange={(e) =>
                      updateLeftPanel({
                        pagination: {
                          ...config.leftPanel?.pagination,
                          enabled: true,
                          pageSize: Math.min(MAX_LOAD_ALL_SIZE, Math.max(1, Number(e.target.value) || 20)),
                        },
                      })
                    }
                    className="h-7 w-24 text-xs"
                  />
                </div>
              )}
            </div>

            {/* 좌측 패널 컬럼 설정 (접이식) */}
            {config.leftPanel?.displayMode !== "custom" && (
              <Collapsible open={leftColumnsOpen} onOpenChange={setLeftColumnsOpen}>
                <CollapsibleTrigger asChild>
                  <button
                    type="button"
                    className="bg-muted/20 hover:bg-muted/40 flex w-full items-center justify-between rounded-md border px-3 py-2 text-left transition-colors"
                  >
                    <div className="flex items-center gap-2">
                      <Columns3 className="text-muted-foreground h-3.5 w-3.5" />
                      <span className="text-xs font-medium">
                        컬럼 설정 ({config.leftPanel?.columns?.length || 0}개)
                      </span>
                    </div>
                    <ChevronDown
                      className={cn(
                        "text-muted-foreground h-3.5 w-3.5 transition-transform duration-200",
                        leftColumnsOpen && "rotate-180",
                      )}
                    />
                  </button>
                </CollapsibleTrigger>
                <CollapsibleContent>
                  <div className="mt-2 rounded-md border p-3">
                    {loadingColumns[leftTableName] ? (
                      <div className="text-muted-foreground flex items-center gap-2 py-4 text-xs">
                        <Loader2 className="h-3 w-3 animate-spin" />
                        컬럼 로딩 중...
                      </div>
                    ) : leftTableColumns.length === 0 ? (
                      <p className="text-muted-foreground py-4 text-center text-xs">
                        테이블을 선택하면 컬럼이 표시됩니다
                      </p>
                    ) : (
                      <PanelColumnSection
                        panelKey="leftPanel"
                        columns={config.leftPanel?.columns}
                        availableColumns={leftTableColumns}
                        entityJoinData={leftEntityJoins}
                        loadingEntityJoins={loadingEntityJoins[leftTableName] || false}
                        tableName={leftTableName}
                        onColumnsChange={(columns) => updateLeftPanel({ columns })}
                      />
                    )}
                  </div>
                </CollapsibleContent>
              </Collapsible>
            )}

            {/* 좌측 패널 데이터 필터 (접이식) */}
            <Collapsible open={leftFilterOpen} onOpenChange={setLeftFilterOpen}>
              <CollapsibleTrigger asChild>
                <button
                  type="button"
                  className="bg-muted/20 hover:bg-muted/40 flex w-full items-center justify-between rounded-md border px-3 py-2 text-left transition-colors"
                >
                  <div className="flex items-center gap-2">
                    <Search className="text-muted-foreground h-3.5 w-3.5" />
                    <span className="text-xs font-medium">데이터 필터</span>
                  </div>
                  <ChevronDown
                    className={cn(
                      "text-muted-foreground h-3.5 w-3.5 transition-transform duration-200",
                      leftFilterOpen && "rotate-180",
                    )}
                  />
                </button>
              </CollapsibleTrigger>
              <CollapsibleContent>
                <div className="mt-2 rounded-md border p-3">
                  <DataFilterConfigPanel
                    tableName={leftTableName}
                    columns={leftTableColumns}
                    config={config.leftPanel?.dataFilter}
                    onConfigChange={(dataFilter) => updateLeftPanel({ dataFilter })}
                  />
                </div>
              </CollapsibleContent>
            </Collapsible>
          </div>
        </CollapsibleContent>
      </Collapsible>

      {/* ═══════════════════════════════════════ */}
      {/* 4단계: 우측 패널 (접이식)                */}
      {/* ═══════════════════════════════════════ */}
      <Collapsible open={rightPanelOpen} onOpenChange={setRightPanelOpen}>
        <CollapsibleTrigger asChild>
          <button
            type="button"
            className="bg-muted/30 hover:bg-muted/50 flex w-full items-center justify-between rounded-lg border px-4 py-2.5 text-left transition-colors"
          >
            <div className="flex items-center gap-2">
              <PanelRight className="text-muted-foreground h-4 w-4" />
              <div>
                <span className="truncate text-sm font-medium">우측 패널 (디테일)</span>
                <p className="text-muted-foreground truncate text-[10px]">{rightTableName || "미설정"}</p>
              </div>
              <Badge variant="secondary" className="h-5 text-[10px]">
                {config.rightPanel?.columns?.length || 0}개 컬럼
              </Badge>
            </div>
            <ChevronDown
              className={cn(
                "text-muted-foreground h-4 w-4 transition-transform duration-200",
                rightPanelOpen && "rotate-180",
              )}
            />
          </button>
        </CollapsibleTrigger>
        <CollapsibleContent>
          <div className="space-y-4 rounded-b-lg border border-t-0 p-4">
            {/* 우측 패널 제목 */}
            <div className="space-y-1.5">
              <Label className="truncate text-xs">패널 제목</Label>
              <Input
                value={config.rightPanel?.title || ""}
                onChange={(e) => updateRightPanel({ title: e.target.value })}
                placeholder="우측 패널 제목"
                className="h-8 text-xs"
              />
            </div>

            {/* 우측 테이블 선택 */}
            <div className="space-y-1.5">
              <Label className="truncate text-xs">데이터 테이블</Label>
              <TableCombobox
                value={rightTableName}
                allTables={allTables}
                screenTableName={screenTableName}
                loading={loadingTables}
                onChange={(tableName) => updateRightPanel({ tableName, columns: [] })}
              />
            </div>

            {/* 표시 모드 */}
            <div className="space-y-1.5">
              <Label className="truncate text-xs">표시 모드</Label>
              <div className="grid grid-cols-3 gap-1.5">
                {DISPLAY_MODE_CARDS.map((card) => {
                  const Icon = card.icon;
                  const currentMode = config.rightPanel?.displayMode || "list";
                  const isSelected = currentMode === card.value;
                  return (
                    <button
                      key={card.value}
                      type="button"
                      onClick={() => updateRightPanel({ displayMode: card.value })}
                      className={cn(
                        "flex flex-col items-center rounded-md border p-2 text-center transition-all",
                        isSelected
                          ? "border-primary bg-primary/5 ring-primary/20 ring-1"
                          : "border-border hover:border-primary/50",
                      )}
                    >
                      <Icon className="text-primary mb-1 h-4 w-4" />
                      <span className="text-[10px] font-medium">{card.title}</span>
                    </button>
                  );
                })}
              </div>
            </div>

            {/* 연결 키 설정 */}
            {rightTableName && (
              <div className="space-y-2">
                <div className="flex items-center gap-2">
                  <Link2 className="text-muted-foreground h-3.5 w-3.5" />
                  <span className="text-xs font-medium">테이블 연결 키</span>
                </div>
                <p className="text-muted-foreground text-[10px]">좌측 패널과 우측 패널을 연결할 컬럼을 설정합니다</p>

                {/* 기존 키 목록 */}
                {(config.rightPanel?.relation?.keys || []).map((key, idx) => (
                  <div key={idx} className="flex items-center gap-2">
                    <Select
                      value={key.leftColumn || ""}
                      onValueChange={(v) => {
                        const keys = [...(config.rightPanel?.relation?.keys || [])];
                        keys[idx] = { ...keys[idx], leftColumn: v };
                        updateRightPanel({
                          relation: {
                            ...config.rightPanel?.relation,
                            keys,
                          },
                        });
                      }}
                    >
                      <SelectTrigger className="h-7 flex-1 text-[11px]">
                        <SelectValue placeholder="좌측 컬럼" />
                      </SelectTrigger>
                      <SelectContent>
                        {leftTableColumns.map((col) => (
                          <SelectItem key={col.columnName} value={col.columnName}>
                            {col.displayName || col.columnName}
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>

                    <ArrowRight className="text-muted-foreground h-3 w-3 shrink-0" />

                    <Select
                      value={key.rightColumn || ""}
                      onValueChange={(v) => {
                        const keys = [...(config.rightPanel?.relation?.keys || [])];
                        keys[idx] = { ...keys[idx], rightColumn: v };
                        updateRightPanel({
                          relation: {
                            ...config.rightPanel?.relation,
                            keys,
                          },
                        });
                      }}
                    >
                      <SelectTrigger className="h-7 flex-1 text-[11px]">
                        <SelectValue placeholder="우측 컬럼" />
                      </SelectTrigger>
                      <SelectContent>
                        {rightTableColumns.map((col) => (
                          <SelectItem key={col.columnName} value={col.columnName}>
                            {col.displayName || col.columnName}
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>

                    <Button
                      type="button"
                      variant="ghost"
                      size="sm"
                      onClick={() => {
                        const keys = config.rightPanel?.relation?.keys?.filter((_, i) => i !== idx) || [];
                        updateRightPanel({
                          relation: {
                            ...config.rightPanel?.relation,
                            keys,
                          },
                        });
                      }}
                      className="text-destructive h-7 w-7 shrink-0 p-0"
                    >
                      <Trash2 className="h-3 w-3" />
                    </Button>
                  </div>
                ))}

                {/* 키가 없을 때 단일키 호환 */}
                {(!config.rightPanel?.relation?.keys || config.rightPanel.relation.keys.length === 0) && (
                  <div className="flex items-center gap-2">
                    <Select
                      value={config.rightPanel?.relation?.leftColumn || ""}
                      onValueChange={(v) =>
                        updateRightPanel({
                          relation: {
                            ...config.rightPanel?.relation,
                            leftColumn: v,
                          },
                        })
                      }
                    >
                      <SelectTrigger className="h-7 flex-1 text-[11px]">
                        <SelectValue placeholder="좌측 컬럼" />
                      </SelectTrigger>
                      <SelectContent>
                        {leftTableColumns.map((col) => (
                          <SelectItem key={col.columnName} value={col.columnName}>
                            {col.displayName || col.columnName}
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>

                    <ArrowRight className="text-muted-foreground h-3 w-3 shrink-0" />

                    <Select
                      value={config.rightPanel?.relation?.rightColumn || ""}
                      onValueChange={(v) =>
                        updateRightPanel({
                          relation: {
                            ...config.rightPanel?.relation,
                            rightColumn: v,
                          },
                        })
                      }
                    >
                      <SelectTrigger className="h-7 flex-1 text-[11px]">
                        <SelectValue placeholder="우측 컬럼" />
                      </SelectTrigger>
                      <SelectContent>
                        {rightTableColumns.map((col) => (
                          <SelectItem key={col.columnName} value={col.columnName}>
                            {col.displayName || col.columnName}
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </div>
                )}

                <Button
                  type="button"
                  variant="ghost"
                  size="sm"
                  onClick={() => {
                    const currentKeys = config.rightPanel?.relation?.keys || [];
                    updateRightPanel({
                      relation: {
                        ...config.rightPanel?.relation,
                        keys: [...currentKeys, { leftColumn: "", rightColumn: "" }],
                      },
                    });
                  }}
                  className="h-7 w-full text-xs"
                >
                  <Plus className="mr-1 h-3 w-3" />
                  복합키 추가
                </Button>
              </div>
            )}

            {/* 우측 패널 기능 토글 */}
            <div className="space-y-1">
              <SwitchRow
                label="검색"
                checked={config.rightPanel?.showSearch ?? false}
                onCheckedChange={(checked) => updateRightPanel({ showSearch: checked })}
              />
              <SwitchRow
                label="추가 버튼"
                checked={config.rightPanel?.showAdd ?? false}
                onCheckedChange={(checked) => updateRightPanel({ showAdd: checked })}
              />
              <SwitchRow
                label="수정 버튼"
                checked={config.rightPanel?.showEdit ?? config.rightPanel?.editButton?.enabled ?? false}
                onCheckedChange={(checked) =>
                  updateRightPanel({
                    showEdit: checked,
                    editButton: { ...config.rightPanel?.editButton!, enabled: checked },
                  })
                }
              />
              <SwitchRow
                label="삭제 버튼"
                checked={config.rightPanel?.showDelete ?? config.rightPanel?.deleteButton?.enabled ?? false}
                onCheckedChange={(checked) =>
                  updateRightPanel({
                    showDelete: checked,
                    deleteButton: { ...config.rightPanel?.deleteButton!, enabled: checked },
                  })
                }
              />
              <SwitchRow
                label="페이징 처리"
                description="서버 페이지 단위 조회 (탭 포함 적용)"
                checked={config.rightPanel?.pagination?.enabled ?? false}
                onCheckedChange={(checked) =>
                  updateRightPanel({
                    pagination: {
                      ...config.rightPanel?.pagination,
                      enabled: checked,
                      pageSize: config.rightPanel?.pagination?.pageSize ?? 20,
                    },
                  })
                }
              />
              {config.rightPanel?.pagination?.enabled && (
                <div className="ml-4 space-y-1">
                  <Label className="text-[10px]">페이지 크기</Label>
                  <Input
                    type="number"
                    min={1}
                    max={MAX_LOAD_ALL_SIZE}
                    value={config.rightPanel?.pagination?.pageSize ?? 20}
                    onChange={(e) =>
                      updateRightPanel({
                        pagination: {
                          ...config.rightPanel?.pagination,
                          enabled: true,
                          pageSize: Math.min(MAX_LOAD_ALL_SIZE, Math.max(1, Number(e.target.value) || 20)),
                        },
                      })
                    }
                    className="h-7 w-24 text-xs"
                  />
                </div>
              )}
            </div>

            {/* 우측 패널 컬럼 설정 (접이식) */}
            {config.rightPanel?.displayMode !== "custom" && (
              <Collapsible open={rightColumnsOpen} onOpenChange={setRightColumnsOpen}>
                <CollapsibleTrigger asChild>
                  <button
                    type="button"
                    className="bg-muted/20 hover:bg-muted/40 flex w-full items-center justify-between rounded-md border px-3 py-2 text-left transition-colors"
                  >
                    <div className="flex items-center gap-2">
                      <Columns3 className="text-muted-foreground h-3.5 w-3.5" />
                      <span className="text-xs font-medium">
                        컬럼 설정 ({config.rightPanel?.columns?.length || 0}개)
                      </span>
                    </div>
                    <ChevronDown
                      className={cn(
                        "text-muted-foreground h-3.5 w-3.5 transition-transform duration-200",
                        rightColumnsOpen && "rotate-180",
                      )}
                    />
                  </button>
                </CollapsibleTrigger>
                <CollapsibleContent>
                  <div className="mt-2 rounded-md border p-3">
                    {loadingColumns[rightTableName] ? (
                      <div className="text-muted-foreground flex items-center gap-2 py-4 text-xs">
                        <Loader2 className="h-3 w-3 animate-spin" />
                        컬럼 로딩 중...
                      </div>
                    ) : rightTableColumns.length === 0 ? (
                      <p className="text-muted-foreground py-4 text-center text-xs">
                        테이블을 선택하면 컬럼이 표시됩니다
                      </p>
                    ) : (
                      <PanelColumnSection
                        panelKey="rightPanel"
                        columns={config.rightPanel?.columns}
                        availableColumns={rightTableColumns}
                        entityJoinData={rightEntityJoins}
                        loadingEntityJoins={loadingEntityJoins[rightTableName] || false}
                        tableName={rightTableName}
                        onColumnsChange={(columns) => updateRightPanel({ columns })}
                      />
                    )}
                  </div>
                </CollapsibleContent>
              </Collapsible>
            )}

            {/* 우측 패널 데이터 필터 (접이식) */}
            <Collapsible open={rightFilterOpen} onOpenChange={setRightFilterOpen}>
              <CollapsibleTrigger asChild>
                <button
                  type="button"
                  className="bg-muted/20 hover:bg-muted/40 flex w-full items-center justify-between rounded-md border px-3 py-2 text-left transition-colors"
                >
                  <div className="flex items-center gap-2">
                    <Search className="text-muted-foreground h-3.5 w-3.5" />
                    <span className="text-xs font-medium">데이터 필터</span>
                  </div>
                  <ChevronDown
                    className={cn(
                      "text-muted-foreground h-3.5 w-3.5 transition-transform duration-200",
                      rightFilterOpen && "rotate-180",
                    )}
                  />
                </button>
              </CollapsibleTrigger>
              <CollapsibleContent>
                <div className="mt-2 rounded-md border p-3">
                  <DataFilterConfigPanel
                    tableName={rightTableName}
                    columns={rightTableColumns}
                    config={config.rightPanel?.dataFilter}
                    onConfigChange={(dataFilter) => updateRightPanel({ dataFilter })}
                  />
                </div>
              </CollapsibleContent>
            </Collapsible>

            {/* 우측 패널 추가 설정 (접이식) */}
            <Collapsible>
              <CollapsibleTrigger asChild>
                <button
                  type="button"
                  className="bg-muted/20 hover:bg-muted/40 flex w-full items-center justify-between rounded-md border px-3 py-2 text-left transition-colors"
                >
                  <div className="flex items-center gap-2">
                    <Settings className="text-muted-foreground h-3.5 w-3.5" />
                    <span className="text-xs font-medium">추가 설정 (중복제거/버튼)</span>
                  </div>
                  <ChevronDown className="text-muted-foreground h-3.5 w-3.5" />
                </button>
              </CollapsibleTrigger>
              <CollapsibleContent>
                <div className="mt-2 space-y-3 rounded-md border p-3">
                  {/* 중복 제거 */}
                  <SwitchRow
                    label="중복 제거"
                    description="같은 값의 행을 하나로 합쳐서 표시"
                    checked={config.rightPanel?.deduplication?.enabled ?? false}
                    onCheckedChange={(checked) =>
                      updateRightPanel({
                        deduplication: {
                          ...config.rightPanel?.deduplication,
                          enabled: checked,
                          groupByColumn: config.rightPanel?.deduplication?.groupByColumn || "",
                          keepStrategy: config.rightPanel?.deduplication?.keepStrategy || "latest",
                        },
                      })
                    }
                  />

                  {config.rightPanel?.deduplication?.enabled && (
                    <div className="border-primary/20 ml-4 space-y-2 border-l-2 pl-3">
                      <div className="flex items-center justify-between">
                        <span className="text-muted-foreground text-xs">기준 컬럼</span>
                        <Select
                          value={config.rightPanel?.deduplication?.groupByColumn || ""}
                          onValueChange={(v) =>
                            updateRightPanel({
                              deduplication: {
                                ...config.rightPanel?.deduplication!,
                                groupByColumn: v,
                              },
                            })
                          }
                        >
                          <SelectTrigger className="h-7 w-[140px] text-[11px]">
                            <SelectValue placeholder="컬럼 선택" />
                          </SelectTrigger>
                          <SelectContent>
                            {rightTableColumns.map((col) => (
                              <SelectItem key={col.columnName} value={col.columnName}>
                                {col.displayName || col.columnName}
                              </SelectItem>
                            ))}
                          </SelectContent>
                        </Select>
                      </div>
                      <div className="flex items-center justify-between">
                        <span className="text-muted-foreground text-xs">유지 전략</span>
                        <Select
                          value={config.rightPanel?.deduplication?.keepStrategy || "latest"}
                          onValueChange={(v) =>
                            updateRightPanel({
                              deduplication: {
                                ...config.rightPanel?.deduplication!,
                                keepStrategy: v as any,
                              },
                            })
                          }
                        >
                          <SelectTrigger className="h-7 w-[140px] text-[11px]">
                            <SelectValue />
                          </SelectTrigger>
                          <SelectContent>
                            <SelectItem value="latest">최신</SelectItem>
                            <SelectItem value="earliest">최초</SelectItem>
                            <SelectItem value="base_price">기본가</SelectItem>
                            <SelectItem value="current_date">현재 날짜</SelectItem>
                          </SelectContent>
                        </Select>
                      </div>
                    </div>
                  )}

                  <Separator />

                  {/* 수정 버튼 설정 */}
                  <SwitchRow
                    label="수정 버튼 모달"
                    description="별도 화면으로 수정 모달 표시"
                    checked={config.rightPanel?.editButton?.mode === "modal"}
                    onCheckedChange={(checked) =>
                      updateRightPanel({
                        editButton: {
                          ...config.rightPanel?.editButton,
                          enabled: config.rightPanel?.editButton?.enabled ?? true,
                          mode: checked ? "modal" : "auto",
                        },
                      })
                    }
                  />

                  {config.rightPanel?.editButton?.mode === "modal" && (
                    <div className="border-primary/20 ml-4 border-l-2 pl-3">
                      <div className="flex items-center justify-between">
                        <span className="text-muted-foreground text-xs">모달 화면 ID</span>
                        <Input
                          type="number"
                          value={config.rightPanel?.editButton?.modalScreenId || ""}
                          onChange={(e) =>
                            updateRightPanel({
                              editButton: {
                                ...config.rightPanel?.editButton!,
                                modalScreenId: parseInt(e.target.value) || undefined,
                              },
                            })
                          }
                          placeholder="화면 ID"
                          className="h-7 w-[100px] text-xs"
                        />
                      </div>
                    </div>
                  )}

                  {/* 추가 버튼 설정 */}
                  <SwitchRow
                    label="추가 버튼 모달"
                    description="별도 화면으로 추가 모달 표시"
                    checked={config.rightPanel?.addButton?.mode === "modal"}
                    onCheckedChange={(checked) =>
                      updateRightPanel({
                        addButton: {
                          ...config.rightPanel?.addButton,
                          enabled: config.rightPanel?.addButton?.enabled ?? true,
                          mode: checked ? "modal" : "auto",
                        },
                      })
                    }
                  />

                  {config.rightPanel?.addButton?.mode === "modal" && (
                    <div className="border-primary/20 ml-4 border-l-2 pl-3">
                      <div className="flex items-center justify-between">
                        <span className="text-muted-foreground text-xs">모달 화면 ID</span>
                        <Input
                          type="number"
                          value={config.rightPanel?.addButton?.modalScreenId || ""}
                          onChange={(e) =>
                            updateRightPanel({
                              addButton: {
                                ...config.rightPanel?.addButton!,
                                modalScreenId: parseInt(e.target.value) || undefined,
                              },
                            })
                          }
                          placeholder="화면 ID"
                          className="h-7 w-[100px] text-xs"
                        />
                      </div>
                    </div>
                  )}

                  {/* 삭제 버튼 설정 */}
                  <SwitchRow
                    label="삭제 확인 메시지"
                    checked={!!config.rightPanel?.deleteButton?.confirmMessage}
                    onCheckedChange={(checked) =>
                      updateRightPanel({
                        deleteButton: {
                          ...config.rightPanel?.deleteButton,
                          enabled: config.rightPanel?.deleteButton?.enabled ?? true,
                          confirmMessage: checked ? "정말 삭제하시겠습니까?" : undefined,
                        },
                      })
                    }
                  />

                  {config.rightPanel?.deleteButton?.confirmMessage && (
                    <div className="border-primary/20 ml-4 border-l-2 pl-3">
                      <Input
                        value={config.rightPanel.deleteButton.confirmMessage}
                        onChange={(e) =>
                          updateRightPanel({
                            deleteButton: {
                              ...config.rightPanel?.deleteButton!,
                              confirmMessage: e.target.value,
                            },
                          })
                        }
                        placeholder="삭제 확인 메시지"
                        className="h-7 text-xs"
                      />
                    </div>
                  )}

                  <Separator />

                  {/* 추가 시 대상 테이블 (N:M 관계) */}
                  <div className="space-y-2">
                    <span className="text-xs font-medium">추가 대상 설정 (N:M)</span>
                    <p className="text-muted-foreground text-[10px]">
                      추가 버튼 클릭 시 실제 INSERT할 테이블을 지정합니다
                    </p>
                    <div className="space-y-1.5">
                      <div className="flex items-center justify-between">
                        <span className="text-muted-foreground text-xs">대상 테이블</span>
                        <Input
                          value={config.rightPanel?.addConfig?.targetTable || ""}
                          onChange={(e) =>
                            updateRightPanel({
                              addConfig: {
                                ...config.rightPanel?.addConfig,
                                targetTable: e.target.value || undefined,
                              },
                            })
                          }
                          placeholder="미설정 시 우측 테이블"
                          className="h-7 w-[160px] text-xs"
                        />
                      </div>
                      <div className="flex items-center justify-between">
                        <span className="text-muted-foreground text-xs">좌측값 컬럼</span>
                        <Input
                          value={config.rightPanel?.addConfig?.leftPanelColumn || ""}
                          onChange={(e) =>
                            updateRightPanel({
                              addConfig: {
                                ...config.rightPanel?.addConfig,
                                leftPanelColumn: e.target.value || undefined,
                              },
                            })
                          }
                          placeholder="좌측 컬럼명"
                          className="h-7 w-[160px] text-xs"
                        />
                      </div>
                      <div className="flex items-center justify-between">
                        <span className="text-muted-foreground text-xs">대상 컬럼</span>
                        <Input
                          value={config.rightPanel?.addConfig?.targetColumn || ""}
                          onChange={(e) =>
                            updateRightPanel({
                              addConfig: {
                                ...config.rightPanel?.addConfig,
                                targetColumn: e.target.value || undefined,
                              },
                            })
                          }
                          placeholder="대상 컬럼명"
                          className="h-7 w-[160px] text-xs"
                        />
                      </div>
                    </div>
                  </div>

                  {/* 테이블 모드 설정 */}
                  {config.rightPanel?.displayMode === "table" && (
                    <>
                      <Separator />
                      <div className="space-y-1">
                        <span className="text-xs font-medium">테이블 옵션</span>
                        <SwitchRow
                          label="체크박스"
                          checked={config.rightPanel?.tableConfig?.showCheckbox ?? false}
                          onCheckedChange={(checked) =>
                            updateRightPanel({
                              tableConfig: {
                                ...config.rightPanel?.tableConfig,
                                showCheckbox: checked,
                              },
                            })
                          }
                        />
                        <SwitchRow
                          label="행 번호"
                          checked={config.rightPanel?.tableConfig?.showRowNumber ?? false}
                          onCheckedChange={(checked) =>
                            updateRightPanel({
                              tableConfig: {
                                ...config.rightPanel?.tableConfig,
                                showRowNumber: checked,
                              },
                            })
                          }
                        />
                        <SwitchRow
                          label="줄무늬"
                          checked={config.rightPanel?.tableConfig?.striped ?? false}
                          onCheckedChange={(checked) =>
                            updateRightPanel({
                              tableConfig: {
                                ...config.rightPanel?.tableConfig,
                                striped: checked,
                              },
                            })
                          }
                        />
                        <SwitchRow
                          label="헤더 고정"
                          checked={config.rightPanel?.tableConfig?.stickyHeader ?? false}
                          onCheckedChange={(checked) =>
                            updateRightPanel({
                              tableConfig: {
                                ...config.rightPanel?.tableConfig,
                                stickyHeader: checked,
                              },
                            })
                          }
                        />
                      </div>
                    </>
                  )}
                </div>
              </CollapsibleContent>
            </Collapsible>
          </div>
        </CollapsibleContent>
      </Collapsible>

      {/* ═══════════════════════════════════════ */}
      {/* 5단계: 추가 탭 (접이식)                  */}
      {/* ═══════════════════════════════════════ */}
      <Collapsible open={tabsOpen} onOpenChange={setTabsOpen}>
        <CollapsibleTrigger asChild>
          <button
            type="button"
            className="bg-muted/30 hover:bg-muted/50 flex w-full items-center justify-between rounded-lg border px-4 py-2.5 text-left transition-colors"
          >
            <div className="flex items-center gap-2">
              <Layers className="text-muted-foreground h-4 w-4" />
              <span className="truncate text-sm font-medium">추가 탭</span>
              <Badge variant="secondary" className="h-5 text-[10px]">
                {config.rightPanel?.additionalTabs?.length || 0}개
              </Badge>
            </div>
            <ChevronDown
              className={cn(
                "text-muted-foreground h-4 w-4 transition-transform duration-200",
                tabsOpen && "rotate-180",
              )}
            />
          </button>
        </CollapsibleTrigger>
        <CollapsibleContent>
          <div className="space-y-3 rounded-b-lg border border-t-0 p-4">
            {/* 탭 목록 */}
            {(config.rightPanel?.additionalTabs || []).map((tab, tabIndex) => (
              <div key={tab.tabId} className="space-y-3 rounded-lg border p-3">
                <div className="flex items-center justify-between">
                  <span className="text-xs font-medium">{tab.label || `탭 ${tabIndex + 1}`}</span>
                  <Button
                    type="button"
                    variant="ghost"
                    size="sm"
                    onClick={() => removeTab(tabIndex)}
                    className="text-destructive h-6 w-6 p-0"
                  >
                    <Trash2 className="h-3 w-3" />
                  </Button>
                </div>

                <div className="grid grid-cols-2 gap-2">
                  <div className="space-y-1">
                    <Label className="text-[10px]">탭 라벨</Label>
                    <Input
                      value={tab.label}
                      onChange={(e) => updateTab(tabIndex, { label: e.target.value })}
                      placeholder="탭 이름"
                      className="h-7 text-xs"
                    />
                  </div>
                  <div className="space-y-1">
                    <Label className="text-[10px]">패널 제목</Label>
                    <Input
                      value={tab.title}
                      onChange={(e) => updateTab(tabIndex, { title: e.target.value })}
                      placeholder="패널 제목"
                      className="h-7 text-xs"
                    />
                  </div>
                </div>

                {/* 탭 테이블 선택 */}
                <div className="space-y-1">
                  <Label className="text-[10px]">테이블</Label>
                  <TableCombobox
                    value={tab.tableName || ""}
                    allTables={allTables}
                    screenTableName={screenTableName}
                    loading={loadingTables}
                    onChange={(tableName) => {
                      updateTab(tabIndex, {
                        tableName,
                        columns: [],
                      });
                      if (tableName) loadTableColumns(tableName);
                    }}
                  />
                </div>

                {/* 탭 표시 모드 */}
                <div className="flex items-center justify-between">
                  <span className="text-muted-foreground text-[10px]">표시 모드</span>
                  <Select
                    value={tab.displayMode || "table"}
                    onValueChange={(v) =>
                      updateTab(tabIndex, {
                        displayMode: v as "list" | "table",
                      })
                    }
                  >
                    <SelectTrigger className="h-7 w-[100px] text-[11px]">
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value="list">목록</SelectItem>
                      <SelectItem value="table">테이블</SelectItem>
                    </SelectContent>
                  </Select>
                </div>

                {/* 탭 연결 키 */}
                {tab.tableName && (
                  <div className="space-y-1.5">
                    <span className="text-[10px] font-medium">연결 키</span>
                    <div className="flex items-center gap-2">
                      <Select
                        value={tab.relation?.leftColumn || ""}
                        onValueChange={(v) =>
                          updateTab(tabIndex, {
                            relation: {
                              ...tab.relation,
                              leftColumn: v,
                            },
                          })
                        }
                      >
                        <SelectTrigger className="h-7 flex-1 text-[11px]">
                          <SelectValue placeholder="좌측 컬럼" />
                        </SelectTrigger>
                        <SelectContent>
                          {leftTableColumns.map((col) => (
                            <SelectItem key={col.columnName} value={col.columnName}>
                              {col.displayName || col.columnName}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                      <ArrowRight className="text-muted-foreground h-3 w-3 shrink-0" />
                      <Select
                        value={tab.relation?.rightColumn || ""}
                        onValueChange={(v) =>
                          updateTab(tabIndex, {
                            relation: {
                              ...tab.relation,
                              rightColumn: v,
                            },
                          })
                        }
                      >
                        <SelectTrigger className="h-7 flex-1 text-[11px]">
                          <SelectValue placeholder="우측 컬럼" />
                        </SelectTrigger>
                        <SelectContent>
                          {(loadedTableColumns[tab.tableName] || []).map((col) => (
                            <SelectItem key={col.columnName} value={col.columnName}>
                              {col.displayName || col.columnName}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    </div>
                  </div>
                )}

                {/* 탭 기능 토글 */}
                <div className="space-y-0.5">
                  <SwitchRow
                    label="검색"
                    checked={tab.showSearch ?? false}
                    onCheckedChange={(checked) => updateTab(tabIndex, { showSearch: checked })}
                  />
                  <SwitchRow
                    label="추가"
                    checked={tab.showAdd ?? false}
                    onCheckedChange={(checked) => updateTab(tabIndex, { showAdd: checked })}
                  />
                  <SwitchRow
                    label="삭제"
                    checked={tab.showDelete ?? false}
                    onCheckedChange={(checked) => updateTab(tabIndex, { showDelete: checked })}
                  />
                </div>
              </div>
            ))}

            {/* 탭 추가 버튼 */}
            <Button type="button" variant="outline" size="sm" onClick={addTab} className="h-8 w-full text-xs">
              <Plus className="mr-1 h-3 w-3" />탭 추가
            </Button>
          </div>
        </CollapsibleContent>
      </Collapsible>

      {/* ═══════════════════════════════════════ */}
      {/* 6단계: 고급 설정 (기본 접힘)             */}
      {/* ═══════════════════════════════════════ */}
      <Collapsible open={advancedOpen} onOpenChange={setAdvancedOpen}>
        <CollapsibleTrigger asChild>
          <button
            type="button"
            className="bg-muted/30 hover:bg-muted/50 flex w-full items-center justify-between rounded-lg border px-4 py-2.5 text-left transition-colors"
          >
            <div className="flex items-center gap-2">
              <Settings className="text-muted-foreground h-4 w-4" />
              <span className="truncate text-sm font-medium">고급 설정</span>
              <Badge variant="secondary" className="h-5 text-[10px]">
                8개
              </Badge>
            </div>
            <ChevronDown
              className={cn(
                "text-muted-foreground h-4 w-4 transition-transform duration-200",
                advancedOpen && "rotate-180",
              )}
            />
          </button>
        </CollapsibleTrigger>
        <CollapsibleContent>
          <div className="space-y-3 rounded-b-lg border border-t-0 p-4">
            <SwitchRow
              label="선택 동기화"
              description="좌우 패널 간 선택 항목 동기화"
              checked={config.syncSelection ?? false}
              onCheckedChange={(checked) => updateConfig({ syncSelection: checked })}
            />

            <Separator />

            {/* 최소 너비 설정 */}
            <div className="space-y-2">
              <span className="text-xs font-medium">최소 너비 (px)</span>
              <div className="grid grid-cols-2 gap-2">
                <div className="space-y-1">
                  <Label className="text-[10px]">좌측</Label>
                  <Input
                    type="number"
                    value={config.minLeftWidth || 200}
                    onChange={(e) =>
                      updateConfig({
                        minLeftWidth: parseInt(e.target.value) || 200,
                      })
                    }
                    className="h-7 text-xs"
                  />
                </div>
                <div className="space-y-1">
                  <Label className="text-[10px]">우측</Label>
                  <Input
                    type="number"
                    value={config.minRightWidth || 300}
                    onChange={(e) =>
                      updateConfig({
                        minRightWidth: parseInt(e.target.value) || 300,
                      })
                    }
                    className="h-7 text-xs"
                  />
                </div>
              </div>
            </div>

            <Separator />

            {/* 좌측 패널 하위 항목 추가 설정 */}
            {config.leftPanel?.showItemAddButton && (
              <div className="space-y-2">
                <span className="text-xs font-medium">하위 항목 추가 설정</span>
                <div className="space-y-1.5">
                  <div className="flex items-center justify-between">
                    <span className="text-muted-foreground text-xs">부모 컬럼</span>
                    <Input
                      value={config.leftPanel?.itemAddConfig?.parentColumn || ""}
                      onChange={(e) =>
                        updateLeftPanel({
                          itemAddConfig: {
                            ...config.leftPanel?.itemAddConfig,
                            parentColumn: e.target.value,
                            sourceColumn: config.leftPanel?.itemAddConfig?.sourceColumn || "",
                          },
                        })
                      }
                      placeholder="예: parent_dept_code"
                      className="h-7 w-[160px] text-xs"
                    />
                  </div>
                  <div className="flex items-center justify-between">
                    <span className="text-muted-foreground text-xs">소스 컬럼</span>
                    <Input
                      value={config.leftPanel?.itemAddConfig?.sourceColumn || ""}
                      onChange={(e) =>
                        updateLeftPanel({
                          itemAddConfig: {
                            ...config.leftPanel?.itemAddConfig!,
                            sourceColumn: e.target.value,
                          },
                        })
                      }
                      placeholder="예: dept_code"
                      className="h-7 w-[160px] text-xs"
                    />
                  </div>
                </div>
              </div>
            )}

            {/* 좌측 패널 테이블 모드 설정 */}
            {config.leftPanel?.displayMode === "table" && (
              <div className="space-y-1">
                <span className="text-xs font-medium">좌측 테이블 옵션</span>
                <SwitchRow
                  label="체크박스"
                  checked={config.leftPanel?.tableConfig?.showCheckbox ?? false}
                  onCheckedChange={(checked) =>
                    updateLeftPanel({
                      tableConfig: {
                        ...config.leftPanel?.tableConfig,
                        showCheckbox: checked,
                      },
                    })
                  }
                />
                <SwitchRow
                  label="행 번호"
                  checked={config.leftPanel?.tableConfig?.showRowNumber ?? false}
                  onCheckedChange={(checked) =>
                    updateLeftPanel({
                      tableConfig: {
                        ...config.leftPanel?.tableConfig,
                        showRowNumber: checked,
                      },
                    })
                  }
                />
                <SwitchRow
                  label="줄무늬"
                  checked={config.leftPanel?.tableConfig?.striped ?? false}
                  onCheckedChange={(checked) =>
                    updateLeftPanel({
                      tableConfig: {
                        ...config.leftPanel?.tableConfig,
                        striped: checked,
                      },
                    })
                  }
                />
                <SwitchRow
                  label="헤더 고정"
                  checked={config.leftPanel?.tableConfig?.stickyHeader ?? false}
                  onCheckedChange={(checked) =>
                    updateLeftPanel({
                      tableConfig: {
                        ...config.leftPanel?.tableConfig,
                        stickyHeader: checked,
                      },
                    })
                  }
                />
              </div>
            )}

            {/* 좌측 패널 수정/추가 버튼 모달 설정 */}
            <Separator />
            <div className="space-y-1">
              <span className="text-xs font-medium">좌측 버튼 모달 설정</span>
              <SwitchRow
                label="수정 버튼 모달"
                checked={config.leftPanel?.editButton?.mode === "modal"}
                onCheckedChange={(checked) =>
                  updateLeftPanel({
                    editButton: {
                      ...config.leftPanel?.editButton,
                      enabled: config.leftPanel?.editButton?.enabled ?? true,
                      mode: checked ? "modal" : "auto",
                    },
                  })
                }
              />
              {config.leftPanel?.editButton?.mode === "modal" && (
                <div className="border-primary/20 ml-4 border-l-2 pl-3">
                  <div className="flex items-center justify-between py-1">
                    <span className="text-muted-foreground text-xs">모달 화면 ID</span>
                    <Input
                      type="number"
                      value={config.leftPanel?.editButton?.modalScreenId || ""}
                      onChange={(e) =>
                        updateLeftPanel({
                          editButton: {
                            ...config.leftPanel?.editButton!,
                            modalScreenId: parseInt(e.target.value) || undefined,
                          },
                        })
                      }
                      placeholder="화면 ID"
                      className="h-7 w-[100px] text-xs"
                    />
                  </div>
                </div>
              )}

              <SwitchRow
                label="추가 버튼 모달"
                checked={config.leftPanel?.addButton?.mode === "modal"}
                onCheckedChange={(checked) =>
                  updateLeftPanel({
                    addButton: {
                      ...config.leftPanel?.addButton,
                      enabled: config.leftPanel?.addButton?.enabled ?? true,
                      mode: checked ? "modal" : "auto",
                    },
                  })
                }
              />
              {config.leftPanel?.addButton?.mode === "modal" && (
                <div className="border-primary/20 ml-4 border-l-2 pl-3">
                  <div className="flex items-center justify-between py-1">
                    <span className="text-muted-foreground text-xs">모달 화면 ID</span>
                    <Input
                      type="number"
                      value={config.leftPanel?.addButton?.modalScreenId || ""}
                      onChange={(e) =>
                        updateLeftPanel({
                          addButton: {
                            ...config.leftPanel?.addButton!,
                            modalScreenId: parseInt(e.target.value) || undefined,
                          },
                        })
                      }
                      placeholder="화면 ID"
                      className="h-7 w-[100px] text-xs"
                    />
                  </div>
                </div>
              )}
            </div>

            {/* 패널 헤더 높이 */}
            <Separator />
            <div className="space-y-2">
              <span className="text-xs font-medium">패널 헤더 높이 (px)</span>
              <div className="grid grid-cols-2 gap-2">
                <div className="space-y-1">
                  <Label className="text-[10px]">좌측</Label>
                  <Input
                    type="number"
                    value={config.leftPanel?.panelHeaderHeight || ""}
                    onChange={(e) =>
                      updateLeftPanel({
                        panelHeaderHeight: parseInt(e.target.value) || undefined,
                      })
                    }
                    placeholder="자동"
                    className="h-7 text-xs"
                  />
                </div>
                <div className="space-y-1">
                  <Label className="text-[10px]">우측</Label>
                  <Input
                    type="number"
                    value={config.rightPanel?.panelHeaderHeight || ""}
                    onChange={(e) =>
                      updateRightPanel({
                        panelHeaderHeight: parseInt(e.target.value) || undefined,
                      })
                    }
                    placeholder="자동"
                    className="h-7 text-xs"
                  />
                </div>
              </div>
            </div>
          </div>
        </CollapsibleContent>
      </Collapsible>
    </div>
  );
};

V2SplitPanelLayoutConfigPanel.displayName = "V2SplitPanelLayoutConfigPanel";

export default V2SplitPanelLayoutConfigPanel;
