"use client";

import React, { useState, useEffect, useCallback, useMemo } from "react";
import { Label } from "@/components/ui/label";
import { Input } from "@/components/ui/input";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Button } from "@/components/ui/button";
import { Switch } from "@/components/ui/switch";
import { Plus, X, GripVertical, Check, ChevronsUpDown, Table, Layers } from "lucide-react";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Badge } from "@/components/ui/badge";
import { ScrollArea } from "@/components/ui/scroll-area";
import {
  RepeatScreenModalProps,
  CardRowConfig,
  CardColumnConfig,
  ColumnSourceConfig,
  ColumnTargetConfig,
  DataSourceConfig,
  GroupingConfig,
  AggregationConfig,
  TableLayoutConfig,
  TableColumnConfig,
  CardContentRowConfig,
  AggregationDisplayConfig,
} from "./types";
import { tableManagementApi } from "@/lib/api/tableManagement";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command";
import { cn } from "@/lib/utils";

interface RepeatScreenModalConfigPanelProps {
  config: Partial<RepeatScreenModalProps>;
  onChange: (config: Partial<RepeatScreenModalProps>) => void;
}

// 검색 가능한 컬럼 선택기 (Combobox) - 240px 최적화
function SourceColumnSelector({
  sourceTable,
  value,
  onChange,
  placeholder = "컬럼 선택",
}: {
  sourceTable: string;
  value: string;
  onChange: (value: string) => void;
  placeholder?: string;
  showTableName?: boolean;
}) {
  const [columns, setColumns] = useState<{ columnName: string; displayName?: string }[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  const [open, setOpen] = useState(false);

  useEffect(() => {
    const loadColumns = async () => {
      if (!sourceTable) {
        setColumns([]);
        return;
      }

      setIsLoading(true);
      try {
        const response = await tableManagementApi.getColumnList(sourceTable);
        if (response.success && response.data) {
          setColumns(response.data.columns);
        }
      } catch (error) {
        console.error("컬럼 로드 실패:", error);
        setColumns([]);
      } finally {
        setIsLoading(false);
      }
    };
    loadColumns();
  }, [sourceTable]);

  const selectedColumn = columns.find((col) => col.columnName === value);
  const displayText = selectedColumn ? selectedColumn.columnName : placeholder;

  return (
    <Popover open={open} onOpenChange={setOpen}>
      <PopoverTrigger asChild>
        <Button
          variant="outline"
          role="combobox"
          aria-expanded={open}
          className="h-6 w-full justify-between text-[10px]"
          disabled={!sourceTable || isLoading}
        >
          <span className="truncate">{isLoading ? "..." : displayText}</span>
          <ChevronsUpDown className="ml-1 h-3 w-3 shrink-0 opacity-50" />
        </Button>
      </PopoverTrigger>
      <PopoverContent className="p-0 max-h-[200px] w-[200px]" align="start">
        <Command>
          <CommandInput placeholder="검색..." className="text-[10px] h-7" />
          <CommandList className="max-h-[160px] overflow-y-auto">
            <CommandEmpty className="text-[10px] py-2">없음</CommandEmpty>
            <CommandGroup>
              {columns.map((col) => (
                <CommandItem
                  key={col.columnName}
                  value={`${col.columnName} ${col.displayName || ""}`}
                  onSelect={() => {
                    onChange(col.columnName);
                    setOpen(false);
                  }}
                  className="text-[10px] py-1"
                >
                  <Check
                    className={cn("mr-1 h-3 w-3", value === col.columnName ? "opacity-100" : "opacity-0")}
                  />
                  <span className="truncate">{col.columnName}</span>
                </CommandItem>
              ))}
            </CommandGroup>
          </CommandList>
        </Command>
      </PopoverContent>
    </Popover>
  );
}

// 카드 제목 편집기 - 직접 입력 + 필드 삽입 방식
function CardTitleEditor({
  sourceTable,
  currentValue,
  onChange,
}: {
  sourceTable: string;
  currentValue: string;
  onChange: (value: string) => void;
}) {
  const [columns, setColumns] = useState<{ columnName: string; displayName?: string }[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  const [open, setOpen] = useState(false);
  const [localValue, setLocalValue] = useState(currentValue || "");
  const inputRef = React.useRef<HTMLInputElement>(null);

  useEffect(() => {
    setLocalValue(currentValue || "");
  }, [currentValue]);

  useEffect(() => {
    const loadColumns = async () => {
      if (!sourceTable) {
        setColumns([]);
        return;
      }

      setIsLoading(true);
      try {
        const response = await tableManagementApi.getColumnList(sourceTable);
        if (response.success && response.data) {
          setColumns(response.data.columns || []);
        }
      } catch (error) {
        console.error("컬럼 로드 실패:", error);
        setColumns([]);
      } finally {
        setIsLoading(false);
      }
    };
    loadColumns();
  }, [sourceTable]);

  // 필드 삽입 (현재 커서 위치 또는 끝에)
  const insertField = (fieldName: string) => {
    const newValue = localValue ? `${localValue} - {${fieldName}}` : `{${fieldName}}`;
    setLocalValue(newValue);
    onChange(newValue);
    setOpen(false);
  };

  // 추천 템플릿
  const templateOptions = useMemo(() => {
    const options = [
      { value: "카드 {index}", label: "카드 {index} - 순번만" },
    ];

    if (columns.length > 0) {
      // part_code - part_name 패턴 찾기
      const codeCol = columns.find((c) => 
        c.columnName.toLowerCase().includes("code") || c.columnName.toLowerCase().includes("no")
      );
      const nameCol = columns.find((c) => 
        c.columnName.toLowerCase().includes("name") && !c.columnName.toLowerCase().includes("code")
      );

      if (codeCol && nameCol) {
        options.push({
          value: `{${codeCol.columnName}} - {${nameCol.columnName}}`,
          label: `{${codeCol.columnName}} - {${nameCol.columnName}} (추천)`,
        });
      }

      // 첫 번째 컬럼 단일
      const firstCol = columns[0];
      options.push({
        value: `{${firstCol.columnName}}`,
        label: `{${firstCol.columnName}}${firstCol.displayName ? ` - ${firstCol.displayName}` : ""}`,
      });
    }

    return options;
  }, [columns]);

  // 입력값 변경 핸들러
  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setLocalValue(e.target.value);
  };

  // 입력 완료 (blur 또는 Enter)
  const handleInputBlur = () => {
    if (localValue !== currentValue) {
      onChange(localValue);
    }
  };

  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === "Enter") {
      handleInputBlur();
    }
  };

  return (
    <div className="space-y-1.5">
      {/* 직접 입력 필드 */}
      <div className="flex gap-1">
        <Input
          ref={inputRef}
          value={localValue}
          onChange={handleInputChange}
          onBlur={handleInputBlur}
          onKeyDown={handleKeyDown}
          placeholder="{part_code} - {part_name}"
          className="h-7 text-[10px] flex-1"
        />
        <Popover open={open} onOpenChange={setOpen}>
          <PopoverTrigger asChild>
            <Button
              variant="outline"
              size="sm"
              className="h-7 px-2 text-[9px]"
              disabled={isLoading || !sourceTable}
            >
              <Plus className="h-3 w-3" />
            </Button>
          </PopoverTrigger>
          <PopoverContent className="p-0 w-[200px]" align="end">
            <Command>
              <CommandInput placeholder="필드 검색..." className="text-[10px] h-7" />
              <CommandList className="max-h-[200px] overflow-y-auto">
                <CommandEmpty className="text-[10px] py-2 text-center">없음</CommandEmpty>
                
                {/* 추천 템플릿 */}
                <CommandGroup heading="추천 템플릿">
                  {templateOptions.map((opt) => (
                    <CommandItem
                      key={opt.value}
                      value={opt.value}
                      onSelect={() => {
                        setLocalValue(opt.value);
                        onChange(opt.value);
                        setOpen(false);
                      }}
                      className="text-[10px] py-1"
                    >
                      <span className="truncate">{opt.label}</span>
                    </CommandItem>
                  ))}
                </CommandGroup>

                {/* 필드 삽입 */}
                {columns.length > 0 && (
                  <CommandGroup heading="필드 추가 (끝에 삽입)">
                    <CommandItem
                      key="_index"
                      value="index"
                      onSelect={() => insertField("index")}
                      className="text-[10px] py-1"
                    >
                      <Plus className="h-3 w-3 mr-1 text-primary" />
                      <span>index - 순번</span>
                    </CommandItem>
                    {columns.map((col) => (
                      <CommandItem
                        key={col.columnName}
                        value={col.columnName}
                        onSelect={() => insertField(col.columnName)}
                        className="text-[10px] py-1"
                      >
                        <Plus className="h-3 w-3 mr-1 text-primary" />
                        <span className="truncate">
                          {col.columnName}
                          {col.displayName && (
                            <span className="text-muted-foreground ml-1">- {col.displayName}</span>
                          )}
                        </span>
                      </CommandItem>
                    ))}
                  </CommandGroup>
                )}
              </CommandList>
            </Command>
          </PopoverContent>
        </Popover>
      </div>

      {/* 안내 텍스트 */}
      <p className="text-[9px] text-muted-foreground">
        직접 입력하거나 + 버튼으로 필드 추가. 예: {"{part_code} - {part_name}"}
      </p>
    </div>
  );
}

// 집계 설정 아이템 (로컬 상태 관리로 입력 시 리렌더링 방지)
function AggregationConfigItem({
  agg,
  index,
  sourceTable,
  onUpdate,
  onRemove,
}: {
  agg: AggregationConfig;
  index: number;
  sourceTable: string;
  onUpdate: (updates: Partial<AggregationConfig>) => void;
  onRemove: () => void;
}) {
  const [localLabel, setLocalLabel] = useState(agg.label || "");
  const [localResultField, setLocalResultField] = useState(agg.resultField || "");

  // agg 변경 시 로컬 상태 동기화
  useEffect(() => {
    setLocalLabel(agg.label || "");
    setLocalResultField(agg.resultField || "");
  }, [agg.label, agg.resultField]);

  return (
    <div className="border rounded p-2 space-y-1.5 bg-background">
      <div className="flex items-center justify-between">
        <Badge variant="secondary" className="text-[9px] px-1 py-0">
          집계 {index + 1}
        </Badge>
        <Button
          size="sm"
          variant="ghost"
          onClick={onRemove}
          className="h-5 w-5 p-0"
        >
          <X className="h-3 w-3" />
        </Button>
      </div>

      <div className="space-y-1">
        <Label className="text-[9px]">원본 필드</Label>
        <SourceColumnSelector
          sourceTable={sourceTable}
          value={agg.sourceField}
          onChange={(value) => onUpdate({ sourceField: value })}
          placeholder="합계할 필드"
        />
      </div>

      <div className="flex gap-2">
        <div className="flex-1 space-y-1 min-w-0">
          <Label className="text-[9px]">집계 타입</Label>
          <Select
            value={agg.type}
            onValueChange={(value) => onUpdate({ type: value as AggregationConfig["type"] })}
          >
            <SelectTrigger className="h-6 text-[10px] w-full">
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="sum">합계</SelectItem>
              <SelectItem value="count">개수</SelectItem>
              <SelectItem value="avg">평균</SelectItem>
              <SelectItem value="min">최소</SelectItem>
              <SelectItem value="max">최대</SelectItem>
            </SelectContent>
          </Select>
        </div>

        <div className="flex-1 space-y-1 min-w-0">
          <Label className="text-[9px]">라벨</Label>
          <Input
            value={localLabel}
            onChange={(e) => setLocalLabel(e.target.value)}
            onBlur={() => onUpdate({ label: localLabel })}
            onKeyDown={(e) => {
              if (e.key === "Enter") {
                onUpdate({ label: localLabel });
              }
            }}
            placeholder="총수주잔량"
            className="h-6 text-[10px]"
          />
        </div>
      </div>

      <div className="space-y-1">
        <Label className="text-[9px]">결과 필드명</Label>
        <Input
          value={localResultField}
          onChange={(e) => setLocalResultField(e.target.value)}
          onBlur={() => onUpdate({ resultField: localResultField })}
          onKeyDown={(e) => {
            if (e.key === "Enter") {
              onUpdate({ resultField: localResultField });
            }
          }}
          placeholder="total_balance_qty"
          className="h-6 text-[10px]"
        />
      </div>
    </div>
  );
}

// 테이블 선택기 (Combobox) - 240px 최적화
function TableSelector({ value, onChange }: { value: string; onChange: (value: string) => void }) {
  const [tables, setTables] = useState<{ tableName: string; displayName?: string }[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  const [open, setOpen] = useState(false);

  useEffect(() => {
    const loadTables = async () => {
      setIsLoading(true);
      try {
        const response = await tableManagementApi.getTableList();
        if (response.success && response.data) {
          // API 응답이 배열인 경우와 객체인 경우 모두 처리
          const tableData = Array.isArray(response.data) 
            ? response.data 
            : (response.data as any).tables || response.data || [];
          setTables(tableData);
        }
      } catch (error) {
        console.error("테이블 로드 실패:", error);
        setTables([]);
      } finally {
        setIsLoading(false);
      }
    };
    loadTables();
  }, []);

  const selectedTable = (tables || []).find((t) => t.tableName === value);
  const displayText = selectedTable ? selectedTable.tableName : "테이블 선택";

  return (
    <Popover open={open} onOpenChange={setOpen}>
      <PopoverTrigger asChild>
        <Button
          variant="outline"
          role="combobox"
          aria-expanded={open}
          className="h-7 w-full justify-between text-[10px]"
          disabled={isLoading}
        >
          <span className="truncate">{isLoading ? "..." : displayText}</span>
          <ChevronsUpDown className="ml-1 h-3 w-3 shrink-0 opacity-50" />
        </Button>
      </PopoverTrigger>
      <PopoverContent className="p-0 max-h-[200px] w-[200px]" align="start">
        <Command>
          <CommandInput placeholder="검색..." className="text-[10px] h-7" />
          <CommandList className="max-h-[160px] overflow-y-auto">
            <CommandEmpty className="text-[10px] py-2">없음</CommandEmpty>
            <CommandGroup>
              {tables.map((table) => (
                <CommandItem
                  key={table.tableName}
                  value={`${table.tableName} ${table.displayName || ""}`}
                  onSelect={() => {
                    onChange(table.tableName);
                    setOpen(false);
                  }}
                  className="text-[10px] py-1"
                >
                  <Check
                    className={cn("mr-1 h-3 w-3", value === table.tableName ? "opacity-100" : "opacity-0")}
                  />
                  <span className="truncate">{table.tableName}</span>
                </CommandItem>
              ))}
            </CommandGroup>
          </CommandList>
        </Command>
      </PopoverContent>
    </Popover>
  );
}

// 모듈 레벨에서 탭 상태 유지 (컴포넌트 리마운트 시에도 유지)
let persistedActiveTab = "basic";

export function RepeatScreenModalConfigPanel({ config, onChange }: RepeatScreenModalConfigPanelProps) {
  const [localConfig, setLocalConfig] = useState<Partial<RepeatScreenModalProps>>(() => ({
    dataSource: { sourceTable: "" },
    saveMode: "all",
    cardSpacing: "24px",
    showCardBorder: true,
    showCardTitle: true,
    cardTitle: "카드 {index}",
    grouping: { enabled: false, groupByField: "", aggregations: [] },
    contentRows: [], // 🆕 v3: 자유 레이아웃
    // 레거시 호환
    cardMode: "simple",
    cardLayout: [],
    tableLayout: { headerRows: [], tableColumns: [] },
    ...config,
  }));

  const [allTables, setAllTables] = useState<{ tableName: string; displayName?: string }[]>([]);
  
  // 탭 상태 유지 (모듈 레벨 변수와 동기화)
  const [activeTab, setActiveTab] = useState(persistedActiveTab);
  
  // 탭 변경 시 모듈 레벨 변수도 업데이트
  const handleTabChange = (tab: string) => {
    persistedActiveTab = tab;
    setActiveTab(tab);
  };

  // 테이블 목록 로드
  useEffect(() => {
    const loadTables = async () => {
      try {
        const response = await tableManagementApi.getTableList();
        if (response.success && response.data) {
          // API 응답이 배열인 경우와 객체인 경우 모두 처리
          const tableData = Array.isArray(response.data) 
            ? response.data 
            : (response.data as any).tables || response.data || [];
          setAllTables(tableData);
        }
      } catch (error) {
        console.error("테이블 로드 실패:", error);
      }
    };
    loadTables();
  }, []);

  // Debounced update for input fields
  const updateConfigDebounced = useCallback(
    (updates: Partial<RepeatScreenModalProps>) => {
      const timeoutId = setTimeout(() => {
        setLocalConfig((prev) => {
          const newConfig = { ...prev, ...updates };
          onChange(newConfig);
          return newConfig;
        });
      }, 500);

      return () => clearTimeout(timeoutId);
    },
    [onChange]
  );

  // Immediate update for select/switch fields
  // requestAnimationFrame을 사용하여 React 렌더링 사이클 이후에 onChange 호출
  const updateConfig = useCallback((updates: Partial<RepeatScreenModalProps>) => {
    setLocalConfig((prev) => {
      const newConfig = { ...prev, ...updates };
      // 비동기로 onChange 호출하여 현재 렌더링 사이클 완료 후 실행
      requestAnimationFrame(() => {
        onChange(newConfig);
      });
      return newConfig;
    });
  }, [onChange]);

  // === 그룹핑 관련 함수 ===
  const updateGrouping = (updates: Partial<GroupingConfig>) => {
    updateConfig({
      grouping: {
        ...localConfig.grouping,
        enabled: localConfig.grouping?.enabled ?? false,
        groupByField: localConfig.grouping?.groupByField ?? "",
        aggregations: localConfig.grouping?.aggregations ?? [],
        ...updates,
      },
    });
  };

  const addAggregation = () => {
    const newAgg: AggregationConfig = {
      sourceField: "",
      type: "sum",
      resultField: `agg_${Date.now()}`,
      label: "",
    };
    updateGrouping({
      aggregations: [...(localConfig.grouping?.aggregations || []), newAgg],
    });
  };

  const removeAggregation = (index: number) => {
    const newAggs = [...(localConfig.grouping?.aggregations || [])];
    newAggs.splice(index, 1);
    updateGrouping({ aggregations: newAggs });
  };

  const updateAggregation = (index: number, updates: Partial<AggregationConfig>) => {
    const newAggs = [...(localConfig.grouping?.aggregations || [])];
    newAggs[index] = { ...newAggs[index], ...updates };
    updateGrouping({ aggregations: newAggs });
  };

  // === 테이블 레이아웃 관련 함수 ===
  const updateTableLayout = (updates: Partial<TableLayoutConfig>) => {
    updateConfig({
      tableLayout: {
        ...localConfig.tableLayout,
        headerRows: localConfig.tableLayout?.headerRows ?? [],
        tableColumns: localConfig.tableLayout?.tableColumns ?? [],
        ...updates,
      },
    });
  };

  const addTableColumn = () => {
    const newCol: TableColumnConfig = {
      id: `tcol-${Date.now()}`,
      field: "",
      label: "",
      type: "text",
      width: "auto",
      editable: false,
    };
    updateTableLayout({
      tableColumns: [...(localConfig.tableLayout?.tableColumns || []), newCol],
    });
  };

  const removeTableColumn = (index: number) => {
    const newCols = [...(localConfig.tableLayout?.tableColumns || [])];
    newCols.splice(index, 1);
    updateTableLayout({ tableColumns: newCols });
  };

  const updateTableColumn = (index: number, updates: Partial<TableColumnConfig>) => {
    const newCols = [...(localConfig.tableLayout?.tableColumns || [])];
    newCols[index] = { ...newCols[index], ...updates };
    updateTableLayout({ tableColumns: newCols });
  };

  // === 헤더 행 관련 함수 (simple 모드와 동일) ===
  const addHeaderRow = () => {
    const newRow: CardRowConfig = {
      id: `hrow-${Date.now()}`,
      columns: [],
      gap: "16px",
      layout: "horizontal",
    };
    updateTableLayout({
      headerRows: [...(localConfig.tableLayout?.headerRows || []), newRow],
    });
  };

  const removeHeaderRow = (rowIndex: number) => {
    const newRows = [...(localConfig.tableLayout?.headerRows || [])];
    newRows.splice(rowIndex, 1);
    updateTableLayout({ headerRows: newRows });
  };

  const updateHeaderRow = (rowIndex: number, updates: Partial<CardRowConfig>) => {
    const newRows = [...(localConfig.tableLayout?.headerRows || [])];
    newRows[rowIndex] = { ...newRows[rowIndex], ...updates };
    updateTableLayout({ headerRows: newRows });
  };

  const addHeaderColumn = (rowIndex: number) => {
    const newRows = [...(localConfig.tableLayout?.headerRows || [])];
    const newColumn: CardColumnConfig = {
      id: `hcol-${Date.now()}`,
      field: "",
      label: "",
      type: "text",
      width: "auto",
      editable: false,
    };
    newRows[rowIndex].columns.push(newColumn);
    updateTableLayout({ headerRows: newRows });
  };

  const removeHeaderColumn = (rowIndex: number, colIndex: number) => {
    const newRows = [...(localConfig.tableLayout?.headerRows || [])];
    newRows[rowIndex].columns.splice(colIndex, 1);
    updateTableLayout({ headerRows: newRows });
  };

  const updateHeaderColumn = (rowIndex: number, colIndex: number, updates: Partial<CardColumnConfig>) => {
    const newRows = [...(localConfig.tableLayout?.headerRows || [])];
    newRows[rowIndex].columns[colIndex] = { ...newRows[rowIndex].columns[colIndex], ...updates };
    updateTableLayout({ headerRows: newRows });
  };

  // === 🆕 v3: contentRows 관련 함수 ===
  const addContentRow = (type: CardContentRowConfig["type"]) => {
    const newRow: CardContentRowConfig = {
      id: `crow-${Date.now()}`,
      type,
      // 타입별 기본값
      ...(type === "header" || type === "fields"
        ? { columns: [], layout: "horizontal", gap: "16px" }
        : {}),
      ...(type === "aggregation"
        ? { aggregationFields: [], aggregationLayout: "horizontal" }
        : {}),
      ...(type === "table"
        ? { tableColumns: [], showTableHeader: true }
        : {}),
    };
    updateConfig({
      contentRows: [...(localConfig.contentRows || []), newRow],
    });
  };

  const removeContentRow = (rowIndex: number) => {
    const newRows = [...(localConfig.contentRows || [])];
    newRows.splice(rowIndex, 1);
    updateConfig({ contentRows: newRows });
  };

  const updateContentRow = (rowIndex: number, updates: Partial<CardContentRowConfig>) => {
    const newRows = [...(localConfig.contentRows || [])];
    newRows[rowIndex] = { ...newRows[rowIndex], ...updates };
    updateConfig({ contentRows: newRows });
  };

  // contentRow 내 컬럼 관리 (header/fields 타입)
  const addContentRowColumn = (rowIndex: number) => {
    const newRows = [...(localConfig.contentRows || [])];
    const newColumn: CardColumnConfig = {
      id: `col-${Date.now()}`,
      field: "",
      label: "",
      type: "text",
      width: "auto",
      editable: false,
    };
    newRows[rowIndex].columns = [...(newRows[rowIndex].columns || []), newColumn];
    updateConfig({ contentRows: newRows });
  };

  const removeContentRowColumn = (rowIndex: number, colIndex: number) => {
    const newRows = [...(localConfig.contentRows || [])];
    newRows[rowIndex].columns?.splice(colIndex, 1);
    updateConfig({ contentRows: newRows });
  };

  const updateContentRowColumn = (rowIndex: number, colIndex: number, updates: Partial<CardColumnConfig>) => {
    const newRows = [...(localConfig.contentRows || [])];
    if (newRows[rowIndex].columns) {
      newRows[rowIndex].columns![colIndex] = { ...newRows[rowIndex].columns![colIndex], ...updates };
    }
    updateConfig({ contentRows: newRows });
  };

  // contentRow 내 집계 필드 관리 (aggregation 타입)
  const addContentRowAggField = (rowIndex: number) => {
    const newRows = [...(localConfig.contentRows || [])];
    const newAggField: AggregationDisplayConfig = {
      aggregationResultField: "",
      label: "",
    };
    newRows[rowIndex].aggregationFields = [...(newRows[rowIndex].aggregationFields || []), newAggField];
    updateConfig({ contentRows: newRows });
  };

  const removeContentRowAggField = (rowIndex: number, fieldIndex: number) => {
    const newRows = [...(localConfig.contentRows || [])];
    newRows[rowIndex].aggregationFields?.splice(fieldIndex, 1);
    updateConfig({ contentRows: newRows });
  };

  const updateContentRowAggField = (rowIndex: number, fieldIndex: number, updates: Partial<AggregationDisplayConfig>) => {
    const newRows = [...(localConfig.contentRows || [])];
    if (newRows[rowIndex].aggregationFields) {
      newRows[rowIndex].aggregationFields![fieldIndex] = {
        ...newRows[rowIndex].aggregationFields![fieldIndex],
        ...updates,
      };
    }
    updateConfig({ contentRows: newRows });
  };

  // contentRow 내 테이블 컬럼 관리 (table 타입)
  const addContentRowTableColumn = (rowIndex: number) => {
    const newRows = [...(localConfig.contentRows || [])];
    const newCol: TableColumnConfig = {
      id: `tcol-${Date.now()}`,
      field: "",
      label: "",
      type: "text",
      editable: false,
    };
    newRows[rowIndex].tableColumns = [...(newRows[rowIndex].tableColumns || []), newCol];
    updateConfig({ contentRows: newRows });
  };

  const removeContentRowTableColumn = (rowIndex: number, colIndex: number) => {
    const newRows = [...(localConfig.contentRows || [])];
    newRows[rowIndex].tableColumns?.splice(colIndex, 1);
    updateConfig({ contentRows: newRows });
  };

  const updateContentRowTableColumn = (rowIndex: number, colIndex: number, updates: Partial<TableColumnConfig>) => {
    const newRows = [...(localConfig.contentRows || [])];
    if (newRows[rowIndex].tableColumns) {
      newRows[rowIndex].tableColumns![colIndex] = { ...newRows[rowIndex].tableColumns![colIndex], ...updates };
    }
    updateConfig({ contentRows: newRows });
  };

  // === (레거시) Simple 모드 행/컬럼 관련 함수 ===
  const addRow = () => {
    const newRow: CardRowConfig = {
      id: `row-${Date.now()}`,
      columns: [],
      gap: "16px",
      layout: "horizontal",
    };
    updateConfig({
      cardLayout: [...(localConfig.cardLayout || []), newRow],
    });
  };

  const removeRow = (rowIndex: number) => {
    const newLayout = [...(localConfig.cardLayout || [])];
    newLayout.splice(rowIndex, 1);
    updateConfig({ cardLayout: newLayout });
  };

  const updateRow = (rowIndex: number, updates: Partial<CardRowConfig>) => {
    const newLayout = [...(localConfig.cardLayout || [])];
    newLayout[rowIndex] = { ...newLayout[rowIndex], ...updates };
    updateConfig({ cardLayout: newLayout });
  };

  const addColumn = (rowIndex: number) => {
    const newLayout = [...(localConfig.cardLayout || [])];
    const newColumn: CardColumnConfig = {
      id: `col-${Date.now()}`,
      field: "",
      label: "",
      type: "text",
      width: "auto",
      editable: true,
      required: false,
    };
    newLayout[rowIndex].columns.push(newColumn);
    updateConfig({ cardLayout: newLayout });
  };

  const removeColumn = (rowIndex: number, colIndex: number) => {
    const newLayout = [...(localConfig.cardLayout || [])];
    newLayout[rowIndex].columns.splice(colIndex, 1);
    updateConfig({ cardLayout: newLayout });
  };

  const updateColumn = (rowIndex: number, colIndex: number, updates: Partial<CardColumnConfig>) => {
    const newLayout = [...(localConfig.cardLayout || [])];
    newLayout[rowIndex].columns[colIndex] = {
      ...newLayout[rowIndex].columns[colIndex],
      ...updates,
    };
    updateConfig({ cardLayout: newLayout });
  };

  return (
    <ScrollArea className="h-[calc(100vh-200px)]">
      <div className="space-y-4 p-2">
        <Tabs value={activeTab} onValueChange={handleTabChange} className="w-full">
          <TabsList className="grid w-full grid-cols-4 h-auto p-1">
            <TabsTrigger value="basic" className="text-[9px] px-1 py-1">
              기본
            </TabsTrigger>
            <TabsTrigger value="data" className="text-[9px] px-1 py-1">
              소스
            </TabsTrigger>
            <TabsTrigger value="grouping" className="text-[9px] px-1 py-1">
              그룹
            </TabsTrigger>
            <TabsTrigger value="layout" className="text-[9px] px-1 py-1">
              레이아웃
            </TabsTrigger>
          </TabsList>

          {/* === 기본 설정 탭 === */}
          <TabsContent value="basic" className="space-y-3 mt-3">
            <div className="space-y-3 border rounded-lg p-3 bg-card">
              <h3 className="text-xs font-semibold">카드 설정</h3>

              {/* 카드 제목 표시 여부 */}
              <div className="flex items-center justify-between">
                <Label className="text-[10px]">카드 제목 표시</Label>
                <Switch
                  checked={localConfig.showCardTitle}
                  onCheckedChange={(checked) => updateConfig({ showCardTitle: checked })}
                  className="scale-75"
                />
              </div>

              {/* 카드 제목 설정 (표시할 때만) */}
              {localConfig.showCardTitle && (
                <div className="space-y-1.5">
                  <Label className="text-[10px]">카드 제목 템플릿</Label>
                  <CardTitleEditor
                    sourceTable={localConfig.dataSource?.sourceTable || ""}
                    currentValue={localConfig.cardTitle || ""}
                    onChange={(value) => {
                      setLocalConfig((prev) => ({ ...prev, cardTitle: value }));
                      updateConfig({ cardTitle: value });
                    }}
                  />
                </div>
              )}

              <div className="space-y-1.5">
                <Label className="text-[10px]">카드 간격</Label>
                <Select value={localConfig.cardSpacing} onValueChange={(value) => updateConfig({ cardSpacing: value })}>
                  <SelectTrigger className="h-7 text-[10px] w-full">
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="8px">8px</SelectItem>
                    <SelectItem value="16px">16px</SelectItem>
                    <SelectItem value="24px">24px</SelectItem>
                    <SelectItem value="32px">32px</SelectItem>
                  </SelectContent>
                </Select>
              </div>

              <div className="flex items-center justify-between">
                <Label className="text-[10px]">테두리</Label>
                <Switch
                  checked={localConfig.showCardBorder}
                  onCheckedChange={(checked) => updateConfig({ showCardBorder: checked })}
                  className="scale-75"
                />
              </div>

              <div className="space-y-1.5">
                <Label className="text-[10px]">저장 모드</Label>
                <Select
                  value={localConfig.saveMode}
                  onValueChange={(value) => updateConfig({ saveMode: value as "all" | "individual" })}
                >
                  <SelectTrigger className="h-7 text-[10px] w-full">
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="all">전체 저장</SelectItem>
                    <SelectItem value="individual">개별 저장</SelectItem>
                  </SelectContent>
                </Select>
              </div>
            </div>
          </TabsContent>

          {/* === 데이터 소스 탭 === */}
          <TabsContent value="data" className="space-y-3 mt-3">
            <div className="space-y-3 border rounded-lg p-3 bg-card">
              <h3 className="text-xs font-semibold">데이터 소스</h3>

              <div className="space-y-1.5">
                <Label className="text-[10px]">소스 테이블</Label>
                <TableSelector
                  value={localConfig.dataSource?.sourceTable || ""}
                  onChange={(value) =>
                    updateConfig({
                      dataSource: {
                        ...localConfig.dataSource,
                        sourceTable: value,
                      },
                    })
                  }
                />
              </div>

              <div className="space-y-1.5">
                <Label className="text-[10px]">필터 필드</Label>
                <Input
                  value={localConfig.dataSource?.filterField || ""}
                  onChange={(e) => {
                    setLocalConfig((prev) => ({
                      ...prev,
                      dataSource: {
                        ...prev.dataSource,
                        sourceTable: prev.dataSource?.sourceTable || "",
                        filterField: e.target.value,
                      },
                    }));
                    updateConfigDebounced({
                      dataSource: {
                        ...localConfig.dataSource,
                        sourceTable: localConfig.dataSource?.sourceTable || "",
                        filterField: e.target.value,
                      },
                    });
                  }}
                  placeholder="selectedIds"
                  className="h-7 text-[10px]"
                />
                <p className="text-[9px] text-muted-foreground">formData에서 가져올 필드</p>
              </div>
            </div>
          </TabsContent>

          {/* === 그룹핑 설정 탭 === */}
          <TabsContent value="grouping" className="space-y-3 mt-3">
            <div className="space-y-3 border rounded-lg p-3 bg-card">
              <div className="flex items-center justify-between">
                <h3 className="text-xs font-semibold">그룹핑</h3>
                <Switch
                  checked={localConfig.grouping?.enabled}
                  onCheckedChange={(checked) => updateGrouping({ enabled: checked })}
                  className="scale-75"
                />
              </div>

              {localConfig.grouping?.enabled && (
                <>
                  <div className="space-y-1.5">
                    <Label className="text-[10px]">그룹 기준 필드</Label>
                    <SourceColumnSelector
                      sourceTable={localConfig.dataSource?.sourceTable || ""}
                      value={localConfig.grouping?.groupByField || ""}
                      onChange={(value) => updateGrouping({ groupByField: value })}
                      placeholder="예: part_code"
                    />
                    <p className="text-[9px] text-muted-foreground">같은 값을 가진 행들을 하나의 카드로 묶음</p>
                  </div>

                  {/* 집계 설정 */}
                  <div className="space-y-2 pt-2 border-t">
                    <div className="flex items-center justify-between">
                      <Label className="text-[10px] font-semibold">집계 설정</Label>
                      <Button size="sm" variant="outline" onClick={addAggregation} className="h-5 text-[9px] px-1">
                        <Plus className="h-2 w-2 mr-0.5" />
                        추가
                      </Button>
                    </div>

                    {(localConfig.grouping?.aggregations || []).map((agg, index) => (
                      <AggregationConfigItem
                        key={`agg-${index}`}
                        agg={agg}
                        index={index}
                        sourceTable={localConfig.dataSource?.sourceTable || ""}
                        onUpdate={(updates) => updateAggregation(index, updates)}
                        onRemove={() => removeAggregation(index)}
                      />
                    ))}

                    {(localConfig.grouping?.aggregations || []).length === 0 && (
                      <p className="text-[9px] text-muted-foreground text-center py-2">
                        집계 설정이 없습니다
                      </p>
                    )}
                  </div>
                </>
              )}
            </div>
          </TabsContent>

          {/* === 레이아웃 설정 탭 === */}
          <TabsContent value="layout" className="space-y-3 mt-3">
            <div className="space-y-3">
              {/* 행 추가 버튼들 */}
              <div className="space-y-2 border rounded-lg p-3 bg-card">
                <h3 className="text-xs font-semibold">행 추가</h3>
                <div className="grid grid-cols-2 gap-2">
                  <Button
                    size="sm"
                    variant="outline"
                    onClick={() => addContentRow("header")}
                    className="h-8 text-[9px]"
                  >
                    <Layers className="h-3 w-3 mr-1" />
                    헤더
                  </Button>
                  <Button
                    size="sm"
                    variant="outline"
                    onClick={() => addContentRow("aggregation")}
                    className="h-8 text-[9px]"
                  >
                    <Table className="h-3 w-3 mr-1" />
                    집계
                  </Button>
                  <Button
                    size="sm"
                    variant="outline"
                    onClick={() => addContentRow("table")}
                    className="h-8 text-[9px]"
                  >
                    <Table className="h-3 w-3 mr-1" />
                    테이블
                  </Button>
                  <Button
                    size="sm"
                    variant="outline"
                    onClick={() => addContentRow("fields")}
                    className="h-8 text-[9px]"
                  >
                    <Layers className="h-3 w-3 mr-1" />
                    필드
                  </Button>
                </div>
                <p className="text-[9px] text-muted-foreground">
                  원하는 타입의 행을 추가하세요. 순서대로 카드에 표시됩니다.
                </p>
              </div>

              {/* 행 목록 */}
              {(localConfig.contentRows || []).length > 0 ? (
                <div className="space-y-3">
                  {(localConfig.contentRows || []).map((row, rowIndex) => (
                    <ContentRowConfigSection
                      key={row.id || `crow-${rowIndex}`}
                      row={row}
                      rowIndex={rowIndex}
                      totalRows={(localConfig.contentRows || []).length}
                      allTables={allTables}
                      dataSourceTable={localConfig.dataSource?.sourceTable || ""}
                      aggregations={localConfig.grouping?.aggregations || []}
                      onUpdateRow={(updates) => updateContentRow(rowIndex, updates)}
                      onRemoveRow={() => removeContentRow(rowIndex)}
                      onAddColumn={() => addContentRowColumn(rowIndex)}
                      onRemoveColumn={(colIndex) => removeContentRowColumn(rowIndex, colIndex)}
                      onUpdateColumn={(colIndex, updates) => updateContentRowColumn(rowIndex, colIndex, updates)}
                      onAddAggField={() => addContentRowAggField(rowIndex)}
                      onRemoveAggField={(fieldIndex) => removeContentRowAggField(rowIndex, fieldIndex)}
                      onUpdateAggField={(fieldIndex, updates) => updateContentRowAggField(rowIndex, fieldIndex, updates)}
                      onAddTableColumn={() => addContentRowTableColumn(rowIndex)}
                      onRemoveTableColumn={(colIndex) => removeContentRowTableColumn(rowIndex, colIndex)}
                      onUpdateTableColumn={(colIndex, updates) => updateContentRowTableColumn(rowIndex, colIndex, updates)}
                    />
                  ))}
                </div>
              ) : (
                <div className="text-center py-8 border border-dashed rounded-lg">
                  <p className="text-[10px] text-muted-foreground mb-2">행이 없습니다</p>
                  <p className="text-[9px] text-muted-foreground">
                    위의 버튼으로 헤더/집계/테이블/필드 행을 추가하세요
                  </p>
                </div>
              )}
            </div>
          </TabsContent>
        </Tabs>
      </div>
    </ScrollArea>
  );
}

// === 🆕 v3: 콘텐츠 행 설정 섹션 ===
function ContentRowConfigSection({
  row,
  rowIndex,
  totalRows,
  allTables,
  dataSourceTable,
  aggregations,
  onUpdateRow,
  onRemoveRow,
  onAddColumn,
  onRemoveColumn,
  onUpdateColumn,
  onAddAggField,
  onRemoveAggField,
  onUpdateAggField,
  onAddTableColumn,
  onRemoveTableColumn,
  onUpdateTableColumn,
}: {
  row: CardContentRowConfig;
  rowIndex: number;
  totalRows: number;
  allTables: { tableName: string; displayName?: string }[];
  dataSourceTable: string;
  aggregations: AggregationConfig[];
  onUpdateRow: (updates: Partial<CardContentRowConfig>) => void;
  onRemoveRow: () => void;
  onAddColumn: () => void;
  onRemoveColumn: (colIndex: number) => void;
  onUpdateColumn: (colIndex: number, updates: Partial<CardColumnConfig>) => void;
  onAddAggField: () => void;
  onRemoveAggField: (fieldIndex: number) => void;
  onUpdateAggField: (fieldIndex: number, updates: Partial<AggregationDisplayConfig>) => void;
  onAddTableColumn: () => void;
  onRemoveTableColumn: (colIndex: number) => void;
  onUpdateTableColumn: (colIndex: number, updates: Partial<TableColumnConfig>) => void;
}) {
  // 로컬 상태로 Input 필드 관리 (타이핑 시 리렌더링 방지)
  const [localTableTitle, setLocalTableTitle] = useState(row.tableTitle || "");

  useEffect(() => {
    setLocalTableTitle(row.tableTitle || "");
  }, [row.tableTitle]);

  const handleTableTitleBlur = () => {
    if (localTableTitle !== row.tableTitle) {
      onUpdateRow({ tableTitle: localTableTitle });
    }
  };

  // 행 타입별 색상
  const typeColors = {
    header: "bg-purple-50 dark:bg-purple-950 border-purple-200 dark:border-purple-800",
    aggregation: "bg-orange-50 dark:bg-orange-950 border-orange-200 dark:border-orange-800",
    table: "bg-blue-50 dark:bg-blue-950 border-blue-200 dark:border-blue-800",
    fields: "bg-green-50 dark:bg-green-950 border-green-200 dark:border-green-800",
  };

  const typeLabels = {
    header: "헤더",
    aggregation: "집계",
    table: "테이블",
    fields: "필드",
  };

  const typeBadgeColors = {
    header: "bg-purple-100 text-purple-700",
    aggregation: "bg-orange-100 text-orange-700",
    table: "bg-blue-100 text-blue-700",
    fields: "bg-green-100 text-green-700",
  };

  return (
    <div className={cn("border rounded-lg p-2 space-y-2", typeColors[row.type])}>
      {/* 행 헤더 */}
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-1">
          <GripVertical className="h-3 w-3 text-muted-foreground" />
          <Badge className={cn("text-[9px] px-1 py-0", typeBadgeColors[row.type])}>
            행 {rowIndex + 1}: {typeLabels[row.type]}
          </Badge>
        </div>
        <Button size="sm" variant="ghost" onClick={onRemoveRow} className="h-5 w-5 p-0">
          <X className="h-3 w-3" />
        </Button>
      </div>

      {/* 타입 변경 */}
      <div className="space-y-1">
        <Label className="text-[9px]">타입 변경</Label>
        <Select
          value={row.type}
          onValueChange={(value) => onUpdateRow({ type: value as CardContentRowConfig["type"] })}
        >
          <SelectTrigger className="h-6 text-[10px] w-full">
            <SelectValue />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="header">헤더</SelectItem>
            <SelectItem value="aggregation">집계</SelectItem>
            <SelectItem value="table">테이블</SelectItem>
            <SelectItem value="fields">필드</SelectItem>
          </SelectContent>
        </Select>
      </div>

      {/* 헤더/필드 타입 설정 */}
      {(row.type === "header" || row.type === "fields") && (
        <div className="space-y-2 pt-2 border-t">
          <div className="flex gap-2">
            <div className="flex-1 space-y-1 min-w-0">
              <Label className="text-[9px]">방향</Label>
              <Select
                value={row.layout || "horizontal"}
                onValueChange={(value) => onUpdateRow({ layout: value as "horizontal" | "vertical" })}
              >
                <SelectTrigger className="h-6 text-[10px] w-full">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="horizontal">가로</SelectItem>
                  <SelectItem value="vertical">세로</SelectItem>
                </SelectContent>
              </Select>
            </div>
            <div className="flex-1 space-y-1 min-w-0">
              <Label className="text-[9px]">배경색</Label>
              <Select
                value={row.backgroundColor || "none"}
                onValueChange={(value) => onUpdateRow({ backgroundColor: value === "none" ? undefined : value })}
              >
                <SelectTrigger className="h-6 text-[10px] w-full">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="none">없음</SelectItem>
                  <SelectItem value="blue">파랑</SelectItem>
                  <SelectItem value="green">초록</SelectItem>
                  <SelectItem value="purple">보라</SelectItem>
                  <SelectItem value="orange">주황</SelectItem>
                </SelectContent>
              </Select>
            </div>
          </div>

          {/* 컬럼 목록 */}
          <div className="space-y-2 pl-2 border-l-2 border-primary/30">
            <div className="flex items-center justify-between">
              <Label className="text-[9px] font-semibold">컬럼 ({(row.columns || []).length}개)</Label>
              <Button size="sm" variant="outline" onClick={onAddColumn} className="h-5 text-[9px] px-1">
                <Plus className="h-2 w-2 mr-0.5" />
                추가
              </Button>
            </div>

            {(row.columns || []).map((col, colIndex) => (
              <ColumnConfigSection
                key={col.id || `col-${colIndex}`}
                col={col}
                colIndex={colIndex}
                allTables={allTables}
                dataSourceTable={dataSourceTable}
                aggregations={aggregations}
                onUpdate={(updates) => onUpdateColumn(colIndex, updates)}
                onRemove={() => onRemoveColumn(colIndex)}
              />
            ))}

            {(row.columns || []).length === 0 && (
              <div className="text-center py-2 text-[9px] text-muted-foreground border border-dashed rounded">
                컬럼 추가
              </div>
            )}
          </div>
        </div>
      )}

      {/* 집계 타입 설정 */}
      {row.type === "aggregation" && (
        <div className="space-y-2 pt-2 border-t">
          <div className="flex gap-2">
            <div className="flex-1 space-y-1 min-w-0">
              <Label className="text-[9px]">레이아웃</Label>
              <Select
                value={row.aggregationLayout || "horizontal"}
                onValueChange={(value) => onUpdateRow({ aggregationLayout: value as "horizontal" | "grid" })}
              >
                <SelectTrigger className="h-6 text-[10px] w-full">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="horizontal">가로 나열</SelectItem>
                  <SelectItem value="grid">그리드</SelectItem>
                </SelectContent>
              </Select>
            </div>
            {row.aggregationLayout === "grid" && (
              <div className="flex-1 space-y-1 min-w-0">
                <Label className="text-[9px]">컬럼 수</Label>
                <Select
                  value={String(row.aggregationColumns || 4)}
                  onValueChange={(value) => onUpdateRow({ aggregationColumns: Number(value) })}
                >
                  <SelectTrigger className="h-6 text-[10px] w-full">
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="2">2개</SelectItem>
                    <SelectItem value="3">3개</SelectItem>
                    <SelectItem value="4">4개</SelectItem>
                  </SelectContent>
                </Select>
              </div>
            )}
          </div>

          {/* 집계 필드 목록 */}
          <div className="space-y-2 pl-2 border-l-2 border-orange-300">
            <div className="flex items-center justify-between">
              <Label className="text-[9px] font-semibold">집계 필드 ({(row.aggregationFields || []).length}개)</Label>
              <Button size="sm" variant="outline" onClick={onAddAggField} className="h-5 text-[9px] px-1">
                <Plus className="h-2 w-2 mr-0.5" />
                추가
              </Button>
            </div>

            {aggregations.length === 0 && (
              <p className="text-[9px] text-orange-600 bg-orange-100 dark:bg-orange-900 p-2 rounded">
                먼저 그룹 탭에서 집계 설정을 추가하세요
              </p>
            )}

            {(row.aggregationFields || []).map((field, fieldIndex) => (
              <div key={fieldIndex} className="border rounded p-2 space-y-1.5 bg-background">
                <div className="flex items-center justify-between">
                  <Badge variant="secondary" className="text-[9px] px-1 py-0">
                    집계 {fieldIndex + 1}
                  </Badge>
                  <Button size="sm" variant="ghost" onClick={() => onRemoveAggField(fieldIndex)} className="h-5 w-5 p-0">
                    <X className="h-3 w-3" />
                  </Button>
                </div>

                <div className="space-y-1">
                  <Label className="text-[9px]">집계 필드</Label>
                  <Select
                    value={field.aggregationResultField}
                    onValueChange={(value) => onUpdateAggField(fieldIndex, { aggregationResultField: value })}
                  >
                    <SelectTrigger className="h-6 text-[10px] w-full">
                      <SelectValue placeholder="선택" />
                    </SelectTrigger>
                    <SelectContent>
                      {aggregations.map((agg) => (
                        <SelectItem key={agg.resultField} value={agg.resultField}>
                          {agg.label || agg.resultField}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>

                <div className="space-y-1">
                  <Label className="text-[9px]">표시 라벨</Label>
                  <Input
                    value={field.label}
                    onChange={(e) => onUpdateAggField(fieldIndex, { label: e.target.value })}
                    placeholder="총수주잔량"
                    className="h-6 text-[10px]"
                  />
                </div>

                <div className="flex gap-2">
                  <div className="flex-1 space-y-1 min-w-0">
                    <Label className="text-[9px]">배경색</Label>
                    <Select
                      value={field.backgroundColor || "none"}
                      onValueChange={(value) => onUpdateAggField(fieldIndex, { backgroundColor: value === "none" ? undefined : value })}
                    >
                      <SelectTrigger className="h-6 text-[10px] w-full">
                        <SelectValue />
                      </SelectTrigger>
                      <SelectContent>
                        <SelectItem value="none">없음</SelectItem>
                        <SelectItem value="blue">파랑</SelectItem>
                        <SelectItem value="green">초록</SelectItem>
                        <SelectItem value="orange">주황</SelectItem>
                      </SelectContent>
                    </Select>
                  </div>
                  <div className="flex-1 space-y-1 min-w-0">
                    <Label className="text-[9px]">폰트 크기</Label>
                    <Select
                      value={field.fontSize || "base"}
                      onValueChange={(value) => onUpdateAggField(fieldIndex, { fontSize: value as AggregationDisplayConfig["fontSize"] })}
                    >
                      <SelectTrigger className="h-6 text-[10px] w-full">
                        <SelectValue />
                      </SelectTrigger>
                      <SelectContent>
                        <SelectItem value="sm">작게</SelectItem>
                        <SelectItem value="base">보통</SelectItem>
                        <SelectItem value="lg">크게</SelectItem>
                        <SelectItem value="xl">매우 크게</SelectItem>
                      </SelectContent>
                    </Select>
                  </div>
                </div>
              </div>
            ))}

            {(row.aggregationFields || []).length === 0 && aggregations.length > 0 && (
              <div className="text-center py-2 text-[9px] text-muted-foreground border border-dashed rounded">
                집계 필드 추가
              </div>
            )}
          </div>
        </div>
      )}

      {/* 테이블 타입 설정 */}
      {row.type === "table" && (
        <div className="space-y-2 pt-2 border-t">
          <div className="flex gap-2">
            <div className="flex-1 space-y-1 min-w-0">
              <Label className="text-[9px]">테이블 제목</Label>
              <Input
                value={localTableTitle}
                onChange={(e) => setLocalTableTitle(e.target.value)}
                onBlur={handleTableTitleBlur}
                onKeyDown={(e) => e.key === "Enter" && handleTableTitleBlur()}
                placeholder="선택사항"
                className="h-6 text-[10px]"
              />
            </div>
            <div className="flex items-center gap-1 pt-4">
              <Switch
                checked={row.showTableHeader !== false}
                onCheckedChange={(checked) => onUpdateRow({ showTableHeader: checked })}
                className="scale-[0.6]"
              />
              <Label className="text-[9px]">헤더</Label>
            </div>
          </div>

          {/* 테이블 컬럼 목록 */}
          <div className="space-y-2 pl-2 border-l-2 border-blue-300">
            <div className="flex items-center justify-between">
              <Label className="text-[9px] font-semibold">테이블 컬럼 ({(row.tableColumns || []).length}개)</Label>
              <Button size="sm" variant="outline" onClick={onAddTableColumn} className="h-5 text-[9px] px-1">
                <Plus className="h-2 w-2 mr-0.5" />
                추가
              </Button>
            </div>

            {(row.tableColumns || []).map((col, colIndex) => (
              <TableColumnConfigSection
                key={col.id || `tcol-${colIndex}`}
                col={col}
                colIndex={colIndex}
                allTables={allTables}
                dataSourceTable={dataSourceTable}
                onUpdate={(updates) => onUpdateTableColumn(colIndex, updates)}
                onRemove={() => onRemoveTableColumn(colIndex)}
              />
            ))}

            {(row.tableColumns || []).length === 0 && (
              <div className="text-center py-2 text-[9px] text-muted-foreground border border-dashed rounded">
                테이블 컬럼 추가
              </div>
            )}
          </div>
        </div>
      )}
    </div>
  );
}

// === (레거시) 행 설정 섹션 ===
function RowConfigSection({
  row,
  rowIndex,
  allTables,
  dataSourceTable,
  aggregations,
  onUpdateRow,
  onRemoveRow,
  onAddColumn,
  onRemoveColumn,
  onUpdateColumn,
  isHeader = false,
}: {
  row: CardRowConfig;
  rowIndex: number;
  allTables: { tableName: string; displayName?: string }[];
  dataSourceTable: string;
  aggregations: AggregationConfig[];
  onUpdateRow: (updates: Partial<CardRowConfig>) => void;
  onRemoveRow: () => void;
  onAddColumn: () => void;
  onRemoveColumn: (colIndex: number) => void;
  onUpdateColumn: (colIndex: number, updates: Partial<CardColumnConfig>) => void;
  isHeader?: boolean;
}) {
  return (
    <div className="border rounded-lg p-2 space-y-2 bg-background">
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-1">
          <GripVertical className="h-3 w-3 text-muted-foreground" />
          <Badge variant="outline" className="text-[9px] px-1 py-0">
            행 {rowIndex + 1}
          </Badge>
          <span className="text-[9px] text-muted-foreground">({row.columns.length}개)</span>
        </div>
        <Button size="sm" variant="ghost" onClick={onRemoveRow} className="h-5 w-5 p-0">
          <X className="h-3 w-3" />
        </Button>
      </div>

      {/* 행 설정 */}
      <div className="flex gap-2">
        <div className="flex-1 space-y-1 min-w-0">
          <Label className="text-[9px]">방향</Label>
          <Select
            value={row.layout || "horizontal"}
            onValueChange={(value) => onUpdateRow({ layout: value as "horizontal" | "vertical" })}
          >
            <SelectTrigger className="h-6 text-[10px] w-full">
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="horizontal">가로</SelectItem>
              <SelectItem value="vertical">세로</SelectItem>
            </SelectContent>
          </Select>
        </div>

        {isHeader && (
          <div className="flex-1 space-y-1 min-w-0">
            <Label className="text-[9px]">배경색</Label>
            <Select
              value={row.backgroundColor || "none"}
              onValueChange={(value) => onUpdateRow({ backgroundColor: value === "none" ? undefined : value })}
            >
              <SelectTrigger className="h-6 text-[10px] w-full">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="none">없음</SelectItem>
                <SelectItem value="blue">파랑</SelectItem>
                <SelectItem value="green">초록</SelectItem>
                <SelectItem value="purple">보라</SelectItem>
                <SelectItem value="orange">주황</SelectItem>
              </SelectContent>
            </Select>
          </div>
        )}
      </div>

      {/* 컬럼 목록 */}
      <div className="space-y-2 pl-2 border-l-2 border-primary/30">
        <div className="flex items-center justify-between">
          <Label className="text-[9px] font-semibold">컬럼</Label>
          <Button size="sm" variant="outline" onClick={onAddColumn} className="h-5 text-[9px] px-1">
            <Plus className="h-2 w-2 mr-0.5" />
            추가
          </Button>
        </div>

        {row.columns.map((col, colIndex) => (
          <ColumnConfigSection
            key={col.id || `col-${colIndex}`}
            col={col}
            colIndex={colIndex}
            allTables={allTables}
            dataSourceTable={dataSourceTable}
            aggregations={aggregations}
            onUpdate={(updates) => onUpdateColumn(colIndex, updates)}
            onRemove={() => onRemoveColumn(colIndex)}
          />
        ))}

        {row.columns.length === 0 && (
          <div className="text-center py-2 text-[9px] text-muted-foreground border border-dashed rounded">
            컬럼 추가
          </div>
        )}
      </div>
    </div>
  );
}

// === 컬럼 설정 섹션 (로컬 상태로 입력 필드 관리) ===
function ColumnConfigSection({
  col,
  colIndex,
  allTables,
  dataSourceTable,
  aggregations,
  onUpdate,
  onRemove,
}: {
  col: CardColumnConfig;
  colIndex: number;
  allTables: { tableName: string; displayName?: string }[];
  dataSourceTable: string;
  aggregations: AggregationConfig[];
  onUpdate: (updates: Partial<CardColumnConfig>) => void;
  onRemove: () => void;
}) {
  // 로컬 상태로 Input 필드 관리 (타이핑 시 리렌더링 방지)
  const [localField, setLocalField] = useState(col.field || "");
  const [localLabel, setLocalLabel] = useState(col.label || "");

  useEffect(() => {
    setLocalField(col.field || "");
    setLocalLabel(col.label || "");
  }, [col.field, col.label]);

  const handleFieldBlur = () => {
    if (localField !== col.field) {
      onUpdate({ field: localField });
    }
  };

  const handleLabelBlur = () => {
    if (localLabel !== col.label) {
      onUpdate({ label: localLabel });
    }
  };

  return (
    <div className="border rounded p-2 space-y-2 bg-background">
      <div className="flex items-center justify-between">
        <Badge variant="secondary" className="text-[9px] px-1 py-0">
          컬럼 {colIndex + 1}
        </Badge>
        <Button size="sm" variant="ghost" onClick={onRemove} className="h-5 w-5 p-0">
          <X className="h-3 w-3" />
        </Button>
      </div>

      {/* 기본 설정 */}
      <div className="space-y-1.5">
        <div className="space-y-1">
          <Label className="text-[9px]">필드명</Label>
          <Input
            value={localField}
            onChange={(e) => setLocalField(e.target.value)}
            onBlur={handleFieldBlur}
            onKeyDown={(e) => e.key === "Enter" && handleFieldBlur()}
            placeholder="field_name"
            className="h-6 text-[10px]"
          />
        </div>

        <div className="space-y-1">
          <Label className="text-[9px]">라벨</Label>
          <Input
            value={localLabel}
            onChange={(e) => setLocalLabel(e.target.value)}
            onBlur={handleLabelBlur}
            onKeyDown={(e) => e.key === "Enter" && handleLabelBlur()}
            placeholder="표시명"
            className="h-6 text-[10px]"
          />
        </div>

        <div className="flex gap-2">
          <div className="flex-1 space-y-1 min-w-0">
            <Label className="text-[9px]">타입</Label>
            <Select value={col.type} onValueChange={(value) => onUpdate({ type: value as any })}>
              <SelectTrigger className="h-6 text-[10px] w-full">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="text">텍스트</SelectItem>
                <SelectItem value="number">숫자</SelectItem>
                <SelectItem value="date">날짜</SelectItem>
                <SelectItem value="select">선택</SelectItem>
                <SelectItem value="aggregation">집계값</SelectItem>
              </SelectContent>
            </Select>
          </div>

          <div className="flex-1 space-y-1 min-w-0">
            <Label className="text-[9px]">너비</Label>
            <Select value={col.width || "auto"} onValueChange={(value) => onUpdate({ width: value })}>
              <SelectTrigger className="h-6 text-[10px] w-full">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="auto">자동</SelectItem>
                <SelectItem value="50%">50%</SelectItem>
                <SelectItem value="100%">100%</SelectItem>
              </SelectContent>
            </Select>
          </div>
        </div>

        {/* 집계값 타입일 때 */}
        {col.type === "aggregation" && aggregations.length > 0 && (
          <div className="space-y-1">
            <Label className="text-[9px]">집계 필드</Label>
            <Select
              value={col.aggregationField || ""}
              onValueChange={(value) => onUpdate({ aggregationField: value })}
            >
              <SelectTrigger className="h-6 text-[10px] w-full">
                <SelectValue placeholder="선택" />
              </SelectTrigger>
              <SelectContent>
                {aggregations.map((agg) => (
                  <SelectItem key={agg.resultField} value={agg.resultField}>
                    {agg.label || agg.resultField}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
        )}
      </div>

      {/* 편집/필수 설정 */}
      <div className="flex items-center justify-between pt-1 border-t">
        <div className="flex items-center gap-1">
          <Switch
            checked={col.editable}
            onCheckedChange={(checked) => onUpdate({ editable: checked })}
            className="scale-[0.6]"
          />
          <Label className="text-[9px]">편집</Label>
        </div>
        <div className="flex items-center gap-1">
          <Switch
            checked={col.required}
            onCheckedChange={(checked) => onUpdate({ required: checked })}
            className="scale-[0.6]"
          />
          <Label className="text-[9px]">필수</Label>
        </div>
      </div>

      {/* 데이터 소스 설정 */}
      {col.type !== "aggregation" && (
        <div className="space-y-1.5 p-1.5 bg-blue-50 dark:bg-blue-950 rounded border border-blue-200 dark:border-blue-800">
          <Label className="text-[9px] font-semibold text-blue-600">소스</Label>
          <Select
            value={col.sourceConfig?.type || "manual"}
            onValueChange={(value) =>
              onUpdate({
                sourceConfig: {
                  ...col.sourceConfig,
                  type: value as "direct" | "join" | "manual",
                },
              })
            }
          >
            <SelectTrigger className="h-6 text-[10px] w-full">
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="direct">직접</SelectItem>
              <SelectItem value="join">조인</SelectItem>
              <SelectItem value="manual">수동</SelectItem>
            </SelectContent>
          </Select>

          {col.sourceConfig?.type === "direct" && (
            <SourceColumnSelector
              sourceTable={dataSourceTable}
              value={col.sourceConfig.sourceColumn || ""}
              onChange={(value) =>
                onUpdate({
                  sourceConfig: {
                    ...col.sourceConfig,
                    type: "direct",
                    sourceColumn: value,
                  } as ColumnSourceConfig,
                })
              }
            />
          )}

          {col.sourceConfig?.type === "join" && (
            <div className="space-y-1">
              <Select
                value={col.sourceConfig.joinTable || ""}
                onValueChange={(value) =>
                  onUpdate({
                    sourceConfig: {
                      ...col.sourceConfig,
                      type: "join",
                      joinTable: value,
                    },
                  })
                }
              >
                <SelectTrigger className="h-6 text-[10px] w-full">
                  <SelectValue placeholder="조인 테이블" />
                </SelectTrigger>
                <SelectContent>
                  {(allTables || []).map((table) => (
                    <SelectItem key={table.tableName} value={table.tableName}>
                      {table.tableName}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>

              <SourceColumnSelector
                sourceTable={dataSourceTable}
                value={col.sourceConfig.joinKey || ""}
                onChange={(value) =>
                  onUpdate({
                    sourceConfig: {
                      ...col.sourceConfig,
                      type: "join",
                      joinKey: value,
                    } as ColumnSourceConfig,
                  })
                }
              />
            </div>
          )}
        </div>
      )}

      {/* 데이터 타겟 설정 */}
      <div className="space-y-1.5 p-1.5 bg-green-50 dark:bg-green-950 rounded border border-green-200 dark:border-green-800">
        <Label className="text-[9px] font-semibold text-green-600">저장</Label>

        <Select
          value={col.targetConfig?.targetTable || ""}
          onValueChange={(value) =>
            onUpdate({
              targetConfig: {
                ...col.targetConfig,
                targetTable: value,
                targetColumn: col.targetConfig?.targetColumn || "",
                saveEnabled: true,
              },
            })
          }
        >
          <SelectTrigger className="h-6 text-[10px] w-full">
            <SelectValue placeholder="테이블" />
          </SelectTrigger>
          <SelectContent>
            {(allTables || []).map((table) => (
              <SelectItem key={table.tableName} value={table.tableName}>
                {table.tableName}
              </SelectItem>
            ))}
          </SelectContent>
        </Select>

        {col.targetConfig?.targetTable && (
          <SourceColumnSelector
            sourceTable={col.targetConfig.targetTable}
            value={col.targetConfig.targetColumn || ""}
            onChange={(value) =>
              onUpdate({
                targetConfig: {
                  ...col.targetConfig,
                  targetColumn: value,
                } as ColumnTargetConfig,
              })
            }
          />
        )}
      </div>
    </div>
  );
}

// === 테이블 컬럼 설정 섹션 (로컬 상태로 입력 필드 관리) ===
function TableColumnConfigSection({
  col,
  colIndex,
  allTables,
  dataSourceTable,
  onUpdate,
  onRemove,
}: {
  col: TableColumnConfig;
  colIndex: number;
  allTables: { tableName: string; displayName?: string }[];
  dataSourceTable: string;
  onUpdate: (updates: Partial<TableColumnConfig>) => void;
  onRemove: () => void;
}) {
  // 로컬 상태로 Input 필드 관리 (타이핑 시 리렌더링 방지)
  const [localLabel, setLocalLabel] = useState(col.label || "");
  const [localWidth, setLocalWidth] = useState(col.width || "");

  useEffect(() => {
    setLocalLabel(col.label || "");
    setLocalWidth(col.width || "");
  }, [col.label, col.width]);

  const handleLabelBlur = () => {
    if (localLabel !== col.label) {
      onUpdate({ label: localLabel });
    }
  };

  const handleWidthBlur = () => {
    if (localWidth !== col.width) {
      onUpdate({ width: localWidth });
    }
  };

  return (
    <div className="border rounded p-2 space-y-2 bg-background">
      <div className="flex items-center justify-between">
        <Badge variant="secondary" className="text-[9px] px-1 py-0">
          컬럼 {colIndex + 1}
        </Badge>
        <Button size="sm" variant="ghost" onClick={onRemove} className="h-5 w-5 p-0">
          <X className="h-3 w-3" />
        </Button>
      </div>

      <div className="space-y-1.5">
        <div className="space-y-1">
          <Label className="text-[9px]">필드명</Label>
          <SourceColumnSelector
            sourceTable={dataSourceTable}
            value={col.field}
            onChange={(value) => onUpdate({ field: value })}
            placeholder="필드 선택"
          />
        </div>

        <div className="space-y-1">
          <Label className="text-[9px]">헤더 라벨</Label>
          <Input
            value={localLabel}
            onChange={(e) => setLocalLabel(e.target.value)}
            onBlur={handleLabelBlur}
            onKeyDown={(e) => e.key === "Enter" && handleLabelBlur()}
            placeholder="표시명"
            className="h-6 text-[10px]"
          />
        </div>

        <div className="flex gap-2">
          <div className="flex-1 space-y-1 min-w-0">
            <Label className="text-[9px]">타입</Label>
            <Select value={col.type} onValueChange={(value) => onUpdate({ type: value as any })}>
              <SelectTrigger className="h-6 text-[10px] w-full">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="text">텍스트</SelectItem>
                <SelectItem value="number">숫자</SelectItem>
                <SelectItem value="date">날짜</SelectItem>
                <SelectItem value="badge">배지</SelectItem>
              </SelectContent>
            </Select>
          </div>

          <div className="flex-1 space-y-1 min-w-0">
            <Label className="text-[9px]">너비</Label>
            <Input
              value={localWidth}
              onChange={(e) => setLocalWidth(e.target.value)}
              onBlur={handleWidthBlur}
              onKeyDown={(e) => e.key === "Enter" && handleWidthBlur()}
              placeholder="100px"
              className="h-6 text-[10px]"
            />
          </div>
        </div>
      </div>

      {/* 편집 설정 */}
      <div className="flex items-center justify-between pt-1 border-t">
        <div className="flex items-center gap-1">
          <Switch
            checked={col.editable}
            onCheckedChange={(checked) => onUpdate({ editable: checked })}
            className="scale-[0.6]"
          />
          <Label className="text-[9px]">편집 가능</Label>
        </div>
      </div>

      {/* 편집 가능할 때 저장 설정 */}
      {col.editable && (
        <div className="space-y-1.5 p-1.5 bg-green-50 dark:bg-green-950 rounded border border-green-200 dark:border-green-800">
          <Label className="text-[9px] font-semibold text-green-600">저장</Label>

          <Select
            value={col.targetConfig?.targetTable || ""}
            onValueChange={(value) =>
              onUpdate({
                targetConfig: {
                  ...col.targetConfig,
                  targetTable: value,
                  targetColumn: col.targetConfig?.targetColumn || "",
                  saveEnabled: true,
                },
              })
            }
          >
            <SelectTrigger className="h-6 text-[10px] w-full">
              <SelectValue placeholder="테이블" />
            </SelectTrigger>
            <SelectContent>
              {(allTables || []).map((table) => (
                <SelectItem key={table.tableName} value={table.tableName}>
                  {table.tableName}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>

          {col.targetConfig?.targetTable && (
            <SourceColumnSelector
              sourceTable={col.targetConfig.targetTable}
              value={col.targetConfig.targetColumn || ""}
              onChange={(value) =>
                onUpdate({
                  targetConfig: {
                    ...col.targetConfig,
                    targetColumn: value,
                  } as ColumnTargetConfig,
                })
              }
            />
          )}
        </div>
      )}
    </div>
  );
}
