"use client";

/**
 * V2 타임라인 스케줄러 설정 패널
 * 토스식 단계별 UX: 스케줄 데이터 설정 -> 소스 데이터 설정 -> 리소스 설정 -> 표시 설정(접힘) -> 고급 설정(접힘)
 */

import React, { useState, useEffect } 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 { Switch } from "@/components/ui/switch";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command";
import { Settings, ChevronDown, Check, ChevronsUpDown, Database, Users, Layers, Filter, Link, Zap, Trash2, Plus, GripVertical } from "lucide-react";
import { cn } from "@/lib/utils";
import { tableTypeApi } from "@/lib/api/screen";
import type { TimelineSchedulerConfig, ScheduleType, SourceDataConfig, ResourceFieldMapping, FieldMapping, ZoomLevel, ToolbarAction } from "@/lib/registry/components/v2-timeline-scheduler/types";
import { zoomLevelOptions, scheduleTypeOptions, viewModeOptions, dataSourceOptions, toolbarIconOptions } from "@/lib/registry/components/v2-timeline-scheduler/config";

interface V2TimelineSchedulerConfigPanelProps {
  config: TimelineSchedulerConfig;
  onChange: (config: Partial<TimelineSchedulerConfig>) => void;
}

interface TableInfo {
  tableName: string;
  displayName: string;
}

interface ColumnInfo {
  columnName: string;
  displayName: string;
}

export const V2TimelineSchedulerConfigPanel: React.FC<V2TimelineSchedulerConfigPanelProps> = ({
  config,
  onChange,
}) => {
  const [tables, setTables] = useState<TableInfo[]>([]);
  const [sourceColumns, setSourceColumns] = useState<ColumnInfo[]>([]);
  const [resourceColumns, setResourceColumns] = useState<ColumnInfo[]>([]);
  const [scheduleColumns, setScheduleColumns] = useState<ColumnInfo[]>([]);
  const [loading, setLoading] = useState(false);
  const [sourceTableOpen, setSourceTableOpen] = useState(false);
  const [resourceTableOpen, setResourceTableOpen] = useState(false);
  const [customTableOpen, setCustomTableOpen] = useState(false);
  const [scheduleDataOpen, setScheduleDataOpen] = useState(true);
  const [filterLinkOpen, setFilterLinkOpen] = useState(false);
  const [sourceDataOpen, setSourceDataOpen] = useState(true);
  const [resourceOpen, setResourceOpen] = useState(true);
  const [displayOpen, setDisplayOpen] = useState(false);
  const [advancedOpen, setAdvancedOpen] = useState(false);
  const [actionsOpen, setActionsOpen] = useState(false);
  const [newFilterKey, setNewFilterKey] = useState("");
  const [newFilterValue, setNewFilterValue] = useState("");
  const [linkedFilterTableOpen, setLinkedFilterTableOpen] = useState(false);
  const [expandedActionId, setExpandedActionId] = useState<string | null>(null);

  useEffect(() => {
    const loadTables = async () => {
      setLoading(true);
      try {
        const tableList = await tableTypeApi.getTables();
        if (Array.isArray(tableList)) {
          setTables(
            tableList.map((t: any) => ({
              tableName: t.table_name || t.tableName,
              displayName: t.display_name || t.displayName || t.table_name || t.tableName,
            }))
          );
        }
      } catch (err) {
        console.error("테이블 목록 로드 오류:", err);
      } finally {
        setLoading(false);
      }
    };
    loadTables();
  }, []);

  useEffect(() => {
    const loadSourceColumns = async () => {
      if (!config.sourceConfig?.tableName) {
        setSourceColumns([]);
        return;
      }
      try {
        const columns = await tableTypeApi.getColumns(config.sourceConfig.tableName);
        if (Array.isArray(columns)) {
          setSourceColumns(
            columns.map((col: any) => ({
              columnName: col.column_name || col.columnName,
              displayName: col.display_name || col.displayName || col.column_name || col.columnName,
            }))
          );
        }
      } catch (err) {
        console.error("소스 컬럼 로드 오류:", err);
        setSourceColumns([]);
      }
    };
    loadSourceColumns();
  }, [config.sourceConfig?.tableName]);

  useEffect(() => {
    const loadResourceColumns = async () => {
      if (!config.resourceTable) {
        setResourceColumns([]);
        return;
      }
      try {
        const columns = await tableTypeApi.getColumns(config.resourceTable);
        if (Array.isArray(columns)) {
          setResourceColumns(
            columns.map((col: any) => ({
              columnName: col.column_name || col.columnName,
              displayName: col.display_name || col.displayName || col.column_name || col.columnName,
            }))
          );
        }
      } catch (err) {
        console.error("리소스 컬럼 로드 오류:", err);
        setResourceColumns([]);
      }
    };
    loadResourceColumns();
  }, [config.resourceTable]);

  // 커스텀 테이블 또는 schedule_mng 컬럼 로드
  useEffect(() => {
    const loadScheduleColumns = async () => {
      const tableName = config.useCustomTable && config.customTableName
        ? config.customTableName
        : "schedule_mng";
      try {
        const columns = await tableTypeApi.getColumns(tableName);
        if (Array.isArray(columns)) {
          setScheduleColumns(
            columns.map((col: any) => ({
              columnName: col.column_name || col.columnName,
              displayName: col.display_name || col.displayName || col.column_name || col.columnName,
            }))
          );
        }
      } catch (err) {
        console.error("스케줄 테이블 컬럼 로드 오류:", err);
        setScheduleColumns([]);
      }
    };
    loadScheduleColumns();
  }, [config.useCustomTable, config.customTableName]);

  const updateConfig = (updates: Partial<TimelineSchedulerConfig>) => {
    onChange({ ...config, ...updates });
  };

  const updateSourceConfig = (updates: Partial<SourceDataConfig>) => {
    updateConfig({
      sourceConfig: {
        ...config.sourceConfig,
        ...updates,
      },
    });
  };

  const updateFieldMapping = (field: string, value: string) => {
    updateConfig({
      fieldMapping: {
        ...config.fieldMapping,
        id: config.fieldMapping?.id || "id",
        resourceId: config.fieldMapping?.resourceId || "resource_id",
        title: config.fieldMapping?.title || "title",
        startDate: config.fieldMapping?.startDate || "start_date",
        endDate: config.fieldMapping?.endDate || "end_date",
        [field]: value,
      },
    });
  };

  const updateResourceFieldMapping = (field: string, value: string) => {
    updateConfig({
      resourceFieldMapping: {
        ...config.resourceFieldMapping,
        id: config.resourceFieldMapping?.id || "id",
        name: config.resourceFieldMapping?.name || "name",
        [field]: value,
      },
    });
  };

  return (
    <div className="space-y-4">
      {/* ─── 1단계: 스케줄 데이터 테이블 설정 ─── */}
      <Collapsible open={scheduleDataOpen} onOpenChange={setScheduleDataOpen}>
        <CollapsibleTrigger asChild>
          <button
            type="button"
            className="flex w-full items-center justify-between rounded-lg border bg-muted/30 px-4 py-2.5 text-left transition-colors hover:bg-muted/50"
          >
            <div className="flex items-center gap-2">
              <Layers className="h-4 w-4 text-muted-foreground" />
              <span className="text-sm font-medium">스케줄 데이터 테이블</span>
              <Badge variant="secondary" className="text-[10px] h-5">8개 필드</Badge>
            </div>
            <ChevronDown className={cn("h-4 w-4 text-muted-foreground transition-transform duration-200", scheduleDataOpen && "rotate-180")} />
          </button>
        </CollapsibleTrigger>
        <CollapsibleContent>
          <div className="rounded-b-lg border border-t-0 p-4 space-y-3">
        {/* 스케줄 타입 */}
        <div className="flex items-center justify-between py-1">
          <span className="text-xs text-muted-foreground truncate">스케줄 타입</span>
          <Select
            value={config.scheduleType || "PRODUCTION"}
            onValueChange={(v) => updateConfig({ scheduleType: v as ScheduleType })}
          >
            <SelectTrigger className="h-7 w-[140px] text-xs">
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              {scheduleTypeOptions.map((opt) => (
                <SelectItem key={opt.value} value={opt.value}>
                  {opt.label}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>

        {/* 뷰 모드 */}
        <div className="flex items-center justify-between py-1">
          <div>
            <p className="text-xs text-muted-foreground truncate">표시 모드</p>
            <p className="text-[10px] text-muted-foreground mt-0.5">
              {viewModeOptions.find((o) => o.value === (config.viewMode || "resource"))?.description}
            </p>
          </div>
          <Select
            value={config.viewMode || "resource"}
            onValueChange={(v) => updateConfig({ viewMode: v as any })}
          >
            <SelectTrigger className="h-7 w-[140px] text-xs">
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              {viewModeOptions.map((opt) => (
                <SelectItem key={opt.value} value={opt.value}>
                  {opt.label}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>

        {/* 커스텀 테이블 사용 여부 */}
        <div className="flex items-center justify-between py-1">
          <div>
            <p className="text-xs text-muted-foreground">커스텀 테이블 사용</p>
            <p className="text-[10px] text-muted-foreground mt-0.5">OFF: schedule_mng 사용</p>
          </div>
          <Switch
            checked={config.useCustomTable ?? false}
            onCheckedChange={(v) => updateConfig({ useCustomTable: v })}
          />
        </div>

        {/* 커스텀 테이블 선택 (Combobox) */}
        {config.useCustomTable && (
          <div className="space-y-1">
            <span className="text-xs text-muted-foreground">커스텀 테이블명</span>
            <Popover open={customTableOpen} onOpenChange={setCustomTableOpen}>
              <PopoverTrigger asChild>
                <Button
                  variant="outline"
                  role="combobox"
                  aria-expanded={customTableOpen}
                  className="h-8 w-full justify-between text-xs"
                  disabled={loading}
                >
                  {config.customTableName
                    ? tables.find((t) => t.tableName === config.customTableName)?.displayName ||
                      config.customTableName
                    : "커스텀 테이블 선택..."}
                  <ChevronsUpDown className="ml-2 h-3 w-3 shrink-0 opacity-50" />
                </Button>
              </PopoverTrigger>
              <PopoverContent className="p-0" style={{ width: "var(--radix-popover-trigger-width)" }} align="start">
                <Command
                  filter={(value, search) => {
                    return value.toLowerCase().includes(search.toLowerCase()) ? 1 : 0;
                  }}
                >
                  <CommandInput placeholder="테이블 검색..." className="text-xs" />
                  <CommandList>
                    <CommandEmpty className="text-xs">테이블을 찾을 수 없습니다.</CommandEmpty>
                    <CommandGroup>
                      {tables.map((table) => (
                        <CommandItem
                          key={table.tableName}
                          value={`${table.displayName} ${table.tableName}`}
                          onSelect={() => {
                            updateConfig({ customTableName: table.tableName, selectedTable: table.tableName });
                            setCustomTableOpen(false);
                          }}
                          className="text-xs"
                        >
                          <Check
                            className={cn(
                              "mr-2 h-3 w-3",
                              config.customTableName === table.tableName ? "opacity-100" : "opacity-0"
                            )}
                          />
                          <div className="flex flex-col">
                            <span>{table.displayName}</span>
                            <span className="text-muted-foreground text-[10px]">{table.tableName}</span>
                          </div>
                        </CommandItem>
                      ))}
                    </CommandGroup>
                  </CommandList>
                </Command>
              </PopoverContent>
            </Popover>
          </div>
        )}

        {/* 디자인 모드 표시용 테이블명 (selectedTable) */}
        {!config.useCustomTable && (
          <div className="flex items-center justify-between py-1">
            <span className="text-xs text-muted-foreground truncate">디자인 모드 표시 테이블</span>
            <Input
              value={config.selectedTable || "schedule_mng"}
              onChange={(e) => updateConfig({ selectedTable: e.target.value })}
              placeholder="schedule_mng"
              className="h-7 w-[140px] text-xs"
            />
          </div>
        )}

        {/* 스케줄 필드 매핑 */}
        <div className="ml-1 border-l-2 border-primary/20 pl-3 space-y-2 pt-1">
          <p className="text-xs font-medium text-primary truncate">스케줄 필드 매핑</p>

          <div className="flex items-center justify-between py-1">
            <span className="text-xs text-muted-foreground truncate">ID 필드 *</span>
            <Select
              value={config.fieldMapping?.id || "schedule_id"}
              onValueChange={(v) => updateFieldMapping("id", v)}
            >
              <SelectTrigger className="h-7 w-[130px] text-xs">
                <SelectValue placeholder="선택" />
              </SelectTrigger>
              <SelectContent>
                {scheduleColumns.map((col) => (
                  <SelectItem key={col.columnName} value={col.columnName}>
                    {col.displayName}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>

          <div className="flex items-center justify-between py-1">
            <span className="text-xs text-muted-foreground truncate">리소스 ID 필드 *</span>
            <Select
              value={config.fieldMapping?.resourceId || "resource_id"}
              onValueChange={(v) => updateFieldMapping("resourceId", v)}
            >
              <SelectTrigger className="h-7 w-[130px] text-xs">
                <SelectValue placeholder="선택" />
              </SelectTrigger>
              <SelectContent>
                {scheduleColumns.map((col) => (
                  <SelectItem key={col.columnName} value={col.columnName}>
                    {col.displayName}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>

          <div className="flex items-center justify-between py-1">
            <span className="text-xs text-muted-foreground truncate">제목 필드 *</span>
            <Select
              value={config.fieldMapping?.title || "schedule_name"}
              onValueChange={(v) => updateFieldMapping("title", v)}
            >
              <SelectTrigger className="h-7 w-[130px] text-xs">
                <SelectValue placeholder="선택" />
              </SelectTrigger>
              <SelectContent>
                {scheduleColumns.map((col) => (
                  <SelectItem key={col.columnName} value={col.columnName}>
                    {col.displayName}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>

          <div className="flex items-center justify-between py-1">
            <span className="text-xs text-muted-foreground truncate">시작일 필드 *</span>
            <Select
              value={config.fieldMapping?.startDate || "start_date"}
              onValueChange={(v) => updateFieldMapping("startDate", v)}
            >
              <SelectTrigger className="h-7 w-[130px] text-xs">
                <SelectValue placeholder="선택" />
              </SelectTrigger>
              <SelectContent>
                {scheduleColumns.map((col) => (
                  <SelectItem key={col.columnName} value={col.columnName}>
                    {col.displayName}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>

          <div className="flex items-center justify-between py-1">
            <span className="text-xs text-muted-foreground truncate">종료일 필드 *</span>
            <Select
              value={config.fieldMapping?.endDate || "end_date"}
              onValueChange={(v) => updateFieldMapping("endDate", v)}
            >
              <SelectTrigger className="h-7 w-[130px] text-xs">
                <SelectValue placeholder="선택" />
              </SelectTrigger>
              <SelectContent>
                {scheduleColumns.map((col) => (
                  <SelectItem key={col.columnName} value={col.columnName}>
                    {col.displayName}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>

          <div className="flex items-center justify-between py-1">
            <span className="text-xs text-muted-foreground truncate">상태 필드</span>
            <Select
              value={config.fieldMapping?.status || ""}
              onValueChange={(v) => updateFieldMapping("status", v)}
            >
              <SelectTrigger className="h-7 w-[130px] text-xs">
                <SelectValue placeholder="선택" />
              </SelectTrigger>
              <SelectContent>
                {scheduleColumns.map((col) => (
                  <SelectItem key={col.columnName} value={col.columnName}>
                    {col.displayName}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>

          <div className="flex items-center justify-between py-1">
            <span className="text-xs text-muted-foreground truncate">진행률 필드</span>
            <Select
              value={config.fieldMapping?.progress || ""}
              onValueChange={(v) => updateFieldMapping("progress", v)}
            >
              <SelectTrigger className="h-7 w-[130px] text-xs">
                <SelectValue placeholder="선택" />
              </SelectTrigger>
              <SelectContent>
                {scheduleColumns.map((col) => (
                  <SelectItem key={col.columnName} value={col.columnName}>
                    {col.displayName}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>

          <div className="flex items-center justify-between py-1">
            <span className="text-xs text-muted-foreground truncate">색상 필드</span>
            <Select
              value={config.fieldMapping?.color || ""}
              onValueChange={(v) => updateFieldMapping("color", v)}
            >
              <SelectTrigger className="h-7 w-[130px] text-xs">
                <SelectValue placeholder="선택" />
              </SelectTrigger>
              <SelectContent>
                {scheduleColumns.map((col) => (
                  <SelectItem key={col.columnName} value={col.columnName}>
                    {col.displayName}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
          </div>
        </div>
      </CollapsibleContent>
    </Collapsible>

      {/* ─── 필터 & 연동 설정 ─── */}
      <Collapsible open={filterLinkOpen} onOpenChange={setFilterLinkOpen}>
        <CollapsibleTrigger asChild>
          <button
            type="button"
            className="flex w-full items-center justify-between rounded-lg border bg-muted/30 px-4 py-2.5 text-left transition-colors hover:bg-muted/50"
          >
            <div className="flex items-center gap-2">
              <Filter className="h-4 w-4 text-muted-foreground" />
              <span className="text-sm font-medium">필터 & 연동 설정</span>
              <Badge variant="secondary" className="text-[10px] h-5">
                {Object.keys(config.staticFilters || {}).length + (config.linkedFilter ? 1 : 0)}개
              </Badge>
            </div>
            <ChevronDown className={cn("h-4 w-4 text-muted-foreground transition-transform duration-200", filterLinkOpen && "rotate-180")} />
          </button>
        </CollapsibleTrigger>
        <CollapsibleContent>
          <div className="rounded-b-lg border border-t-0 p-4 space-y-4">
            {/* 정적 필터 */}
            <div className="space-y-2">
              <p className="text-xs font-medium text-primary">정적 필터 (staticFilters)</p>
              <p className="text-[10px] text-muted-foreground">데이터 조회 시 항상 적용되는 고정 필터 조건</p>

              {Object.entries(config.staticFilters || {}).map(([key, value]) => (
                <div key={key} className="flex items-center gap-2">
                  <Input value={key} disabled className="h-7 flex-1 text-xs bg-muted/30" />
                  <span className="text-xs text-muted-foreground">=</span>
                  <Input value={value} disabled className="h-7 flex-1 text-xs bg-muted/30" />
                  <Button
                    variant="ghost"
                    size="sm"
                    onClick={() => {
                      const updated = { ...config.staticFilters };
                      delete updated[key];
                      updateConfig({ staticFilters: Object.keys(updated).length > 0 ? updated : undefined });
                    }}
                    className="h-7 w-7 p-0 text-destructive hover:text-destructive"
                  >
                    <Trash2 className="h-3 w-3" />
                  </Button>
                </div>
              ))}

              <div className="flex items-center gap-2">
                <Input
                  value={newFilterKey}
                  onChange={(e) => setNewFilterKey(e.target.value)}
                  placeholder="필드명 (예: product_type)"
                  className="h-7 flex-1 text-xs"
                />
                <span className="text-xs text-muted-foreground">=</span>
                <Input
                  value={newFilterValue}
                  onChange={(e) => setNewFilterValue(e.target.value)}
                  placeholder="값 (예: 완제품)"
                  className="h-7 flex-1 text-xs"
                />
                <Button
                  variant="outline"
                  size="sm"
                  onClick={() => {
                    if (!newFilterKey.trim()) return;
                    updateConfig({
                      staticFilters: {
                        ...(config.staticFilters || {}),
                        [newFilterKey.trim()]: newFilterValue.trim(),
                      },
                    });
                    setNewFilterKey("");
                    setNewFilterValue("");
                  }}
                  disabled={!newFilterKey.trim()}
                  className="h-7 w-7 p-0"
                >
                  <Plus className="h-3 w-3" />
                </Button>
              </div>
            </div>

            {/* 구분선 */}
            <div className="border-t" />

            {/* 연결 필터 */}
            <div className="space-y-2">
              <div className="flex items-center justify-between">
                <div>
                  <p className="text-xs font-medium text-primary flex items-center gap-1">
                    <Link className="h-3 w-3" />
                    연결 필터 (linkedFilter)
                  </p>
                  <p className="text-[10px] text-muted-foreground mt-0.5">다른 컴포넌트 선택에 따라 데이터를 필터링</p>
                </div>
                <Switch
                  checked={!!config.linkedFilter}
                  onCheckedChange={(v) => {
                    if (v) {
                      updateConfig({
                        linkedFilter: {
                          sourceField: "",
                          targetField: "",
                          showEmptyWhenNoSelection: true,
                          emptyMessage: "좌측 목록에서 항목을 선택하세요",
                        },
                      });
                    } else {
                      updateConfig({ linkedFilter: undefined });
                    }
                  }}
                />
              </div>

              {config.linkedFilter && (
                <div className="ml-1 border-l-2 border-primary/20 pl-3 space-y-2 pt-1">
                  <div className="flex items-center justify-between py-1">
                    <div>
                      <span className="text-xs text-muted-foreground">소스 테이블명</span>
                      <p className="text-[10px] text-muted-foreground mt-0.5">선택 이벤트의 tableName 매칭</p>
                    </div>
                    <Popover open={linkedFilterTableOpen} onOpenChange={setLinkedFilterTableOpen}>
                      <PopoverTrigger asChild>
                        <Button
                          variant="outline"
                          role="combobox"
                          className="h-7 w-[140px] justify-between text-xs"
                          disabled={loading}
                        >
                          {config.linkedFilter.sourceTableName || "선택..."}
                          <ChevronsUpDown className="ml-1 h-3 w-3 shrink-0 opacity-50" />
                        </Button>
                      </PopoverTrigger>
                      <PopoverContent className="p-0 w-[200px]" align="end">
                        <Command filter={(value, search) => value.toLowerCase().includes(search.toLowerCase()) ? 1 : 0}>
                          <CommandInput placeholder="테이블 검색..." className="text-xs" />
                          <CommandList>
                            <CommandEmpty className="text-xs p-2">없음</CommandEmpty>
                            <CommandGroup>
                              {tables.map((table) => (
                                <CommandItem
                                  key={table.tableName}
                                  value={`${table.displayName} ${table.tableName}`}
                                  onSelect={() => {
                                    updateConfig({
                                      linkedFilter: { ...config.linkedFilter!, sourceTableName: table.tableName },
                                    });
                                    setLinkedFilterTableOpen(false);
                                  }}
                                  className="text-xs"
                                >
                                  <Check className={cn("mr-2 h-3 w-3", config.linkedFilter?.sourceTableName === table.tableName ? "opacity-100" : "opacity-0")} />
                                  {table.displayName}
                                </CommandItem>
                              ))}
                            </CommandGroup>
                          </CommandList>
                        </Command>
                      </PopoverContent>
                    </Popover>
                  </div>

                  <div className="flex items-center justify-between py-1">
                    <span className="text-xs text-muted-foreground">소스 필드 (sourceField) *</span>
                    <Input
                      value={config.linkedFilter.sourceField || ""}
                      onChange={(e) => updateConfig({ linkedFilter: { ...config.linkedFilter!, sourceField: e.target.value } })}
                      placeholder="예: part_code"
                      className="h-7 w-[140px] text-xs"
                    />
                  </div>

                  <div className="flex items-center justify-between py-1">
                    <span className="text-xs text-muted-foreground">타겟 필드 (targetField) *</span>
                    <Input
                      value={config.linkedFilter.targetField || ""}
                      onChange={(e) => updateConfig({ linkedFilter: { ...config.linkedFilter!, targetField: e.target.value } })}
                      placeholder="예: item_code"
                      className="h-7 w-[140px] text-xs"
                    />
                  </div>

                  <div className="flex items-center justify-between py-1">
                    <span className="text-xs text-muted-foreground">빈 상태 메시지</span>
                    <Input
                      value={config.linkedFilter.emptyMessage || ""}
                      onChange={(e) => updateConfig({ linkedFilter: { ...config.linkedFilter!, emptyMessage: e.target.value } })}
                      placeholder="선택 안내 문구"
                      className="h-7 w-[180px] text-xs"
                    />
                  </div>

                  <div className="flex items-center justify-between py-1">
                    <span className="text-xs text-muted-foreground">선택 없을 때 빈 화면</span>
                    <Switch
                      checked={config.linkedFilter.showEmptyWhenNoSelection ?? true}
                      onCheckedChange={(v) => updateConfig({ linkedFilter: { ...config.linkedFilter!, showEmptyWhenNoSelection: v } })}
                    />
                  </div>
                </div>
              )}
            </div>
          </div>
        </CollapsibleContent>
      </Collapsible>

      {/* ─── 2단계: 소스 데이터 설정 ─── */}
      <Collapsible open={sourceDataOpen} onOpenChange={setSourceDataOpen}>
        <CollapsibleTrigger asChild>
          <button
            type="button"
            className="flex w-full items-center justify-between rounded-lg border bg-muted/30 px-4 py-2.5 text-left transition-colors hover:bg-muted/50"
          >
            <div className="flex items-center gap-2">
              <Database className="h-4 w-4 text-muted-foreground" />
              <span className="text-sm font-medium">소스 데이터 설정</span>
              <Badge variant="secondary" className="text-[10px] h-5">
                {config.sourceConfig?.tableName ? "4개 필드" : "미설정"}
              </Badge>
            </div>
            <ChevronDown className={cn("h-4 w-4 text-muted-foreground transition-transform duration-200", sourceDataOpen && "rotate-180")} />
          </button>
        </CollapsibleTrigger>
        <CollapsibleContent>
          <div className="rounded-b-lg border border-t-0 p-4 space-y-3">
        {/* 소스 테이블 Combobox */}
        <div className="space-y-1">
          <span className="text-xs text-muted-foreground truncate">소스 테이블 (수주/작업요청 등)</span>
          <Popover open={sourceTableOpen} onOpenChange={setSourceTableOpen}>
            <PopoverTrigger asChild>
              <Button
                variant="outline"
                role="combobox"
                aria-expanded={sourceTableOpen}
                className="h-8 w-full justify-between text-xs"
                disabled={loading}
              >
                {config.sourceConfig?.tableName
                  ? tables.find((t) => t.tableName === config.sourceConfig?.tableName)?.displayName ||
                    config.sourceConfig.tableName
                  : "소스 테이블 선택..."}
                <ChevronsUpDown className="ml-2 h-3 w-3 shrink-0 opacity-50" />
              </Button>
            </PopoverTrigger>
            <PopoverContent className="p-0" style={{ width: "var(--radix-popover-trigger-width)" }} align="start">
              <Command
                filter={(value, search) => {
                  return value.toLowerCase().includes(search.toLowerCase()) ? 1 : 0;
                }}
              >
                <CommandInput placeholder="테이블 검색..." className="text-xs" />
                <CommandList>
                  <CommandEmpty className="text-xs">테이블을 찾을 수 없습니다.</CommandEmpty>
                  <CommandGroup>
                    {tables.map((table) => (
                      <CommandItem
                        key={table.tableName}
                        value={`${table.displayName} ${table.tableName}`}
                        onSelect={() => {
                          updateSourceConfig({ tableName: table.tableName });
                          setSourceTableOpen(false);
                        }}
                        className="text-xs"
                      >
                        <Check
                          className={cn(
                            "mr-2 h-3 w-3",
                            config.sourceConfig?.tableName === table.tableName ? "opacity-100" : "opacity-0"
                          )}
                        />
                        <div className="flex flex-col">
                          <span>{table.displayName}</span>
                          <span className="text-muted-foreground text-[10px]">{table.tableName}</span>
                        </div>
                      </CommandItem>
                    ))}
                  </CommandGroup>
                </CommandList>
              </Command>
            </PopoverContent>
          </Popover>
        </div>

        {/* 소스 필드 매핑 (테이블 선택 시) */}
        {config.sourceConfig?.tableName && (
          <div className="ml-1 border-l-2 border-primary/20 pl-3 space-y-2 pt-1">
            <p className="text-xs font-medium text-primary truncate">필드 매핑</p>

            <div className="flex items-center justify-between py-1">
              <div>
                <span className="text-xs text-muted-foreground truncate">기준일 (마감일/납기일) *</span>
                <p className="text-[10px] text-muted-foreground mt-0.5">스케줄 종료일로 사용돼요</p>
              </div>
              <Select
                value={config.sourceConfig?.dueDateField || ""}
                onValueChange={(v) => updateSourceConfig({ dueDateField: v })}
              >
                <SelectTrigger className="h-7 w-[130px] text-xs">
                  <SelectValue placeholder="필수 선택" />
                </SelectTrigger>
                <SelectContent>
                  {sourceColumns.map((col) => (
                    <SelectItem key={col.columnName} value={col.columnName}>
                      {col.displayName}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>

            <div className="flex items-center justify-between py-1">
              <span className="text-xs text-muted-foreground truncate">수량 필드</span>
              <Select
                value={config.sourceConfig?.quantityField || ""}
                onValueChange={(v) => updateSourceConfig({ quantityField: v })}
              >
                <SelectTrigger className="h-7 w-[130px] text-xs">
                  <SelectValue placeholder="선택" />
                </SelectTrigger>
                <SelectContent>
                  {sourceColumns.map((col) => (
                    <SelectItem key={col.columnName} value={col.columnName}>
                      {col.displayName}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>

            <div className="flex items-center justify-between py-1">
              <span className="text-xs text-muted-foreground truncate">그룹 필드 (품목코드)</span>
              <Select
                value={config.sourceConfig?.groupByField || ""}
                onValueChange={(v) => updateSourceConfig({ groupByField: v })}
              >
                <SelectTrigger className="h-7 w-[130px] text-xs">
                  <SelectValue placeholder="선택" />
                </SelectTrigger>
                <SelectContent>
                  {sourceColumns.map((col) => (
                    <SelectItem key={col.columnName} value={col.columnName}>
                      {col.displayName}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>

            <div className="flex items-center justify-between py-1">
              <span className="text-xs text-muted-foreground truncate">그룹명 필드 (품목명)</span>
              <Select
                value={config.sourceConfig?.groupNameField || ""}
                onValueChange={(v) => updateSourceConfig({ groupNameField: v })}
              >
                <SelectTrigger className="h-7 w-[130px] text-xs">
                  <SelectValue placeholder="선택" />
                </SelectTrigger>
                <SelectContent>
                  {sourceColumns.map((col) => (
                    <SelectItem key={col.columnName} value={col.columnName}>
                      {col.displayName}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
          </div>
        )}
        </div>
      </CollapsibleContent>
    </Collapsible>

      {/* ─── 3단계: 리소스 설정 ─── */}
      <Collapsible open={resourceOpen} onOpenChange={setResourceOpen}>
        <CollapsibleTrigger asChild>
          <button
            type="button"
            className="flex w-full items-center justify-between rounded-lg border bg-muted/30 px-4 py-2.5 text-left transition-colors hover:bg-muted/50"
          >
            <div className="flex items-center gap-2">
              <Users className="h-4 w-4 text-muted-foreground" />
              <span className="text-sm font-medium">리소스 설정 (설비/작업자)</span>
              <Badge variant="secondary" className="text-[10px] h-5">
                {config.resourceTable ? "3개 필드" : "미설정"}
              </Badge>
            </div>
            <ChevronDown className={cn("h-4 w-4 text-muted-foreground transition-transform duration-200", resourceOpen && "rotate-180")} />
          </button>
        </CollapsibleTrigger>
        <CollapsibleContent>
          <div className="rounded-b-lg border border-t-0 p-4 space-y-3">
        {/* 리소스 테이블 Combobox */}
        <div className="space-y-1">
          <span className="text-xs text-muted-foreground truncate">리소스 테이블</span>
          <Popover open={resourceTableOpen} onOpenChange={setResourceTableOpen}>
            <PopoverTrigger asChild>
              <Button
                variant="outline"
                role="combobox"
                aria-expanded={resourceTableOpen}
                className="h-8 w-full justify-between text-xs"
                disabled={loading}
              >
                {config.resourceTable
                  ? tables.find((t) => t.tableName === config.resourceTable)?.displayName || config.resourceTable
                  : "리소스 테이블 선택..."}
                <ChevronsUpDown className="ml-2 h-3 w-3 shrink-0 opacity-50" />
              </Button>
            </PopoverTrigger>
            <PopoverContent className="p-0" style={{ width: "var(--radix-popover-trigger-width)" }} align="start">
              <Command
                filter={(value, search) => {
                  return value.toLowerCase().includes(search.toLowerCase()) ? 1 : 0;
                }}
              >
                <CommandInput placeholder="테이블 검색..." className="text-xs" />
                <CommandList>
                  <CommandEmpty className="text-xs">테이블을 찾을 수 없습니다.</CommandEmpty>
                  <CommandGroup>
                    {tables.map((table) => (
                      <CommandItem
                        key={table.tableName}
                        value={`${table.displayName} ${table.tableName}`}
                        onSelect={() => {
                          updateConfig({ resourceTable: table.tableName });
                          setResourceTableOpen(false);
                        }}
                        className="text-xs"
                      >
                        <Check
                          className={cn(
                            "mr-2 h-3 w-3",
                            config.resourceTable === table.tableName ? "opacity-100" : "opacity-0"
                          )}
                        />
                        <div className="flex flex-col">
                          <span>{table.displayName}</span>
                          <span className="text-muted-foreground text-[10px]">{table.tableName}</span>
                        </div>
                      </CommandItem>
                    ))}
                  </CommandGroup>
                </CommandList>
              </Command>
            </PopoverContent>
          </Popover>
        </div>

        {/* 리소스 필드 매핑 */}
        {config.resourceTable && (
          <div className="ml-1 border-l-2 border-primary/20 pl-3 space-y-2 pt-1">
            <p className="text-xs font-medium text-primary truncate">리소스 필드</p>

            <div className="flex items-center justify-between py-1">
              <span className="text-xs text-muted-foreground truncate">ID 필드</span>
              <Select
                value={config.resourceFieldMapping?.id || ""}
                onValueChange={(v) => updateResourceFieldMapping("id", v)}
              >
                <SelectTrigger className="h-7 w-[130px] text-xs">
                  <SelectValue placeholder="선택" />
                </SelectTrigger>
                <SelectContent>
                  {resourceColumns.map((col) => (
                    <SelectItem key={col.columnName} value={col.columnName}>
                      {col.displayName}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>

            <div className="flex items-center justify-between py-1">
              <span className="text-xs text-muted-foreground truncate">이름 필드</span>
              <Select
                value={config.resourceFieldMapping?.name || ""}
                onValueChange={(v) => updateResourceFieldMapping("name", v)}
              >
                <SelectTrigger className="h-7 w-[130px] text-xs">
                  <SelectValue placeholder="선택" />
                </SelectTrigger>
                <SelectContent>
                  {resourceColumns.map((col) => (
                    <SelectItem key={col.columnName} value={col.columnName}>
                      {col.displayName}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>

            <div className="flex items-center justify-between py-1">
              <span className="text-xs text-muted-foreground truncate">그룹 필드</span>
              <Select
                value={config.resourceFieldMapping?.group || ""}
                onValueChange={(v) => updateResourceFieldMapping("group", v)}
              >
                <SelectTrigger className="h-7 w-[130px] text-xs">
                  <SelectValue placeholder="선택" />
                </SelectTrigger>
                <SelectContent>
                  {resourceColumns.map((col) => (
                    <SelectItem key={col.columnName} value={col.columnName}>
                      {col.displayName}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
          </div>
        )}
        </div>
      </CollapsibleContent>
    </Collapsible>

      {/* ─── 4단계: 표시 설정 (Collapsible) ─── */}
      <Collapsible open={displayOpen} onOpenChange={setDisplayOpen}>
        <CollapsibleTrigger asChild>
          <button
            type="button"
            className="flex w-full items-center justify-between rounded-lg border bg-muted/30 px-4 py-2.5 text-left transition-colors hover:bg-muted/50"
          >
            <div className="flex items-center gap-2">
              <Settings className="h-4 w-4 text-muted-foreground" />
              <span className="text-sm font-medium">표시 설정</span>
              <Badge variant="secondary" className="text-[10px] h-5">18개</Badge>
            </div>
            <ChevronDown
              className={cn(
                "h-4 w-4 text-muted-foreground transition-transform duration-200",
                displayOpen && "rotate-180"
              )}
            />
          </button>
        </CollapsibleTrigger>
        <CollapsibleContent>
          <div className="rounded-b-lg border border-t-0 p-4 space-y-3">
            {/* 줌 레벨 */}
            <div className="flex items-center justify-between py-1">
              <span className="text-xs text-muted-foreground truncate">기본 줌 레벨</span>
              <Select
                value={config.defaultZoomLevel || "day"}
                onValueChange={(v) => updateConfig({ defaultZoomLevel: v as ZoomLevel })}
              >
                <SelectTrigger className="h-7 w-[100px] text-xs">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  {zoomLevelOptions.map((opt) => (
                    <SelectItem key={opt.value} value={opt.value}>
                      {opt.label}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>

            {/* 초기 표시 날짜 */}
            <div className="flex items-center justify-between py-1">
              <div>
                <span className="text-xs text-muted-foreground truncate">초기 표시 날짜</span>
                <p className="text-[10px] text-muted-foreground mt-0.5">비워두면 오늘 기준</p>
              </div>
              <Input
                type="date"
                value={config.initialDate || ""}
                onChange={(e) => updateConfig({ initialDate: e.target.value || undefined })}
                className="h-7 w-[140px] text-xs"
              />
            </div>

            {/* 높이 */}
            <div className="flex items-center justify-between py-1">
              <span className="text-xs text-muted-foreground truncate">높이 (px)</span>
              <Input
                type="number"
                value={config.height || 500}
                onChange={(e) => updateConfig({ height: parseInt(e.target.value) || 500 })}
                className="h-7 w-[100px] text-xs"
              />
            </div>

            {/* 최대 높이 */}
            <div className="flex items-center justify-between py-1">
              <span className="text-xs text-muted-foreground truncate">최대 높이 (px)</span>
              <Input
                type="number"
                value={typeof config.maxHeight === "number" ? config.maxHeight : ""}
                onChange={(e) => {
                  const val = e.target.value ? parseInt(e.target.value) : undefined;
                  updateConfig({ maxHeight: val });
                }}
                placeholder="제한 없음"
                className="h-7 w-[100px] text-xs"
              />
            </div>

            {/* 행 높이 */}
            <div className="flex items-center justify-between py-1">
              <span className="text-xs text-muted-foreground truncate">행 높이 (px)</span>
              <Input
                type="number"
                value={config.rowHeight || 50}
                onChange={(e) => updateConfig({ rowHeight: parseInt(e.target.value) || 50 })}
                className="h-7 w-[100px] text-xs"
              />
            </div>

            {/* 헤더 높이 */}
            <div className="flex items-center justify-between py-1">
              <span className="text-xs text-muted-foreground truncate">헤더 높이 (px)</span>
              <Input
                type="number"
                value={config.headerHeight || 60}
                onChange={(e) => updateConfig({ headerHeight: parseInt(e.target.value) || 60 })}
                className="h-7 w-[100px] text-xs"
              />
            </div>

            {/* 리소스 컬럼 너비 */}
            <div className="flex items-center justify-between py-1">
              <span className="text-xs text-muted-foreground truncate">리소스 컬럼 너비 (px)</span>
              <Input
                type="number"
                value={config.resourceColumnWidth || 150}
                onChange={(e) => updateConfig({ resourceColumnWidth: parseInt(e.target.value) || 150 })}
                className="h-7 w-[100px] text-xs"
              />
            </div>

            {/* 셀 너비 (줌 레벨별) */}
            <div className="space-y-2 pt-1">
              <span className="text-xs text-muted-foreground truncate">셀 너비 (줌 레벨별, px)</span>
              <div className="flex items-center gap-2">
                <div className="flex-1">
                  <span className="text-[10px] text-muted-foreground">일</span>
                  <Input
                    type="number"
                    value={config.cellWidth?.day || 60}
                    onChange={(e) => updateConfig({ cellWidth: { ...config.cellWidth, day: parseInt(e.target.value) || 60 } })}
                    className="h-7 text-xs"
                  />
                </div>
                <div className="flex-1">
                  <span className="text-[10px] text-muted-foreground">주</span>
                  <Input
                    type="number"
                    value={config.cellWidth?.week || 120}
                    onChange={(e) => updateConfig({ cellWidth: { ...config.cellWidth, week: parseInt(e.target.value) || 120 } })}
                    className="h-7 text-xs"
                  />
                </div>
                <div className="flex-1">
                  <span className="text-[10px] text-muted-foreground">월</span>
                  <Input
                    type="number"
                    value={config.cellWidth?.month || 40}
                    onChange={(e) => updateConfig({ cellWidth: { ...config.cellWidth, month: parseInt(e.target.value) || 40 } })}
                    className="h-7 text-xs"
                  />
                </div>
              </div>
            </div>

            {/* Switch 토글들 */}
            <div className="flex items-center justify-between py-1">
              <div>
                <p className="text-sm">편집 가능</p>
                <p className="text-[11px] text-muted-foreground">스케줄을 직접 수정할 수 있어요</p>
              </div>
              <Switch
                checked={config.editable ?? true}
                onCheckedChange={(v) => updateConfig({ editable: v })}
              />
            </div>

            <div className="flex items-center justify-between py-1">
              <div>
                <p className="text-sm">드래그 이동</p>
                <p className="text-[11px] text-muted-foreground">스케줄을 드래그해서 날짜를 변경해요</p>
              </div>
              <Switch
                checked={config.draggable ?? true}
                onCheckedChange={(v) => updateConfig({ draggable: v })}
              />
            </div>

            <div className="flex items-center justify-between py-1">
              <div>
                <p className="text-sm">리사이즈</p>
                <p className="text-[11px] text-muted-foreground">스케줄의 기간을 늘이거나 줄여요</p>
              </div>
              <Switch
                checked={config.resizable ?? true}
                onCheckedChange={(v) => updateConfig({ resizable: v })}
              />
            </div>

            <div className="flex items-center justify-between py-1">
              <div>
                <p className="text-sm">오늘 표시선</p>
                <p className="text-[11px] text-muted-foreground">오늘 날짜에 빨간 세로선을 표시해요</p>
              </div>
              <Switch
                checked={config.showTodayLine ?? true}
                onCheckedChange={(v) => updateConfig({ showTodayLine: v })}
              />
            </div>

            <div className="flex items-center justify-between py-1">
              <div>
                <p className="text-sm">진행률 표시</p>
                <p className="text-[11px] text-muted-foreground">각 스케줄의 진행률 바를 보여줘요</p>
              </div>
              <Switch
                checked={config.showProgress ?? true}
                onCheckedChange={(v) => updateConfig({ showProgress: v })}
              />
            </div>

            <div className="flex items-center justify-between py-1">
              <div>
                <p className="text-sm">충돌 표시</p>
                <p className="text-[11px] text-muted-foreground">스케줄 겹침 시 경고를 표시해요</p>
              </div>
              <Switch
                checked={config.showConflicts ?? true}
                onCheckedChange={(v) => updateConfig({ showConflicts: v })}
              />
            </div>

            <div className="flex items-center justify-between py-1">
              <div>
                <p className="text-sm">툴바 표시</p>
                <p className="text-[11px] text-muted-foreground">상단의 네비게이션/줌 컨트롤을 보여줘요</p>
              </div>
              <Switch
                checked={config.showToolbar ?? true}
                onCheckedChange={(v) => updateConfig({ showToolbar: v })}
              />
            </div>

            <div className="flex items-center justify-between py-1">
              <div>
                <p className="text-sm">줌 컨트롤 표시</p>
                <p className="text-[11px] text-muted-foreground">줌 레벨 변경 버튼을 보여줘요</p>
              </div>
              <Switch
                checked={config.showZoomControls ?? true}
                onCheckedChange={(v) => updateConfig({ showZoomControls: v })}
              />
            </div>

            <div className="flex items-center justify-between py-1">
              <div>
                <p className="text-sm">네비게이션 표시</p>
                <p className="text-[11px] text-muted-foreground">이전/다음/오늘 버튼을 보여줘요</p>
              </div>
              <Switch
                checked={config.showNavigation ?? true}
                onCheckedChange={(v) => updateConfig({ showNavigation: v })}
              />
            </div>

            <div className="flex items-center justify-between py-1">
              <div>
                <p className="text-sm">추가 버튼 표시</p>
                <p className="text-[11px] text-muted-foreground">스케줄 추가 버튼을 보여줘요</p>
              </div>
              <Switch
                checked={config.showAddButton ?? true}
                onCheckedChange={(v) => updateConfig({ showAddButton: v })}
              />
            </div>

            <div className="flex items-center justify-between py-1">
              <div>
                <p className="text-sm">범례 표시</p>
                <p className="text-[11px] text-muted-foreground">상태별 색상 범례를 보여줘요</p>
              </div>
              <Switch
                checked={config.showLegend ?? true}
                onCheckedChange={(v) => updateConfig({ showLegend: v })}
              />
            </div>
          </div>
        </CollapsibleContent>
      </Collapsible>

      {/* ─── 5단계: 고급 설정 - 상태별 색상 (Collapsible) ─── */}
      <Collapsible open={advancedOpen} onOpenChange={setAdvancedOpen}>
        <CollapsibleTrigger asChild>
          <button
            type="button"
            className="flex w-full items-center justify-between rounded-lg border bg-muted/30 px-4 py-2.5 text-left transition-colors hover:bg-muted/50"
          >
            <div className="flex items-center gap-2">
              <Settings className="h-4 w-4 text-muted-foreground" />
              <span className="text-sm font-medium">상태별 색상</span>
              <Badge variant="secondary" className="text-[10px] h-5">5개</Badge>
            </div>
            <ChevronDown
              className={cn(
                "h-4 w-4 text-muted-foreground transition-transform duration-200",
                advancedOpen && "rotate-180"
              )}
            />
          </button>
        </CollapsibleTrigger>
        <CollapsibleContent>
          <div className="rounded-b-lg border border-t-0 p-4 space-y-3">
            {[
              { key: "planned", label: "계획됨", defaultColor: "#3b82f6" },
              { key: "in_progress", label: "진행중", defaultColor: "#f59e0b" },
              { key: "completed", label: "완료", defaultColor: "#10b981" },
              { key: "delayed", label: "지연", defaultColor: "#ef4444" },
              { key: "cancelled", label: "취소", defaultColor: "#6b7280" },
            ].map((status) => (
              <div key={status.key} className="flex items-center justify-between py-1">
                <div className="flex items-center gap-2">
                  <div
                    className="h-3 w-3 rounded-full"
                    style={{
                      backgroundColor:
                        (config.statusColors as any)?.[status.key] || status.defaultColor,
                    }}
                  />
                  <span className="text-xs text-muted-foreground">{status.label}</span>
                </div>
                <div className="flex items-center gap-1.5">
                  <input
                    type="color"
                    value={(config.statusColors as any)?.[status.key] || status.defaultColor}
                    onChange={(e) =>
                      updateConfig({
                        statusColors: {
                          ...config.statusColors,
                          [status.key]: e.target.value,
                        },
                      })
                    }
                    className="h-7 w-7 cursor-pointer rounded border"
                  />
                  <Input
                    value={(config.statusColors as any)?.[status.key] || status.defaultColor}
                    onChange={(e) =>
                      updateConfig({
                        statusColors: {
                          ...config.statusColors,
                          [status.key]: e.target.value,
                        },
                      })
                    }
                    className="h-7 w-[80px] text-xs"
                  />
                </div>
              </div>
            ))}
          </div>
        </CollapsibleContent>
      </Collapsible>
      {/* ─── 6단계: 툴바 액션 설정 ─── */}
      <Collapsible open={actionsOpen} onOpenChange={setActionsOpen}>
        <CollapsibleTrigger asChild>
          <button
            type="button"
            className="flex w-full items-center justify-between rounded-lg border bg-muted/30 px-4 py-2.5 text-left transition-colors hover:bg-muted/50"
          >
            <div className="flex items-center gap-2">
              <Zap className="h-4 w-4 text-muted-foreground" />
              <span className="text-sm font-medium">툴바 액션</span>
              <Badge variant="secondary" className="text-[10px] h-5">
                {(config.toolbarActions || []).length}개
              </Badge>
            </div>
            <ChevronDown className={cn("h-4 w-4 text-muted-foreground transition-transform duration-200", actionsOpen && "rotate-180")} />
          </button>
        </CollapsibleTrigger>
        <CollapsibleContent>
          <div className="rounded-b-lg border border-t-0 p-4 space-y-3">
            <p className="text-[10px] text-muted-foreground">
              툴바에 커스텀 버튼을 추가하여 API 호출 (미리보기 → 확인 → 적용) 워크플로우를 구성해요
            </p>

            {/* 기존 액션 목록 */}
            {(config.toolbarActions || []).map((action, index) => (
              <Collapsible
                key={action.id}
                open={expandedActionId === action.id}
                onOpenChange={(open) => setExpandedActionId(open ? action.id : null)}
              >
                <div className="rounded-lg border">
                  <CollapsibleTrigger asChild>
                    <button
                      type="button"
                      className="flex w-full items-center justify-between px-3 py-2 text-left hover:bg-muted/30"
                    >
                      <div className="flex items-center gap-2">
                        <GripVertical className="h-3 w-3 text-muted-foreground/50" />
                        <div className={cn("h-3 w-3 rounded-sm", action.color?.split(" ")[0] || "bg-primary")} />
                        <span className="text-xs font-medium">{action.label || "새 액션"}</span>
                        <Badge variant="outline" className="text-[9px] h-4">
                          {action.dataSource === "linkedSelection" ? "연결선택" : "스케줄"}
                        </Badge>
                      </div>
                      <div className="flex items-center gap-1">
                        <Button
                          variant="ghost"
                          size="sm"
                          onClick={(e) => {
                            e.stopPropagation();
                            const updated = (config.toolbarActions || []).filter((_, i) => i !== index);
                            updateConfig({ toolbarActions: updated.length > 0 ? updated : undefined });
                          }}
                          className="h-6 w-6 p-0 text-destructive hover:text-destructive"
                        >
                          <Trash2 className="h-3 w-3" />
                        </Button>
                        <ChevronDown className={cn("h-3 w-3 text-muted-foreground transition-transform", expandedActionId === action.id && "rotate-180")} />
                      </div>
                    </button>
                  </CollapsibleTrigger>
                  <CollapsibleContent>
                    <div className="border-t px-3 py-3 space-y-2.5">
                      {/* 기본 설정 */}
                      <div className="flex items-center gap-2">
                        <div className="flex-1">
                          <span className="text-[10px] text-muted-foreground">버튼명</span>
                          <Input
                            value={action.label}
                            onChange={(e) => {
                              const updated = [...(config.toolbarActions || [])];
                              updated[index] = { ...updated[index], label: e.target.value };
                              updateConfig({ toolbarActions: updated });
                            }}
                            className="h-7 text-xs"
                          />
                        </div>
                        <div className="w-[110px]">
                          <span className="text-[10px] text-muted-foreground">아이콘</span>
                          <Select
                            value={action.icon || "Zap"}
                            onValueChange={(v) => {
                              const updated = [...(config.toolbarActions || [])];
                              updated[index] = { ...updated[index], icon: v as any };
                              updateConfig({ toolbarActions: updated });
                            }}
                          >
                            <SelectTrigger className="h-7 text-xs">
                              <SelectValue />
                            </SelectTrigger>
                            <SelectContent>
                              {toolbarIconOptions.map((opt) => (
                                <SelectItem key={opt.value} value={opt.value} className="text-xs">
                                  {opt.label}
                                </SelectItem>
                              ))}
                            </SelectContent>
                          </Select>
                        </div>
                      </div>

                      <div>
                        <span className="text-[10px] text-muted-foreground">버튼 색상 (Tailwind 클래스)</span>
                        <Input
                          value={action.color || ""}
                          onChange={(e) => {
                            const updated = [...(config.toolbarActions || [])];
                            updated[index] = { ...updated[index], color: e.target.value };
                            updateConfig({ toolbarActions: updated });
                          }}
                          placeholder="예: bg-emerald-600 hover:bg-emerald-700"
                          className="h-7 text-xs"
                        />
                      </div>

                      {/* API 설정 */}
                      <div className="border-t pt-2">
                        <p className="text-[10px] font-medium text-primary mb-1.5">API 설정</p>
                        <div className="space-y-1.5">
                          <div>
                            <span className="text-[10px] text-muted-foreground">미리보기 API *</span>
                            <Input
                              value={action.previewApi}
                              onChange={(e) => {
                                const updated = [...(config.toolbarActions || [])];
                                updated[index] = { ...updated[index], previewApi: e.target.value };
                                updateConfig({ toolbarActions: updated });
                              }}
                              placeholder="/production/generate-schedule/preview"
                              className="h-7 text-xs"
                            />
                          </div>
                          <div>
                            <span className="text-[10px] text-muted-foreground">적용 API *</span>
                            <Input
                              value={action.applyApi}
                              onChange={(e) => {
                                const updated = [...(config.toolbarActions || [])];
                                updated[index] = { ...updated[index], applyApi: e.target.value };
                                updateConfig({ toolbarActions: updated });
                              }}
                              placeholder="/production/generate-schedule"
                              className="h-7 text-xs"
                            />
                          </div>
                        </div>
                      </div>

                      {/* 다이얼로그 설정 */}
                      <div className="border-t pt-2">
                        <p className="text-[10px] font-medium text-primary mb-1.5">다이얼로그</p>
                        <div className="space-y-1.5">
                          <div>
                            <span className="text-[10px] text-muted-foreground">제목</span>
                            <Input
                              value={action.dialogTitle || ""}
                              onChange={(e) => {
                                const updated = [...(config.toolbarActions || [])];
                                updated[index] = { ...updated[index], dialogTitle: e.target.value };
                                updateConfig({ toolbarActions: updated });
                              }}
                              placeholder="자동 생성"
                              className="h-7 text-xs"
                            />
                          </div>
                          <div>
                            <span className="text-[10px] text-muted-foreground">설명</span>
                            <Input
                              value={action.dialogDescription || ""}
                              onChange={(e) => {
                                const updated = [...(config.toolbarActions || [])];
                                updated[index] = { ...updated[index], dialogDescription: e.target.value };
                                updateConfig({ toolbarActions: updated });
                              }}
                              placeholder="미리보기 후 확인하여 적용합니다"
                              className="h-7 text-xs"
                            />
                          </div>
                        </div>
                      </div>

                      {/* 데이터 소스 설정 */}
                      <div className="border-t pt-2">
                        <p className="text-[10px] font-medium text-primary mb-1.5">데이터 소스</p>
                        <div className="space-y-1.5">
                          <div>
                            <span className="text-[10px] text-muted-foreground">데이터 소스 유형 *</span>
                            <Select
                              value={action.dataSource}
                              onValueChange={(v) => {
                                const updated = [...(config.toolbarActions || [])];
                                updated[index] = { ...updated[index], dataSource: v as any };
                                updateConfig({ toolbarActions: updated });
                              }}
                            >
                              <SelectTrigger className="h-7 text-xs">
                                <SelectValue />
                              </SelectTrigger>
                              <SelectContent>
                                {dataSourceOptions.map((opt) => (
                                  <SelectItem key={opt.value} value={opt.value} className="text-xs">
                                    <div>
                                      <span>{opt.label}</span>
                                      <span className="ml-1 text-[10px] text-muted-foreground">({opt.description})</span>
                                    </div>
                                  </SelectItem>
                                ))}
                              </SelectContent>
                            </Select>
                          </div>

                          {action.dataSource === "linkedSelection" && (
                            <div className="ml-2 border-l-2 border-blue-200 pl-2 space-y-1.5">
                              <div className="flex items-center gap-2">
                                <div className="flex-1">
                                  <span className="text-[10px] text-muted-foreground">그룹 필드</span>
                                  <Input
                                    value={action.payloadConfig?.groupByField || ""}
                                    onChange={(e) => {
                                      const updated = [...(config.toolbarActions || [])];
                                      updated[index] = { ...updated[index], payloadConfig: { ...updated[index].payloadConfig, groupByField: e.target.value || undefined } };
                                      updateConfig({ toolbarActions: updated });
                                    }}
                                    placeholder="linkedFilter.sourceField 사용"
                                    className="h-7 text-xs"
                                  />
                                </div>
                                <div className="flex-1">
                                  <span className="text-[10px] text-muted-foreground">수량 필드</span>
                                  <Input
                                    value={action.payloadConfig?.quantityField || ""}
                                    onChange={(e) => {
                                      const updated = [...(config.toolbarActions || [])];
                                      updated[index] = { ...updated[index], payloadConfig: { ...updated[index].payloadConfig, quantityField: e.target.value || undefined } };
                                      updateConfig({ toolbarActions: updated });
                                    }}
                                    placeholder="balance_qty"
                                    className="h-7 text-xs"
                                  />
                                </div>
                              </div>
                              <div className="flex items-center gap-2">
                                <div className="flex-1">
                                  <span className="text-[10px] text-muted-foreground">기준일 필드</span>
                                  <Input
                                    value={action.payloadConfig?.dueDateField || ""}
                                    onChange={(e) => {
                                      const updated = [...(config.toolbarActions || [])];
                                      updated[index] = { ...updated[index], payloadConfig: { ...updated[index].payloadConfig, dueDateField: e.target.value || undefined } };
                                      updateConfig({ toolbarActions: updated });
                                    }}
                                    placeholder="due_date"
                                    className="h-7 text-xs"
                                  />
                                </div>
                                <div className="flex-1">
                                  <span className="text-[10px] text-muted-foreground">표시명 필드</span>
                                  <Input
                                    value={action.payloadConfig?.nameField || ""}
                                    onChange={(e) => {
                                      const updated = [...(config.toolbarActions || [])];
                                      updated[index] = { ...updated[index], payloadConfig: { ...updated[index].payloadConfig, nameField: e.target.value || undefined } };
                                      updateConfig({ toolbarActions: updated });
                                    }}
                                    placeholder="part_name"
                                    className="h-7 text-xs"
                                  />
                                </div>
                              </div>
                            </div>
                          )}

                          {action.dataSource === "currentSchedules" && (
                            <div className="ml-2 border-l-2 border-amber-200 pl-2 space-y-1.5">
                              <div className="flex items-center gap-2">
                                <div className="flex-1">
                                  <span className="text-[10px] text-muted-foreground">필터 필드</span>
                                  <Input
                                    value={action.payloadConfig?.scheduleFilterField || ""}
                                    onChange={(e) => {
                                      const updated = [...(config.toolbarActions || [])];
                                      updated[index] = { ...updated[index], payloadConfig: { ...updated[index].payloadConfig, scheduleFilterField: e.target.value || undefined } };
                                      updateConfig({ toolbarActions: updated });
                                    }}
                                    placeholder="product_type"
                                    className="h-7 text-xs"
                                  />
                                </div>
                                <div className="flex-1">
                                  <span className="text-[10px] text-muted-foreground">필터 값</span>
                                  <Input
                                    value={action.payloadConfig?.scheduleFilterValue || ""}
                                    onChange={(e) => {
                                      const updated = [...(config.toolbarActions || [])];
                                      updated[index] = { ...updated[index], payloadConfig: { ...updated[index].payloadConfig, scheduleFilterValue: e.target.value || undefined } };
                                      updateConfig({ toolbarActions: updated });
                                    }}
                                    placeholder="완제품"
                                    className="h-7 text-xs"
                                  />
                                </div>
                              </div>
                            </div>
                          )}
                        </div>
                      </div>

                      {/* 표시 조건 */}
                      <div className="border-t pt-2">
                        <p className="text-[10px] font-medium text-primary mb-1.5">표시 조건 (showWhen)</p>
                        <p className="text-[9px] text-muted-foreground mb-1">staticFilters 값과 비교하여 일치할 때만 버튼 표시</p>
                        {Object.entries(action.showWhen || {}).map(([key, value]) => (
                          <div key={key} className="flex items-center gap-1 mb-1">
                            <Input value={key} disabled className="h-6 flex-1 text-[10px] bg-muted/30" />
                            <span className="text-[10px]">=</span>
                            <Input value={value} disabled className="h-6 flex-1 text-[10px] bg-muted/30" />
                            <Button
                              variant="ghost"
                              size="sm"
                              onClick={() => {
                                const updated = [...(config.toolbarActions || [])];
                                const newShowWhen = { ...updated[index].showWhen };
                                delete newShowWhen[key];
                                updated[index] = { ...updated[index], showWhen: Object.keys(newShowWhen).length > 0 ? newShowWhen : undefined };
                                updateConfig({ toolbarActions: updated });
                              }}
                              className="h-6 w-6 p-0 text-destructive"
                            >
                              <Trash2 className="h-2.5 w-2.5" />
                            </Button>
                          </div>
                        ))}
                        <div className="flex items-center gap-1">
                          <Input
                            id={`showWhen-key-${index}`}
                            placeholder="필드명"
                            className="h-6 flex-1 text-[10px]"
                          />
                          <span className="text-[10px]">=</span>
                          <Input
                            id={`showWhen-val-${index}`}
                            placeholder="값"
                            className="h-6 flex-1 text-[10px]"
                          />
                          <Button
                            variant="outline"
                            size="sm"
                            onClick={() => {
                              const keyEl = document.getElementById(`showWhen-key-${index}`) as HTMLInputElement;
                              const valEl = document.getElementById(`showWhen-val-${index}`) as HTMLInputElement;
                              if (!keyEl?.value?.trim()) return;
                              const updated = [...(config.toolbarActions || [])];
                              updated[index] = {
                                ...updated[index],
                                showWhen: { ...(updated[index].showWhen || {}), [keyEl.value.trim()]: valEl?.value?.trim() || "" },
                              };
                              updateConfig({ toolbarActions: updated });
                              keyEl.value = "";
                              if (valEl) valEl.value = "";
                            }}
                            className="h-6 w-6 p-0"
                          >
                            <Plus className="h-2.5 w-2.5" />
                          </Button>
                        </div>
                      </div>
                    </div>
                  </CollapsibleContent>
                </div>
              </Collapsible>
            ))}

            {/* 액션 추가 버튼 */}
            <Button
              variant="outline"
              size="sm"
              onClick={() => {
                const newAction: ToolbarAction = {
                  id: `action_${Date.now()}`,
                  label: "새 액션",
                  icon: "Zap",
                  color: "bg-primary hover:bg-primary/90",
                  previewApi: "",
                  applyApi: "",
                  dataSource: "linkedSelection",
                };
                updateConfig({
                  toolbarActions: [...(config.toolbarActions || []), newAction],
                });
                setExpandedActionId(newAction.id);
              }}
              className="w-full h-8 text-xs gap-1"
            >
              <Plus className="h-3 w-3" />
              액션 추가
            </Button>
          </div>
        </CollapsibleContent>
      </Collapsible>
    </div>
  );
};

V2TimelineSchedulerConfigPanel.displayName = "V2TimelineSchedulerConfigPanel";

export default V2TimelineSchedulerConfigPanel;
