"use client";

/**
 * pop-card-list 설정 패널
 *
 * 3개 탭:
 * [테이블] - 데이터 테이블 선택
 * [카드 템플릿] - 헤더/이미지/본문 필드 + 레이아웃 설정
 * [데이터 소스] - 조인/필터/정렬/개수 설정
 */

import React, { useState, useEffect, useMemo } from "react";
import { ChevronDown, ChevronRight, Plus, Trash2, Database } from "lucide-react";
import type { GridMode } from "@/components/pop/designer/types/pop-layout";
import { GRID_BREAKPOINTS } from "@/components/pop/designer/types/pop-layout";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Switch } from "@/components/ui/switch";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import type {
  PopCardListConfig,
  CardListDataSource,
  CardTemplateConfig,
  CardHeaderConfig,
  CardImageConfig,
  CardBodyConfig,
  CardFieldBinding,
  CardColumnJoin,
  CardColumnFilter,
  CardScrollDirection,
  FilterOperator,
  CardInputFieldConfig,
  CardCalculatedFieldConfig,
  CardCartActionConfig,
} from "../types";
import { CARD_SCROLL_DIRECTION_LABELS, DEFAULT_CARD_IMAGE } from "../types";
import { fetchTableList, fetchTableColumns, type TableInfo, type ColumnInfo } from "../pop-dashboard/utils/dataFetcher";

// ===== Props =====

interface ConfigPanelProps {
  config: PopCardListConfig | undefined;
  onUpdate: (config: PopCardListConfig) => void;
  currentMode?: GridMode;
  currentColSpan?: number;
}

// ===== 기본값 =====

const DEFAULT_DATA_SOURCE: CardListDataSource = {
  tableName: "",
};

const DEFAULT_HEADER: CardHeaderConfig = {
  codeField: undefined,
  titleField: undefined,
};

const DEFAULT_IMAGE: CardImageConfig = {
  enabled: true,
  imageColumn: undefined,
  defaultImage: DEFAULT_CARD_IMAGE,
};

const DEFAULT_BODY: CardBodyConfig = {
  fields: [],
};

const DEFAULT_TEMPLATE: CardTemplateConfig = {
  header: DEFAULT_HEADER,
  image: DEFAULT_IMAGE,
  body: DEFAULT_BODY,
};

const DEFAULT_CONFIG: PopCardListConfig = {
  dataSource: DEFAULT_DATA_SOURCE,
  cardTemplate: DEFAULT_TEMPLATE,
  scrollDirection: "vertical",
  gridColumns: 2,
  gridRows: 3,
  cardSize: "large",
};

// ===== 색상 옵션 =====

const COLOR_OPTIONS = [
  { value: "__default__", label: "기본" },
  { value: "#ef4444", label: "빨간색" },
  { value: "#f97316", label: "주황색" },
  { value: "#eab308", label: "노란색" },
  { value: "#22c55e", label: "초록색" },
  { value: "#3b82f6", label: "파란색" },
  { value: "#8b5cf6", label: "보라색" },
  { value: "#6b7280", label: "회색" },
];

// ===== 메인 컴포넌트 =====

export function PopCardListConfigPanel({ config, onUpdate, currentMode, currentColSpan }: ConfigPanelProps) {
  // 3탭 구조: 기본 설정 (테이블+레이아웃) → 데이터 소스 → 카드 템플릿
  const [activeTab, setActiveTab] = useState<"basic" | "template" | "dataSource">("basic");

  // config가 없으면 기본값 사용
  const cfg: PopCardListConfig = config || DEFAULT_CONFIG;

  // config 업데이트 헬퍼
  const updateConfig = (partial: Partial<PopCardListConfig>) => {
    onUpdate({ ...cfg, ...partial });
  };

  // 테이블이 선택되었는지 확인
  const hasTable = !!cfg.dataSource?.tableName;

  return (
    <div className="flex h-full flex-col">
      {/* 탭 헤더 - 3탭 구조 */}
      <div className="flex border-b">
        <button
          type="button"
          className={`flex-1 px-2 py-2 text-xs font-medium transition-colors ${
            activeTab === "basic"
              ? "border-primary text-primary border-b-2"
              : "text-muted-foreground hover:text-foreground"
          }`}
          onClick={() => setActiveTab("basic")}
        >
          기본 설정
        </button>
        <button
          type="button"
          className={`flex-1 px-2 py-2 text-xs font-medium transition-colors ${
            activeTab === "dataSource"
              ? "border-primary text-primary border-b-2"
              : hasTable
                ? "text-muted-foreground hover:text-foreground"
                : "text-muted-foreground/50 cursor-not-allowed"
          }`}
          onClick={() => hasTable && setActiveTab("dataSource")}
          disabled={!hasTable}
        >
          데이터 소스
        </button>
        <button
          type="button"
          className={`flex-1 px-2 py-2 text-xs font-medium transition-colors ${
            activeTab === "template"
              ? "border-primary text-primary border-b-2"
              : hasTable
                ? "text-muted-foreground hover:text-foreground"
                : "text-muted-foreground/50 cursor-not-allowed"
          }`}
          onClick={() => hasTable && setActiveTab("template")}
          disabled={!hasTable}
        >
          카드 템플릿
        </button>
      </div>

      {/* 탭 내용 */}
      <div className="flex-1 overflow-y-auto p-3">
        {activeTab === "basic" && (
          <BasicSettingsTab
            config={cfg}
            onUpdate={updateConfig}
            currentMode={currentMode}
            currentColSpan={currentColSpan}
          />
        )}
        {activeTab === "dataSource" && <DataSourceTab config={cfg} onUpdate={updateConfig} />}
        {activeTab === "template" && <CardTemplateTab config={cfg} onUpdate={updateConfig} />}
      </div>
    </div>
  );
}

// ===== 기본 설정 탭 (테이블 + 레이아웃 통합) =====

function BasicSettingsTab({
  config,
  onUpdate,
  currentMode,
  currentColSpan,
}: {
  config: PopCardListConfig;
  onUpdate: (partial: Partial<PopCardListConfig>) => void;
  currentMode?: GridMode;
  currentColSpan?: number;
}) {
  const dataSource = config.dataSource || DEFAULT_DATA_SOURCE;
  const [tables, setTables] = useState<TableInfo[]>([]);

  // 테이블 목록 로드
  useEffect(() => {
    fetchTableList().then(setTables);
  }, []);

  // 모드별 추천값 계산
  const recommendation = useMemo(() => {
    if (!currentMode) return null;
    const columns = GRID_BREAKPOINTS[currentMode].columns;
    if (columns >= 8) return { rows: 3, cols: 2 };
    if (columns >= 6) return { rows: 3, cols: 1 };
    return { rows: 2, cols: 1 };
  }, [currentMode]);

  // 열 최대값: colSpan 기반 제한
  const maxColumns = useMemo(() => {
    if (!currentColSpan) return 2;
    return currentColSpan >= 8 ? 2 : 1;
  }, [currentColSpan]);

  // 현재 모드 라벨
  const modeLabel = currentMode ? GRID_BREAKPOINTS[currentMode].label : null;

  // 모드 변경 시 열/행 자동 적용
  useEffect(() => {
    if (!recommendation) return;
    const currentRows = config.gridRows || 3;
    const currentCols = config.gridColumns || 2;
    if (currentRows !== recommendation.rows || currentCols !== recommendation.cols) {
      onUpdate({
        gridRows: recommendation.rows,
        gridColumns: recommendation.cols,
      });
    }
  }, [currentMode]); // eslint-disable-line react-hooks/exhaustive-deps

  return (
    <div className="space-y-4">
      {/* 테이블 선택 섹션 */}
      <CollapsibleSection title="테이블 선택" defaultOpen>
        <div className="space-y-3">
          <div>
            <Label className="text-muted-foreground text-[10px]">데이터 테이블</Label>
            <Select
              value={dataSource.tableName || ""}
              onValueChange={(val) => {
                onUpdate({
                  dataSource: {
                    tableName: val,
                    joins: undefined,
                    filters: undefined,
                    sort: undefined,
                    limit: undefined,
                  },
                  cardTemplate: DEFAULT_TEMPLATE,
                });
              }}
            >
              <SelectTrigger className="mt-1 h-8 text-xs">
                <SelectValue placeholder="테이블을 선택하세요" />
              </SelectTrigger>
              <SelectContent>
                {tables.map((table) => (
                  <SelectItem key={table.tableName} value={table.tableName}>
                    {table.displayName || table.tableName}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>

          {dataSource.tableName && (
            <div className="bg-muted/30 flex items-center gap-2 rounded-md border p-2">
              <Database className="text-primary h-4 w-4" />
              <span className="text-xs font-medium">{dataSource.tableName}</span>
            </div>
          )}
        </div>
      </CollapsibleSection>

      {/* 레이아웃 설정 섹션 */}
      <CollapsibleSection title="레이아웃 설정" defaultOpen>
        <div className="space-y-3">
          {/* 현재 모드 뱃지 */}
          {modeLabel && (
            <div className="bg-muted/50 flex items-center gap-1.5 rounded-md px-2.5 py-1.5">
              <span className="text-muted-foreground text-[10px]">현재:</span>
              <span className="bg-primary/10 text-primary rounded px-1.5 py-0.5 text-[10px] font-medium">
                {modeLabel}
              </span>
            </div>
          )}

          {/* 스크롤 방향 */}
          <div>
            <Label className="text-[10px]">스크롤 방향</Label>
            <div className="mt-1.5 space-y-1.5">
              {(["horizontal", "vertical"] as CardScrollDirection[]).map((dir) => (
                <button
                  key={dir}
                  type="button"
                  className={`flex w-full items-center gap-2 rounded-md border px-3 py-2 text-xs transition-colors ${
                    config.scrollDirection === dir
                      ? "border-primary bg-primary/10 text-primary"
                      : "border-input bg-background hover:bg-accent"
                  }`}
                  onClick={() => onUpdate({ scrollDirection: dir })}
                >
                  <div
                    className={`h-3 w-3 rounded-full border-2 ${
                      config.scrollDirection === dir ? "border-primary bg-primary" : "border-muted-foreground"
                    }`}
                  />
                  {CARD_SCROLL_DIRECTION_LABELS[dir]}
                </button>
              ))}
            </div>
          </div>

          {/* 그리드 배치 설정 (행 x 열) */}
          <div>
            <Label className="text-[10px]">카드 배치 (행 x 열)</Label>
            <div className="mt-1.5 flex items-center gap-2">
              <Input
                type="number"
                min={1}
                max={10}
                value={config.gridRows || 3}
                onChange={(e) => onUpdate({ gridRows: parseInt(e.target.value, 10) || 3 })}
                className="h-7 w-16 text-center text-xs"
              />
              <span className="text-muted-foreground text-xs">x</span>
              <Input
                type="number"
                min={1}
                max={maxColumns}
                value={Math.min(config.gridColumns || 2, maxColumns)}
                onChange={(e) => onUpdate({ gridColumns: Math.min(parseInt(e.target.value, 10) || 1, maxColumns) })}
                className="h-7 w-16 text-center text-xs"
                disabled={maxColumns === 1}
              />
            </div>

            <p className="text-muted-foreground mt-1 text-[9px]">
              {config.scrollDirection === "horizontal" ? "격자로 배치, 가로 스크롤" : "격자로 배치, 세로 스크롤"}
            </p>
            <p className="text-muted-foreground mt-0.5 text-[9px]">
              {maxColumns === 1
                ? "현재 모드에서 열 최대 1 (모드 변경 시 자동 적용)"
                : "모드 변경 시 열/행 자동 적용 / 열 최대 2"}
            </p>
          </div>
        </div>
      </CollapsibleSection>
    </div>
  );
}

// ===== 데이터 소스 탭 =====

function DataSourceTab({
  config,
  onUpdate,
}: {
  config: PopCardListConfig;
  onUpdate: (partial: Partial<PopCardListConfig>) => void;
}) {
  const dataSource = config.dataSource || DEFAULT_DATA_SOURCE;
  const [tables, setTables] = useState<TableInfo[]>([]);
  const [columns, setColumns] = useState<ColumnInfo[]>([]);

  // 테이블 목록 로드
  useEffect(() => {
    fetchTableList().then(setTables);
  }, []);

  // 테이블 선택 시 컬럼 목록 로드
  useEffect(() => {
    if (dataSource.tableName) {
      fetchTableColumns(dataSource.tableName).then(setColumns);
    } else {
      setColumns([]);
    }
  }, [dataSource.tableName]);

  const updateDataSource = (partial: Partial<CardListDataSource>) => {
    onUpdate({
      dataSource: { ...dataSource, ...partial },
    });
  };

  // 테이블이 선택되지 않은 경우
  if (!dataSource.tableName) {
    return (
      <div className="flex flex-col items-center justify-center py-8 text-center">
        <Database className="text-muted-foreground/50 mb-2 h-8 w-8" />
        <p className="text-muted-foreground text-xs">먼저 테이블 탭에서 테이블을 선택하세요</p>
      </div>
    );
  }

  return (
    <div className="space-y-4">
      {/* 현재 선택된 테이블 표시 */}
      <div className="bg-muted/30 flex items-center gap-2 rounded-md border px-3 py-2">
        <Database className="text-muted-foreground h-4 w-4" />
        <span className="text-xs font-medium">{dataSource.tableName}</span>
      </div>

      {/* 조인 설정 */}
      <CollapsibleSection
        title="조인 설정"
        badge={dataSource.joins && dataSource.joins.length > 0 ? `${dataSource.joins.length}개` : "없음"}
      >
        <JoinSettingsSection dataSource={dataSource} tables={tables} onUpdate={updateDataSource} />
      </CollapsibleSection>

      {/* 필터 설정 */}
      <CollapsibleSection
        title="필터 조건"
        badge={dataSource.filters && dataSource.filters.length > 0 ? `${dataSource.filters.length}개` : "없음"}
      >
        <FilterSettingsSection dataSource={dataSource} columns={columns} onUpdate={updateDataSource} />
      </CollapsibleSection>

      {/* 정렬 설정 */}
      <CollapsibleSection title="정렬 기준" badge={dataSource.sort ? "설정됨" : "없음"}>
        <SortSettingsSection dataSource={dataSource} columns={columns} onUpdate={updateDataSource} />
      </CollapsibleSection>

      {/* 표시 개수 */}
      <CollapsibleSection
        title="표시 개수"
        badge={dataSource.limit?.mode === "limited" ? `${dataSource.limit.count}개` : "전체"}
      >
        <LimitSettingsSection dataSource={dataSource} onUpdate={updateDataSource} />
      </CollapsibleSection>
    </div>
  );
}

// ===== 카드 템플릿 탭 =====

function CardTemplateTab({
  config,
  onUpdate,
}: {
  config: PopCardListConfig;
  onUpdate: (partial: Partial<PopCardListConfig>) => void;
}) {
  const dataSource = config.dataSource || DEFAULT_DATA_SOURCE;
  const template = config.cardTemplate || DEFAULT_TEMPLATE;
  const [columns, setColumns] = useState<ColumnInfo[]>([]);

  // 테이블 컬럼 로드
  useEffect(() => {
    if (dataSource.tableName) {
      fetchTableColumns(dataSource.tableName).then(setColumns);
    } else {
      setColumns([]);
    }
  }, [dataSource.tableName]);

  const updateTemplate = (partial: Partial<CardTemplateConfig>) => {
    onUpdate({
      cardTemplate: { ...template, ...partial },
    });
  };

  // 테이블 미선택 시 안내
  if (!dataSource.tableName) {
    return (
      <div className="flex h-40 items-center justify-center text-center">
        <div className="text-muted-foreground">
          <p className="text-sm">테이블을 먼저 선택해주세요</p>
          <p className="mt-1 text-xs">데이터 소스 탭에서 테이블을 선택하세요</p>
        </div>
      </div>
    );
  }

  return (
    <div className="space-y-4">
      {/* 헤더 설정 */}
      <CollapsibleSection title="헤더 설정" defaultOpen>
        <HeaderSettingsSection
          header={template.header || DEFAULT_HEADER}
          columns={columns}
          onUpdate={(header) => updateTemplate({ header })}
        />
      </CollapsibleSection>

      {/* 이미지 설정 */}
      <CollapsibleSection title="이미지 설정" defaultOpen>
        <ImageSettingsSection
          image={template.image || DEFAULT_IMAGE}
          columns={columns}
          onUpdate={(image) => updateTemplate({ image })}
        />
      </CollapsibleSection>

      {/* 본문 필드 */}
      <CollapsibleSection title="본문 필드" badge={`${template.body?.fields?.length || 0}개`} defaultOpen>
        <BodyFieldsSection
          body={template.body || DEFAULT_BODY}
          columns={columns}
          onUpdate={(body) => updateTemplate({ body })}
        />
      </CollapsibleSection>

      {/* 입력 필드 설정 */}
      <CollapsibleSection title="입력 필드" defaultOpen={false}>
        <InputFieldSettingsSection
          inputField={config.inputField}
          columns={columns}
          onUpdate={(inputField) => onUpdate({ inputField })}
        />
      </CollapsibleSection>

      {/* 계산 필드 설정 */}
      <CollapsibleSection title="계산 필드" defaultOpen={false}>
        <CalculatedFieldSettingsSection
          calculatedField={config.calculatedField}
          columns={columns}
          onUpdate={(calculatedField) => onUpdate({ calculatedField })}
        />
      </CollapsibleSection>

      {/* 담기 버튼 설정 */}
      <CollapsibleSection title="담기 버튼 (pop-icon)" defaultOpen={false}>
        <CartActionSettingsSection cartAction={config.cartAction} onUpdate={(cartAction) => onUpdate({ cartAction })} />
      </CollapsibleSection>
    </div>
  );
}

// ===== 접기/펴기 섹션 컴포넌트 =====

function CollapsibleSection({
  title,
  badge,
  defaultOpen = false,
  children,
}: {
  title: string;
  badge?: string;
  defaultOpen?: boolean;
  children: React.ReactNode;
}) {
  const [open, setOpen] = useState(defaultOpen);

  return (
    <div className="rounded-md border">
      <button
        type="button"
        className="hover:bg-muted/50 flex w-full items-center justify-between px-3 py-2 text-left transition-colors"
        onClick={() => setOpen(!open)}
      >
        <div className="flex items-center gap-2">
          {open ? (
            <ChevronDown className="text-muted-foreground h-3.5 w-3.5" />
          ) : (
            <ChevronRight className="text-muted-foreground h-3.5 w-3.5" />
          )}
          <span className="text-xs font-medium">{title}</span>
        </div>
        {badge && <span className="bg-muted text-muted-foreground rounded px-1.5 py-0.5 text-[10px]">{badge}</span>}
      </button>
      {open && <div className="border-t px-3 py-3">{children}</div>}
    </div>
  );
}

// ===== 헤더 설정 섹션 =====

function HeaderSettingsSection({
  header,
  columns,
  onUpdate,
}: {
  header: CardHeaderConfig;
  columns: ColumnInfo[];
  onUpdate: (header: CardHeaderConfig) => void;
}) {
  return (
    <div className="space-y-3">
      {/* 코드 필드 */}
      <div>
        <Label className="text-[10px]">코드 필드</Label>
        <Select
          value={header.codeField || "__none__"}
          onValueChange={(val) => onUpdate({ ...header, codeField: val === "__none__" ? undefined : val })}
        >
          <SelectTrigger className="mt-1 h-7 text-xs">
            <SelectValue placeholder="컬럼 선택 (선택사항)" />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="__none__">선택 안함</SelectItem>
            {columns.map((col) => (
              <SelectItem key={col.name} value={col.name}>
                {col.name}
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
        <p className="text-muted-foreground mt-1 text-[10px]">카드 헤더 왼쪽에 표시될 코드 (예: ITEM032)</p>
      </div>

      {/* 제목 필드 */}
      <div>
        <Label className="text-[10px]">제목 필드</Label>
        <Select
          value={header.titleField || "__none__"}
          onValueChange={(val) => onUpdate({ ...header, titleField: val === "__none__" ? undefined : val })}
        >
          <SelectTrigger className="mt-1 h-7 text-xs">
            <SelectValue placeholder="컬럼 선택 (선택사항)" />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="__none__">선택 안함</SelectItem>
            {columns.map((col) => (
              <SelectItem key={col.name} value={col.name}>
                {col.name}
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
        <p className="text-muted-foreground mt-1 text-[10px]">카드 헤더 오른쪽에 표시될 제목 (예: 너트 M10)</p>
      </div>
    </div>
  );
}

// ===== 이미지 설정 섹션 =====

function ImageSettingsSection({
  image,
  columns,
  onUpdate,
}: {
  image: CardImageConfig;
  columns: ColumnInfo[];
  onUpdate: (image: CardImageConfig) => void;
}) {
  return (
    <div className="space-y-3">
      {/* 이미지 사용 여부 */}
      <div className="flex items-center justify-between">
        <Label className="text-[10px]">이미지 사용</Label>
        <Switch checked={image.enabled} onCheckedChange={(checked) => onUpdate({ ...image, enabled: checked })} />
      </div>

      {image.enabled && (
        <>
          {/* 기본 이미지 미리보기 */}
          <div className="bg-muted/30 rounded-md border p-3">
            <div className="text-muted-foreground mb-2 text-[10px]">기본 이미지 미리보기</div>
            <div className="flex justify-center">
              <div className="bg-card flex h-16 w-16 items-center justify-center rounded-md border">
                <img
                  src={image.defaultImage || DEFAULT_CARD_IMAGE}
                  alt="기본 이미지"
                  className="h-12 w-12 object-contain"
                />
              </div>
            </div>
          </div>

          {/* 기본 이미지 URL */}
          <div>
            <Label className="text-[10px]">기본 이미지 URL</Label>
            <Input
              value={image.defaultImage || ""}
              onChange={(e) =>
                onUpdate({
                  ...image,
                  defaultImage: e.target.value || DEFAULT_CARD_IMAGE,
                })
              }
              placeholder="이미지 URL 입력"
              className="mt-1 h-7 text-xs"
            />
            <p className="text-muted-foreground mt-1 text-[10px]">이미지가 없는 항목에 표시될 기본 이미지</p>
          </div>

          {/* 이미지 컬럼 선택 */}
          <div>
            <Label className="text-[10px]">이미지 URL 컬럼 (선택)</Label>
            <Select
              value={image.imageColumn || "__none__"}
              onValueChange={(val) => onUpdate({ ...image, imageColumn: val === "__none__" ? undefined : val })}
            >
              <SelectTrigger className="mt-1 h-7 text-xs">
                <SelectValue placeholder="컬럼 선택 (선택사항)" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="__none__">선택 안함 (기본 이미지 사용)</SelectItem>
                {columns.map((col) => (
                  <SelectItem key={col.name} value={col.name}>
                    {col.name}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
            <p className="text-muted-foreground mt-1 text-[10px]">
              DB에서 이미지 URL을 가져올 컬럼. URL이 없으면 기본 이미지 사용
            </p>
          </div>
        </>
      )}
    </div>
  );
}

// ===== 본문 필드 섹션 =====

function BodyFieldsSection({
  body,
  columns,
  onUpdate,
}: {
  body: CardBodyConfig;
  columns: ColumnInfo[];
  onUpdate: (body: CardBodyConfig) => void;
}) {
  const fields = body.fields || [];

  // 필드 추가
  const addField = () => {
    const newField: CardFieldBinding = {
      id: `field-${Date.now()}`,
      columnName: "",
      label: "",
      textColor: undefined,
    };
    onUpdate({ fields: [...fields, newField] });
  };

  // 필드 업데이트
  const updateField = (index: number, updated: CardFieldBinding) => {
    const newFields = [...fields];
    newFields[index] = updated;
    onUpdate({ fields: newFields });
  };

  // 필드 삭제
  const deleteField = (index: number) => {
    const newFields = fields.filter((_, i) => i !== index);
    onUpdate({ fields: newFields });
  };

  // 필드 순서 이동
  const moveField = (index: number, direction: "up" | "down") => {
    const newIndex = direction === "up" ? index - 1 : index + 1;
    if (newIndex < 0 || newIndex >= fields.length) return;

    const newFields = [...fields];
    [newFields[index], newFields[newIndex]] = [newFields[newIndex], newFields[index]];
    onUpdate({ fields: newFields });
  };

  return (
    <div className="space-y-3">
      {/* 필드 목록 */}
      {fields.length === 0 ? (
        <div className="bg-muted/30 rounded-md border border-dashed p-4 text-center">
          <p className="text-muted-foreground text-xs">본문에 표시할 필드를 추가하세요</p>
        </div>
      ) : (
        <div className="space-y-2">
          {fields.map((field, index) => (
            <FieldEditor
              key={field.id}
              field={field}
              index={index}
              columns={columns}
              totalCount={fields.length}
              onUpdate={(updated) => updateField(index, updated)}
              onDelete={() => deleteField(index)}
              onMove={(dir) => moveField(index, dir)}
            />
          ))}
        </div>
      )}

      {/* 필드 추가 버튼 */}
      <Button variant="outline" size="sm" className="w-full text-xs" onClick={addField}>
        <Plus className="mr-1 h-3 w-3" />
        필드 추가
      </Button>
    </div>
  );
}

// ===== 필드 편집기 =====

function FieldEditor({
  field,
  index,
  columns,
  totalCount,
  onUpdate,
  onDelete,
  onMove,
}: {
  field: CardFieldBinding;
  index: number;
  columns: ColumnInfo[];
  totalCount: number;
  onUpdate: (field: CardFieldBinding) => void;
  onDelete: () => void;
  onMove: (direction: "up" | "down") => void;
}) {
  return (
    <div className="bg-card rounded-md border p-2">
      <div className="flex items-start gap-2">
        {/* 순서 이동 버튼 */}
        <div className="flex flex-col gap-0.5 pt-1">
          <button
            type="button"
            className="text-muted-foreground hover:bg-muted rounded p-0.5 disabled:opacity-30"
            onClick={() => onMove("up")}
            disabled={index === 0}
          >
            <ChevronDown className="h-3 w-3 rotate-180" />
          </button>
          <button
            type="button"
            className="text-muted-foreground hover:bg-muted rounded p-0.5 disabled:opacity-30"
            onClick={() => onMove("down")}
            disabled={index === totalCount - 1}
          >
            <ChevronDown className="h-3 w-3" />
          </button>
        </div>

        {/* 필드 설정 */}
        <div className="flex-1 space-y-2">
          <div className="flex gap-2">
            {/* 라벨 */}
            <div className="flex-1">
              <Label className="text-[10px]">라벨</Label>
              <Input
                value={field.label}
                onChange={(e) => onUpdate({ ...field, label: e.target.value })}
                placeholder="예: 발주일"
                className="mt-1 h-7 text-xs"
              />
            </div>

            {/* 컬럼 */}
            <div className="flex-1">
              <Label className="text-[10px]">컬럼</Label>
              <Select
                value={field.columnName || "__placeholder__"}
                onValueChange={(val) => onUpdate({ ...field, columnName: val === "__placeholder__" ? "" : val })}
              >
                <SelectTrigger className="mt-1 h-7 text-xs">
                  <SelectValue placeholder="선택" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="__placeholder__" disabled>
                    컬럼 선택
                  </SelectItem>
                  {columns.map((col) => (
                    <SelectItem key={col.name} value={col.name}>
                      {col.name}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
          </div>

          {/* 텍스트 색상 */}
          <div>
            <Label className="text-[10px]">텍스트 색상</Label>
            <Select
              value={field.textColor || "__default__"}
              onValueChange={(val) => onUpdate({ ...field, textColor: val === "__default__" ? undefined : val })}
            >
              <SelectTrigger className="mt-1 h-7 text-xs">
                <SelectValue placeholder="기본" />
              </SelectTrigger>
              <SelectContent>
                {COLOR_OPTIONS.map((opt) => (
                  <SelectItem key={opt.value} value={opt.value}>
                    <div className="flex items-center gap-2">
                      {opt.value !== "__default__" && (
                        <div className="h-3 w-3 rounded-full" style={{ backgroundColor: opt.value }} />
                      )}
                      {opt.label}
                    </div>
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
        </div>

        {/* 삭제 버튼 */}
        <Button variant="ghost" size="icon" className="text-destructive h-6 w-6 shrink-0" onClick={onDelete}>
          <Trash2 className="h-3 w-3" />
        </Button>
      </div>
    </div>
  );
}

// ===== 입력 필드 설정 섹션 =====

function InputFieldSettingsSection({
  inputField,
  columns,
  onUpdate,
}: {
  inputField?: CardInputFieldConfig;
  columns: ColumnInfo[];
  onUpdate: (inputField: CardInputFieldConfig) => void;
}) {
  const field = inputField || {
    enabled: false,
    label: "발주 수량",
    unit: "EA",
    defaultValue: 0,
    min: 0,
    max: 999999,
    step: 1,
  };

  const updateField = (partial: Partial<CardInputFieldConfig>) => {
    onUpdate({ ...field, ...partial });
  };

  return (
    <div className="space-y-3">
      {/* 활성화 스위치 */}
      <div className="flex items-center justify-between">
        <Label className="text-[10px]">입력 필드 사용</Label>
        <Switch checked={field.enabled} onCheckedChange={(enabled) => updateField({ enabled })} />
      </div>

      {field.enabled && (
        <>
          {/* 라벨 */}
          <div>
            <Label className="text-muted-foreground text-[10px]">라벨</Label>
            <Input
              value={field.label || ""}
              onChange={(e) => updateField({ label: e.target.value })}
              className="mt-1 h-7 text-xs"
              placeholder="발주 수량"
            />
          </div>

          {/* 단위 */}
          <div>
            <Label className="text-muted-foreground text-[10px]">단위</Label>
            <Input
              value={field.unit || ""}
              onChange={(e) => updateField({ unit: e.target.value })}
              className="mt-1 h-7 text-xs"
              placeholder="EA"
            />
          </div>

          {/* 기본값 */}
          <div>
            <Label className="text-muted-foreground text-[10px]">기본값</Label>
            <Input
              type="number"
              value={field.defaultValue || 0}
              onChange={(e) => updateField({ defaultValue: parseInt(e.target.value, 10) || 0 })}
              className="mt-1 h-7 text-xs"
              placeholder="0"
            />
          </div>

          {/* 최소/최대값 */}
          <div className="grid grid-cols-2 gap-2">
            <div>
              <Label className="text-muted-foreground text-[10px]">최소값</Label>
              <Input
                type="number"
                value={field.min || 0}
                onChange={(e) => updateField({ min: parseInt(e.target.value, 10) || 0 })}
                className="mt-1 h-7 text-xs"
                placeholder="0"
              />
            </div>
            <div>
              <Label className="text-muted-foreground text-[10px]">최대값</Label>
              <Input
                type="number"
                value={field.max || 999999}
                onChange={(e) => updateField({ max: parseInt(e.target.value, 10) || 999999 })}
                className="mt-1 h-7 text-xs"
                placeholder="999999"
              />
            </div>
          </div>

          {/* 최대값 컬럼 */}
          <div>
            <Label className="text-muted-foreground text-[10px]">최대값 컬럼 (선택)</Label>
            <Select
              value={field.maxColumn || "__none__"}
              onValueChange={(val) => updateField({ maxColumn: val === "__none__" ? undefined : val })}
            >
              <SelectTrigger className="mt-1 h-7 text-xs">
                <SelectValue placeholder="컬럼 선택 (선택사항)" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="__none__">선택 안함 (위 고정 최대값 사용)</SelectItem>
                {columns.map((col) => (
                  <SelectItem key={col.name} value={col.name}>
                    {col.name}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
            <p className="text-muted-foreground mt-1 text-[9px]">
              설정 시 각 카드 행의 해당 컬럼 값이 숫자패드 최대값으로 사용됨 (예: unreceived_qty)
            </p>
          </div>

          {/* 저장 컬럼 (선택사항) */}
          <div>
            <Label className="text-muted-foreground text-[10px]">저장 컬럼 (선택사항)</Label>
            <Select
              value={field.columnName || "__none__"}
              onValueChange={(val) => updateField({ columnName: val === "__none__" ? undefined : val })}
            >
              <SelectTrigger className="mt-1 h-7 text-xs">
                <SelectValue placeholder="컬럼 선택" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="__none__">선택 안함</SelectItem>
                {columns.map((col) => (
                  <SelectItem key={col.name} value={col.name}>
                    {col.name}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
            <p className="text-muted-foreground mt-1 text-[9px]">입력값을 저장할 DB 컬럼 (현재는 로컬 상태만 유지)</p>
          </div>
        </>
      )}
    </div>
  );
}

// ===== 계산 필드 설정 섹션 =====

function CalculatedFieldSettingsSection({
  calculatedField,
  columns,
  onUpdate,
}: {
  calculatedField?: CardCalculatedFieldConfig;
  columns: ColumnInfo[];
  onUpdate: (calculatedField: CardCalculatedFieldConfig) => void;
}) {
  const field = calculatedField || {
    enabled: false,
    label: "미입고",
    formula: "",
    sourceColumns: [],
    unit: "EA",
  };

  const updateField = (partial: Partial<CardCalculatedFieldConfig>) => {
    onUpdate({ ...field, ...partial });
  };

  return (
    <div className="space-y-3">
      {/* 활성화 스위치 */}
      <div className="flex items-center justify-between">
        <Label className="text-[10px]">계산 필드 사용</Label>
        <Switch checked={field.enabled} onCheckedChange={(enabled) => updateField({ enabled })} />
      </div>

      {field.enabled && (
        <>
          {/* 라벨 */}
          <div>
            <Label className="text-muted-foreground text-[10px]">라벨</Label>
            <Input
              value={field.label || ""}
              onChange={(e) => updateField({ label: e.target.value })}
              className="mt-1 h-7 text-xs"
              placeholder="미입고"
            />
          </div>

          {/* 계산식 */}
          <div>
            <Label className="text-muted-foreground text-[10px]">계산식</Label>
            <Input
              value={field.formula || ""}
              onChange={(e) => updateField({ formula: e.target.value })}
              className="mt-1 h-7 font-mono text-xs"
              placeholder="$input - received_qty"
            />
            <p className="text-muted-foreground mt-1 text-[9px]">사용 가능: 컬럼명, $input (입력값), +, -, *, /</p>
          </div>

          {/* 단위 */}
          <div>
            <Label className="text-muted-foreground text-[10px]">단위</Label>
            <Input
              value={field.unit || ""}
              onChange={(e) => updateField({ unit: e.target.value })}
              className="mt-1 h-7 text-xs"
              placeholder="EA"
            />
          </div>

          {/* 사용 가능한 컬럼 목록 */}
          <div>
            <Label className="text-muted-foreground text-[10px]">사용 가능한 컬럼</Label>
            <div className="bg-muted/30 mt-1 max-h-24 overflow-y-auto rounded border p-2">
              <div className="flex flex-wrap gap-1">
                {columns.map((col) => (
                  <span
                    key={col.name}
                    className="bg-muted hover:bg-primary/20 cursor-pointer rounded px-1.5 py-0.5 text-[9px]"
                    onClick={() => {
                      // 클릭 시 계산식에 컬럼명 추가
                      const currentFormula = field.formula || "";
                      updateField({ formula: currentFormula + col.name });
                    }}
                  >
                    {col.name}
                  </span>
                ))}
              </div>
            </div>
            <p className="text-muted-foreground mt-1 text-[9px]">클릭하면 계산식에 추가됩니다</p>
          </div>
        </>
      )}
    </div>
  );
}

// ===== 조인 설정 섹션 =====

function JoinSettingsSection({
  dataSource,
  tables,
  onUpdate,
}: {
  dataSource: CardListDataSource;
  tables: TableInfo[];
  onUpdate: (partial: Partial<CardListDataSource>) => void;
}) {
  const joins = dataSource.joins || [];
  const [sourceColumns, setSourceColumns] = useState<ColumnInfo[]>([]);
  const [targetColumnsMap, setTargetColumnsMap] = useState<Record<string, ColumnInfo[]>>({});

  // 소스 테이블 컬럼 로드
  useEffect(() => {
    if (dataSource.tableName) {
      fetchTableColumns(dataSource.tableName).then(setSourceColumns);
    }
  }, [dataSource.tableName]);

  // 조인 추가
  const addJoin = () => {
    const newJoin: CardColumnJoin = {
      targetTable: "",
      joinType: "LEFT",
      sourceColumn: "",
      targetColumn: "",
    };
    onUpdate({ joins: [...joins, newJoin] });
  };

  // 조인 업데이트
  const updateJoin = (index: number, updated: CardColumnJoin) => {
    const newJoins = [...joins];
    newJoins[index] = updated;
    onUpdate({ joins: newJoins });

    // 대상 테이블 컬럼 로드
    if (updated.targetTable && !targetColumnsMap[updated.targetTable]) {
      fetchTableColumns(updated.targetTable).then((cols) => {
        setTargetColumnsMap((prev) => ({
          ...prev,
          [updated.targetTable]: cols,
        }));
      });
    }
  };

  // 조인 삭제
  const deleteJoin = (index: number) => {
    const newJoins = joins.filter((_, i) => i !== index);
    onUpdate({ joins: newJoins.length > 0 ? newJoins : undefined });
  };

  return (
    <div className="space-y-3">
      {joins.length === 0 ? (
        <div className="bg-muted/30 rounded-md border border-dashed p-3 text-center">
          <p className="text-muted-foreground text-xs">다른 테이블과 조인하여 추가 컬럼을 사용할 수 있습니다</p>
        </div>
      ) : (
        <div className="space-y-2">
          {joins.map((join, index) => (
            <div key={index} className="bg-card space-y-2 rounded-md border p-2">
              <div className="flex items-center justify-between">
                <span className="text-[10px] font-medium">조인 {index + 1}</span>
                <Button
                  variant="ghost"
                  size="icon"
                  className="text-destructive h-5 w-5"
                  onClick={() => deleteJoin(index)}
                >
                  <Trash2 className="h-3 w-3" />
                </Button>
              </div>

              {/* 조인 타입 */}
              <Select
                value={join.joinType}
                onValueChange={(val) =>
                  updateJoin(index, {
                    ...join,
                    joinType: val as "LEFT" | "INNER" | "RIGHT",
                  })
                }
              >
                <SelectTrigger className="h-7 text-xs">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="LEFT">LEFT JOIN</SelectItem>
                  <SelectItem value="INNER">INNER JOIN</SelectItem>
                  <SelectItem value="RIGHT">RIGHT JOIN</SelectItem>
                </SelectContent>
              </Select>

              {/* 대상 테이블 */}
              <Select
                value={join.targetTable || ""}
                onValueChange={(val) =>
                  updateJoin(index, {
                    ...join,
                    targetTable: val,
                    targetColumn: "",
                  })
                }
              >
                <SelectTrigger className="h-7 text-xs">
                  <SelectValue placeholder="대상 테이블" />
                </SelectTrigger>
                <SelectContent>
                  {tables
                    .filter((t) => t.tableName !== dataSource.tableName)
                    .map((table) => (
                      <SelectItem key={table.tableName} value={table.tableName}>
                        {table.displayName || table.tableName}
                      </SelectItem>
                    ))}
                </SelectContent>
              </Select>

              {/* ON 조건 */}
              {join.targetTable && (
                <div className="bg-muted/50 flex items-center gap-1 rounded p-1.5">
                  <Select
                    value={join.sourceColumn || ""}
                    onValueChange={(val) => updateJoin(index, { ...join, sourceColumn: val })}
                  >
                    <SelectTrigger className="h-6 flex-1 text-[10px]">
                      <SelectValue placeholder="소스 컬럼" />
                    </SelectTrigger>
                    <SelectContent>
                      {sourceColumns.map((col) => (
                        <SelectItem key={col.name} value={col.name}>
                          {col.name}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                  <span className="text-muted-foreground text-[10px]">=</span>
                  <Select
                    value={join.targetColumn || ""}
                    onValueChange={(val) => updateJoin(index, { ...join, targetColumn: val })}
                  >
                    <SelectTrigger className="h-6 flex-1 text-[10px]">
                      <SelectValue placeholder="대상 컬럼" />
                    </SelectTrigger>
                    <SelectContent>
                      {(targetColumnsMap[join.targetTable] || []).map((col) => (
                        <SelectItem key={col.name} value={col.name}>
                          {col.name}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
              )}
            </div>
          ))}
        </div>
      )}

      <Button variant="outline" size="sm" className="w-full text-xs" onClick={addJoin}>
        <Plus className="mr-1 h-3 w-3" />
        조인 추가
      </Button>
    </div>
  );
}

// ===== 필터 설정 섹션 =====

function FilterSettingsSection({
  dataSource,
  columns,
  onUpdate,
}: {
  dataSource: CardListDataSource;
  columns: ColumnInfo[];
  onUpdate: (partial: Partial<CardListDataSource>) => void;
}) {
  const filters = dataSource.filters || [];

  const operators: { value: FilterOperator; label: string }[] = [
    { value: "=", label: "=" },
    { value: "!=", label: "!=" },
    { value: ">", label: ">" },
    { value: ">=", label: ">=" },
    { value: "<", label: "<" },
    { value: "<=", label: "<=" },
    { value: "like", label: "LIKE" },
  ];

  // 필터 추가
  const addFilter = () => {
    const newFilter: CardColumnFilter = {
      column: "",
      operator: "=",
      value: "",
    };
    onUpdate({ filters: [...filters, newFilter] });
  };

  // 필터 업데이트
  const updateFilter = (index: number, updated: CardColumnFilter) => {
    const newFilters = [...filters];
    newFilters[index] = updated;
    onUpdate({ filters: newFilters });
  };

  // 필터 삭제
  const deleteFilter = (index: number) => {
    const newFilters = filters.filter((_, i) => i !== index);
    onUpdate({ filters: newFilters.length > 0 ? newFilters : undefined });
  };

  return (
    <div className="space-y-3">
      {filters.length === 0 ? (
        <div className="bg-muted/30 rounded-md border border-dashed p-3 text-center">
          <p className="text-muted-foreground text-xs">필터 조건을 추가하여 데이터를 필터링할 수 있습니다</p>
        </div>
      ) : (
        <div className="space-y-2">
          {filters.map((filter, index) => (
            <div key={index} className="bg-card flex items-center gap-1 rounded-md border p-1.5">
              <Select
                value={filter.column || ""}
                onValueChange={(val) => updateFilter(index, { ...filter, column: val })}
              >
                <SelectTrigger className="h-7 flex-1 text-xs">
                  <SelectValue placeholder="컬럼" />
                </SelectTrigger>
                <SelectContent>
                  {columns.map((col) => (
                    <SelectItem key={col.name} value={col.name}>
                      {col.name}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>

              <Select
                value={filter.operator}
                onValueChange={(val) =>
                  updateFilter(index, {
                    ...filter,
                    operator: val as FilterOperator,
                  })
                }
              >
                <SelectTrigger className="h-7 w-16 text-xs">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  {operators.map((op) => (
                    <SelectItem key={op.value} value={op.value}>
                      {op.label}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>

              <Input
                value={filter.value}
                onChange={(e) => updateFilter(index, { ...filter, value: e.target.value })}
                placeholder="값"
                className="h-7 flex-1 text-xs"
              />

              <Button
                variant="ghost"
                size="icon"
                className="text-destructive h-7 w-7 shrink-0"
                onClick={() => deleteFilter(index)}
              >
                <Trash2 className="h-3 w-3" />
              </Button>
            </div>
          ))}
        </div>
      )}

      <Button variant="outline" size="sm" className="w-full text-xs" onClick={addFilter}>
        <Plus className="mr-1 h-3 w-3" />
        필터 추가
      </Button>
    </div>
  );
}

// ===== 정렬 설정 섹션 =====

function SortSettingsSection({
  dataSource,
  columns,
  onUpdate,
}: {
  dataSource: CardListDataSource;
  columns: ColumnInfo[];
  onUpdate: (partial: Partial<CardListDataSource>) => void;
}) {
  const sort = dataSource.sort;

  return (
    <div className="space-y-3">
      {/* 정렬 사용 여부 */}
      <div className="flex gap-2">
        <button
          type="button"
          className={`flex-1 rounded border px-2 py-1.5 text-xs ${
            !sort ? "border-primary bg-primary/10" : "border-input"
          }`}
          onClick={() => onUpdate({ sort: undefined })}
        >
          정렬 없음
        </button>
        <button
          type="button"
          className={`flex-1 rounded border px-2 py-1.5 text-xs ${
            sort ? "border-primary bg-primary/10" : "border-input"
          }`}
          onClick={() => onUpdate({ sort: { column: "", direction: "asc" } })}
        >
          정렬 사용
        </button>
      </div>

      {sort && (
        <div className="space-y-2">
          {/* 정렬 컬럼 */}
          <div>
            <Label className="text-[10px]">정렬 컬럼</Label>
            <Select value={sort.column || ""} onValueChange={(val) => onUpdate({ sort: { ...sort, column: val } })}>
              <SelectTrigger className="mt-1 h-7 text-xs">
                <SelectValue placeholder="컬럼 선택" />
              </SelectTrigger>
              <SelectContent>
                {columns.map((col) => (
                  <SelectItem key={col.name} value={col.name}>
                    {col.name}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>

          {/* 정렬 방향 */}
          <div>
            <Label className="text-[10px]">정렬 방향</Label>
            <div className="mt-1 flex gap-2">
              <button
                type="button"
                className={`flex-1 rounded border px-2 py-1.5 text-xs ${
                  sort.direction === "asc" ? "border-primary bg-primary/10" : "border-input"
                }`}
                onClick={() => onUpdate({ sort: { ...sort, direction: "asc" } })}
              >
                오름차순
              </button>
              <button
                type="button"
                className={`flex-1 rounded border px-2 py-1.5 text-xs ${
                  sort.direction === "desc" ? "border-primary bg-primary/10" : "border-input"
                }`}
                onClick={() => onUpdate({ sort: { ...sort, direction: "desc" } })}
              >
                내림차순
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

// ===== 표시 개수 설정 섹션 =====

function LimitSettingsSection({
  dataSource,
  onUpdate,
}: {
  dataSource: CardListDataSource;
  onUpdate: (partial: Partial<CardListDataSource>) => void;
}) {
  const limit = dataSource.limit || { mode: "all" as const };
  const isLimited = limit.mode === "limited";

  return (
    <div className="space-y-3">
      {/* 모드 선택 */}
      <div className="flex gap-2">
        <button
          type="button"
          className={`flex-1 rounded border px-2 py-1.5 text-xs ${
            !isLimited ? "border-primary bg-primary/10" : "border-input"
          }`}
          onClick={() => onUpdate({ limit: { mode: "all" } })}
        >
          전체 보기
        </button>
        <button
          type="button"
          className={`flex-1 rounded border px-2 py-1.5 text-xs ${
            isLimited ? "border-primary bg-primary/10" : "border-input"
          }`}
          onClick={() => onUpdate({ limit: { mode: "limited", count: 10 } })}
        >
          개수 제한
        </button>
      </div>

      {isLimited && (
        <div>
          <Label className="text-[10px]">표시 개수</Label>
          <Input
            type="number"
            min={1}
            value={limit.count || 10}
            onChange={(e) =>
              onUpdate({
                limit: {
                  mode: "limited",
                  count: parseInt(e.target.value, 10) || 10,
                },
              })
            }
            className="mt-1 h-7 text-xs"
          />
        </div>
      )}
    </div>
  );
}

// ===== 담기 버튼 설정 섹션 =====

function CartActionSettingsSection({
  cartAction,
  onUpdate,
}: {
  cartAction?: CardCartActionConfig;
  onUpdate: (cartAction: CardCartActionConfig) => void;
}) {
  const action: CardCartActionConfig = cartAction || {
    navigateMode: "none",
    iconType: "lucide",
    iconValue: "ShoppingCart",
    label: "담기",
    cancelLabel: "취소",
  };

  const update = (partial: Partial<CardCartActionConfig>) => {
    onUpdate({ ...action, ...partial });
  };

  return (
    <div className="space-y-3">
      {/* 네비게이션 모드 */}
      <div>
        <Label className="text-[10px]">담기 후 이동</Label>
        <Select value={action.navigateMode} onValueChange={(v) => update({ navigateMode: v as "none" | "screen" })}>
          <SelectTrigger className="mt-1 h-7 text-xs">
            <SelectValue />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="none">없음 (토스트만)</SelectItem>
            <SelectItem value="screen">POP 화면 이동</SelectItem>
          </SelectContent>
        </Select>
      </div>

      {/* 대상 화면 ID (screen 모드일 때만) */}
      {action.navigateMode === "screen" && (
        <div>
          <Label className="text-[10px]">장바구니 화면 ID</Label>
          <Input
            value={action.targetScreenId || ""}
            onChange={(e) => update({ targetScreenId: e.target.value })}
            placeholder="예: 15"
            className="mt-1 h-7 text-xs"
          />
          <p className="text-muted-foreground mt-1 text-[10px]">담기 클릭 시 이동할 POP 화면의 screenId</p>
        </div>
      )}

      {/* 아이콘 타입 */}
      <div>
        <Label className="text-[10px]">아이콘 타입</Label>
        <Select
          value={action.iconType || "lucide"}
          onValueChange={(v) => update({ iconType: v as "lucide" | "emoji" })}
        >
          <SelectTrigger className="mt-1 h-7 text-xs">
            <SelectValue />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="lucide">Lucide 아이콘</SelectItem>
            <SelectItem value="emoji">이모지</SelectItem>
          </SelectContent>
        </Select>
      </div>

      {/* 아이콘 값 */}
      <div>
        <Label className="text-[10px]">{action.iconType === "emoji" ? "이모지" : "Lucide 아이콘명"}</Label>
        <Input
          value={action.iconValue || ""}
          onChange={(e) => update({ iconValue: e.target.value })}
          placeholder={action.iconType === "emoji" ? "예: 🛒" : "예: ShoppingCart"}
          className="mt-1 h-7 text-xs"
        />
        {action.iconType === "lucide" && (
          <p className="text-muted-foreground mt-1 text-[10px]">PascalCase로 입력 (ShoppingCart, Package, Truck 등)</p>
        )}
      </div>

      {/* 담기 라벨 */}
      <div>
        <Label className="text-[10px]">담기 라벨</Label>
        <Input
          value={action.label || ""}
          onChange={(e) => update({ label: e.target.value })}
          placeholder="담기"
          className="mt-1 h-7 text-xs"
        />
      </div>

      {/* 취소 라벨 */}
      <div>
        <Label className="text-[10px]">취소 라벨</Label>
        <Input
          value={action.cancelLabel || ""}
          onChange={(e) => update({ cancelLabel: e.target.value })}
          placeholder="취소"
          className="mt-1 h-7 text-xs"
        />
      </div>
    </div>
  );
}
