"use client";

/**
 * 조건 분기 노드 속성 편집
 */

import { useEffect, useState, useCallback } from "react";
import { Plus, Trash2, Database, Search, Check, ChevronsUpDown } from "lucide-react";
import { Label } from "@/components/ui/label";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { useFlowEditorStore } from "@/lib/stores/flowEditorStore";
import type { ConditionNodeData, ConditionOperator } from "@/types/node-editor";
import { tableManagementApi } from "@/lib/api/tableManagement";
import { cn } from "@/lib/utils";

// 필드 정의
interface FieldDefinition {
  name: string;
  label?: string;
  type?: string;
}

// 테이블 정보
interface TableInfo {
  tableName: string;
  tableLabel: string;
}

// 테이블 컬럼 정보
interface ColumnInfo {
  columnName: string;
  columnLabel: string;
  dataType: string;
}

interface ConditionPropertiesProps {
  nodeId: string;
  data: ConditionNodeData;
}

const OPERATORS = [
  { value: "EQUALS", label: "같음 (=)" },
  { value: "NOT_EQUALS", label: "같지 않음 (≠)" },
  { value: "GREATER_THAN", label: "보다 큼 (>)" },
  { value: "LESS_THAN", label: "보다 작음 (<)" },
  { value: "GREATER_THAN_OR_EQUAL", label: "크거나 같음 (≥)" },
  { value: "LESS_THAN_OR_EQUAL", label: "작거나 같음 (≤)" },
  { value: "LIKE", label: "포함 (LIKE)" },
  { value: "NOT_LIKE", label: "미포함 (NOT LIKE)" },
  { value: "IN", label: "IN" },
  { value: "NOT_IN", label: "NOT IN" },
  { value: "IS_NULL", label: "NULL" },
  { value: "IS_NOT_NULL", label: "NOT NULL" },
  { value: "EXISTS_IN", label: "다른 테이블에 존재함" },
  { value: "NOT_EXISTS_IN", label: "다른 테이블에 존재하지 않음" },
] as const;

// EXISTS 계열 연산자인지 확인
const isExistsOperator = (operator: string): boolean => {
  return operator === "EXISTS_IN" || operator === "NOT_EXISTS_IN";
};

// 테이블 선택용 검색 가능한 Combobox
function TableCombobox({
  tables,
  value,
  onSelect,
  placeholder = "테이블 검색...",
}: {
  tables: TableInfo[];
  value: string;
  onSelect: (value: string) => void;
  placeholder?: string;
}) {
  const [open, setOpen] = useState(false);

  const selectedTable = tables.find((t) => t.tableName === value);

  return (
    <Popover open={open} onOpenChange={setOpen}>
      <PopoverTrigger asChild>
        <Button
          variant="outline"
          role="combobox"
          aria-expanded={open}
          className="mt-1 h-8 w-full justify-between text-xs"
        >
          {selectedTable ? (
            <span className="truncate">
              {selectedTable.tableLabel}
              <span className="ml-1 text-muted-foreground/70">({selectedTable.tableName})</span>
            </span>
          ) : (
            <span className="text-muted-foreground">테이블 선택</span>
          )}
          <ChevronsUpDown className="ml-2 h-3 w-3 shrink-0 opacity-50" />
        </Button>
      </PopoverTrigger>
      <PopoverContent className="w-[300px] p-0" align="start">
        <Command>
          <CommandInput placeholder={placeholder} className="h-8 text-xs" />
          <CommandList>
            <CommandEmpty className="py-2 text-center text-xs">테이블을 찾을 수 없습니다.</CommandEmpty>
            <CommandGroup className="max-h-[200px] overflow-y-auto">
              {tables.map((table) => (
                <CommandItem
                  key={table.tableName}
                  value={`${table.tableLabel} ${table.tableName}`}
                  onSelect={() => {
                    onSelect(table.tableName);
                    setOpen(false);
                  }}
                  className="text-xs"
                >
                  <Check className={cn("mr-2 h-3 w-3", value === table.tableName ? "opacity-100" : "opacity-0")} />
                  <div className="flex flex-col">
                    <span className="font-medium">{table.tableLabel}</span>
                    <span className="text-[10px] text-muted-foreground">{table.tableName}</span>
                  </div>
                </CommandItem>
              ))}
            </CommandGroup>
          </CommandList>
        </Command>
      </PopoverContent>
    </Popover>
  );
}

// 컬럼 선택용 검색 가능한 Combobox
function ColumnCombobox({
  columns,
  value,
  onSelect,
  placeholder = "컬럼 검색...",
}: {
  columns: ColumnInfo[];
  value: string;
  onSelect: (value: string) => void;
  placeholder?: string;
}) {
  const [open, setOpen] = useState(false);

  const selectedColumn = columns.find((c) => c.columnName === value);

  return (
    <Popover open={open} onOpenChange={setOpen}>
      <PopoverTrigger asChild>
        <Button
          variant="outline"
          role="combobox"
          aria-expanded={open}
          className="mt-1 h-8 w-full justify-between text-xs"
        >
          {selectedColumn ? (
            <span className="truncate">
              {selectedColumn.columnLabel}
              <span className="ml-1 text-muted-foreground/70">({selectedColumn.columnName})</span>
            </span>
          ) : (
            <span className="text-muted-foreground">컬럼 선택</span>
          )}
          <ChevronsUpDown className="ml-2 h-3 w-3 shrink-0 opacity-50" />
        </Button>
      </PopoverTrigger>
      <PopoverContent className="w-[300px] p-0" align="start">
        <Command>
          <CommandInput placeholder={placeholder} className="h-8 text-xs" />
          <CommandList>
            <CommandEmpty className="py-2 text-center text-xs">컬럼을 찾을 수 없습니다.</CommandEmpty>
            <CommandGroup className="max-h-[200px] overflow-y-auto">
              {columns.map((col) => (
                <CommandItem
                  key={col.columnName}
                  value={`${col.columnLabel} ${col.columnName}`}
                  onSelect={() => {
                    onSelect(col.columnName);
                    setOpen(false);
                  }}
                  className="text-xs"
                >
                  <Check className={cn("mr-2 h-3 w-3", value === col.columnName ? "opacity-100" : "opacity-0")} />
                  <span className="font-medium">{col.columnLabel}</span>
                  <span className="ml-1 text-[10px] text-muted-foreground/70">({col.columnName})</span>
                </CommandItem>
              ))}
            </CommandGroup>
          </CommandList>
        </Command>
      </PopoverContent>
    </Popover>
  );
}

// 컬럼 선택 섹션 (자동 로드 포함)
function ColumnSelectSection({
  lookupTable,
  lookupField,
  tableColumnsCache,
  loadingColumns,
  loadTableColumns,
  onSelect,
}: {
  lookupTable: string;
  lookupField: string;
  tableColumnsCache: Record<string, ColumnInfo[]>;
  loadingColumns: Record<string, boolean>;
  loadTableColumns: (tableName: string) => Promise<ColumnInfo[]>;
  onSelect: (value: string) => void;
}) {
  // 캐시에 없고 로딩 중이 아니면 자동으로 로드
  useEffect(() => {
    if (lookupTable && !tableColumnsCache[lookupTable] && !loadingColumns[lookupTable]) {
      loadTableColumns(lookupTable);
    }
  }, [lookupTable, tableColumnsCache, loadingColumns, loadTableColumns]);

  const isLoading = loadingColumns[lookupTable];
  const columns = tableColumnsCache[lookupTable];

  return (
    <div>
      <Label className="text-xs text-muted-foreground">
        <Search className="mr-1 inline h-3 w-3" />
        비교할 컬럼
      </Label>
      {isLoading ? (
        <div className="mt-1 rounded border border-dashed bg-muted p-2 text-center text-xs text-muted-foreground/70">
          컬럼 목록 로딩 중...
        </div>
      ) : columns && columns.length > 0 ? (
        <ColumnCombobox columns={columns} value={lookupField} onSelect={onSelect} placeholder="컬럼 검색..." />
      ) : (
        <div className="mt-1 rounded border border-dashed bg-muted p-2 text-center text-xs text-muted-foreground/70">
          컬럼 목록을 로드할 수 없습니다
        </div>
      )}
    </div>
  );
}

export function ConditionProperties({ nodeId, data }: ConditionPropertiesProps) {
  const { updateNode, nodes, edges } = useFlowEditorStore();

  const [displayName, setDisplayName] = useState(data.displayName || "조건 분기");
  const [conditions, setConditions] = useState(data.conditions || []);
  const [logic, setLogic] = useState<"AND" | "OR">(data.logic || "AND");
  const [availableFields, setAvailableFields] = useState<FieldDefinition[]>([]);

  // 타겟 조회 설정 (DB 기존값 비교용)
  const [targetLookup, setTargetLookup] = useState<{
    tableName: string;
    tableLabel?: string;
    lookupKeys: Array<{ sourceField: string; targetField: string; sourceFieldLabel?: string }>;
  } | undefined>(data.targetLookup);
  const [targetLookupColumns, setTargetLookupColumns] = useState<ColumnInfo[]>([]);

  // EXISTS 연산자용 상태
  const [allTables, setAllTables] = useState<TableInfo[]>([]);
  const [tableColumnsCache, setTableColumnsCache] = useState<Record<string, ColumnInfo[]>>({});
  const [loadingTables, setLoadingTables] = useState(false);
  const [loadingColumns, setLoadingColumns] = useState<Record<string, boolean>>({});

  // 데이터 변경 시 로컬 상태 업데이트
  useEffect(() => {
    setDisplayName(data.displayName || "조건 분기");
    setConditions(data.conditions || []);
    setLogic(data.logic || "AND");
    setTargetLookup(data.targetLookup);
  }, [data]);

  // targetLookup 테이블 변경 시 컬럼 목록 로드
  useEffect(() => {
    if (targetLookup?.tableName) {
      loadTableColumns(targetLookup.tableName).then((cols) => {
        setTargetLookupColumns(cols);
      });
    } else {
      setTargetLookupColumns([]);
    }
  }, [targetLookup?.tableName]);

  // 전체 테이블 목록 로드 (EXISTS 연산자용)
  useEffect(() => {
    const loadAllTables = async () => {
      // 이미 EXISTS 연산자가 있거나 로드된 적이 있으면 스킵
      if (allTables.length > 0) return;

      // EXISTS 연산자가 하나라도 있으면 테이블 목록 로드
      const hasExistsOperator = conditions.some((c) => isExistsOperator(c.operator));
      if (!hasExistsOperator) return;

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

    loadAllTables();
  }, [conditions, allTables.length]);

  // 테이블 컬럼 로드 함수
  const loadTableColumns = useCallback(
    async (tableName: string): Promise<ColumnInfo[]> => {
      // 캐시에 있으면 반환
      if (tableColumnsCache[tableName]) {
        return tableColumnsCache[tableName];
      }

      // 이미 로딩 중이면 스킵
      if (loadingColumns[tableName]) {
        return [];
      }

      // 로딩 상태 설정
      setLoadingColumns((prev) => ({ ...prev, [tableName]: true }));

      try {
        // getColumnList 반환: { success, data: { columns, total, ... } }
        const response = await tableManagementApi.getColumnList(tableName);
        if (response.success && response.data && response.data.columns) {
          const columns = response.data.columns.map((c: any) => ({
            columnName: c.columnName,
            columnLabel: c.columnLabel || c.columnName,
            dataType: c.dataType,
          }));
          setTableColumnsCache((prev) => ({ ...prev, [tableName]: columns }));
          console.log(`✅ 테이블 ${tableName} 컬럼 로드 완료:`, columns.length, "개");
          return columns;
        } else {
          console.warn(`⚠️ 테이블 ${tableName} 컬럼 조회 실패:`, response);
        }
      } catch (error) {
        console.error(`❌ 테이블 ${tableName} 컬럼 로드 실패:`, error);
      } finally {
        setLoadingColumns((prev) => ({ ...prev, [tableName]: false }));
      }
      return [];
    },
    [tableColumnsCache, loadingColumns]
  );

  // EXISTS 연산자 선택 시 테이블 목록 강제 로드
  const ensureTablesLoaded = useCallback(async () => {
    if (allTables.length > 0) return;

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

  // 🔥 연결된 소스 노드의 필드를 재귀적으로 수집
  useEffect(() => {
    const getAllSourceFields = (currentNodeId: string, visited: Set<string> = new Set()): FieldDefinition[] => {
      if (visited.has(currentNodeId)) return [];
      visited.add(currentNodeId);

      const fields: FieldDefinition[] = [];

      // 현재 노드로 들어오는 엣지 찾기
      const incomingEdges = edges.filter((e) => e.target === currentNodeId);

      for (const edge of incomingEdges) {
        const sourceNode = nodes.find((n) => n.id === edge.source);
        if (!sourceNode) continue;

        const sourceData = sourceNode.data as any;

        // 소스 노드 타입별 필드 수집
        if (sourceNode.type === "tableSource") {
          // Table Source: fields 사용
          if (sourceData.fields && Array.isArray(sourceData.fields)) {
            console.log("🔍 [ConditionProperties] Table Source 필드:", sourceData.fields);
            fields.push(...sourceData.fields);
          } else {
            console.log("⚠️ [ConditionProperties] Table Source에 필드 없음:", sourceData);
          }
        } else if (sourceNode.type === "externalDBSource") {
          // External DB Source: outputFields 사용
          if (sourceData.outputFields && Array.isArray(sourceData.outputFields)) {
            console.log("🔍 [ConditionProperties] External DB 필드:", sourceData.outputFields);
            fields.push(...sourceData.outputFields);
          } else {
            console.log("⚠️ [ConditionProperties] External DB에 필드 없음:", sourceData);
          }
        } else if (sourceNode.type === "dataTransform") {
          // Data Transform: 재귀적으로 상위 노드 필드 수집
          const upperFields = getAllSourceFields(sourceNode.id, visited);

          // Data Transform의 변환 결과 추가
          if (sourceData.transformations && Array.isArray(sourceData.transformations)) {
            const inPlaceFields = new Set<string>();

            for (const transform of sourceData.transformations) {
              const { sourceField, targetField } = transform;

              // In-place 변환인지 확인
              if (!targetField || targetField === sourceField) {
                inPlaceFields.add(sourceField);
              } else {
                // 새로운 필드 생성
                fields.push({ name: targetField, label: targetField });
              }
            }

            // 원본 필드 중 in-place 변환되지 않은 것들 추가
            for (const field of upperFields) {
              if (!inPlaceFields.has(field.name)) {
                fields.push(field);
              } else {
                // In-place 변환된 필드는 원본 이름으로 유지
                fields.push(field);
              }
            }
          } else {
            fields.push(...upperFields);
          }
        } else if (sourceNode.type === "restAPISource") {
          // REST API Source: responseFields 사용
          if (sourceData.responseFields && Array.isArray(sourceData.responseFields)) {
            console.log("🔍 [ConditionProperties] REST API 필드:", sourceData.responseFields);
            fields.push(
              ...sourceData.responseFields.map((f: any) => ({
                name: f.name || f.fieldName,
                label: f.label || f.displayName || f.name,
                type: f.dataType || f.type,
              })),
            );
          } else {
            console.log("⚠️ [ConditionProperties] REST API에 필드 없음:", sourceData);
          }
        } else if (sourceNode.type === "condition") {
          // 조건 노드: 재귀적으로 상위 노드 필드 수집 (통과 노드)
          console.log("✅ [ConditionProperties] 조건 노드 통과 → 상위 탐색");
          fields.push(...getAllSourceFields(sourceNode.id, visited));
        } else if (
          sourceNode.type === "insertAction" ||
          sourceNode.type === "updateAction" ||
          sourceNode.type === "deleteAction" ||
          sourceNode.type === "upsertAction"
        ) {
          // Action 노드: 재귀적으로 상위 노드 필드 수집
          fields.push(...getAllSourceFields(sourceNode.id, visited));
        } else {
          // 기타 모든 노드: 재귀적으로 상위 노드 필드 수집 (통과 노드로 처리)
          console.log(`✅ [ConditionProperties] 통과 노드 (${sourceNode.type}) → 상위 탐색`);
          fields.push(...getAllSourceFields(sourceNode.id, visited));
        }
      }

      // 중복 제거
      const uniqueFields = Array.from(new Map(fields.map((f) => [f.name, f])).values());
      return uniqueFields;
    };

    const fields = getAllSourceFields(nodeId);
    console.log("✅ [ConditionProperties] 최종 수집된 필드:", fields);
    console.log("🔍 [ConditionProperties] 현재 노드 ID:", nodeId);
    console.log(
      "🔍 [ConditionProperties] 연결된 엣지:",
      edges.filter((e) => e.target === nodeId),
    );
    setAvailableFields(fields);
  }, [nodeId, nodes, edges]);

  const handleAddCondition = () => {
    const newCondition = {
      field: "",
      operator: "EQUALS" as ConditionOperator,
      value: "",
      valueType: "static" as "static" | "field",
      // EXISTS 연산자용 필드는 초기값 없음
      lookupTable: undefined,
      lookupTableLabel: undefined,
      lookupField: undefined,
      lookupFieldLabel: undefined,
    };
    setConditions([...conditions, newCondition]);
  };

  const handleRemoveCondition = (index: number) => {
    const newConditions = conditions.filter((_, i) => i !== index);
    setConditions(newConditions);
    updateNode(nodeId, {
      conditions: newConditions,
    });
  };

  const handleDisplayNameChange = (newDisplayName: string) => {
    setDisplayName(newDisplayName);
    updateNode(nodeId, {
      displayName: newDisplayName,
    });
  };

  const handleConditionChange = async (index: number, field: string, value: any) => {
    const newConditions = [...conditions];
    newConditions[index] = { ...newConditions[index], [field]: value };

    // EXISTS 연산자로 변경 시 테이블 목록 로드 및 기존 value/valueType 초기화
    if (field === "operator" && isExistsOperator(value)) {
      await ensureTablesLoaded();
      // EXISTS 연산자에서는 value, valueType이 필요 없으므로 초기화
      newConditions[index].value = "";
      newConditions[index].valueType = undefined;
    }

    // EXISTS 연산자에서 다른 연산자로 변경 시 lookup 필드들 초기화
    if (field === "operator" && !isExistsOperator(value)) {
      newConditions[index].lookupTable = undefined;
      newConditions[index].lookupTableLabel = undefined;
      newConditions[index].lookupField = undefined;
      newConditions[index].lookupFieldLabel = undefined;
    }

    // lookupTable 변경 시 컬럼 목록 로드 및 라벨 설정
    if (field === "lookupTable" && value) {
      const tableInfo = allTables.find((t) => t.tableName === value);
      if (tableInfo) {
        newConditions[index].lookupTableLabel = tableInfo.tableLabel;
      }
      // 테이블 변경 시 필드 초기화
      newConditions[index].lookupField = undefined;
      newConditions[index].lookupFieldLabel = undefined;
      // 컬럼 목록 미리 로드
      await loadTableColumns(value);
    }

    // lookupField 변경 시 라벨 설정
    if (field === "lookupField" && value) {
      const tableName = newConditions[index].lookupTable;
      if (tableName && tableColumnsCache[tableName]) {
        const columnInfo = tableColumnsCache[tableName].find((c) => c.columnName === value);
        if (columnInfo) {
          newConditions[index].lookupFieldLabel = columnInfo.columnLabel;
        }
      }
    }

    setConditions(newConditions);
    updateNode(nodeId, {
      conditions: newConditions,
    });
  };

  const handleLogicChange = (newLogic: "AND" | "OR") => {
    setLogic(newLogic);
    updateNode(nodeId, {
      logic: newLogic,
    });
  };

  // 타겟 조회 테이블 변경
  const handleTargetLookupTableChange = async (tableName: string) => {
    await ensureTablesLoaded();
    const tableInfo = allTables.find((t) => t.tableName === tableName);
    const newLookup = {
      tableName,
      tableLabel: tableInfo?.tableLabel || tableName,
      lookupKeys: targetLookup?.lookupKeys || [],
    };
    setTargetLookup(newLookup);
    updateNode(nodeId, { targetLookup: newLookup });

    // 컬럼 로드
    const cols = await loadTableColumns(tableName);
    setTargetLookupColumns(cols);
  };

  // 타겟 조회 키 필드 변경
  const handleTargetLookupKeyChange = (sourceField: string, targetField: string) => {
    if (!targetLookup) return;
    const sourceFieldInfo = availableFields.find((f) => f.name === sourceField);
    const newLookup = {
      ...targetLookup,
      lookupKeys: [{ sourceField, targetField, sourceFieldLabel: sourceFieldInfo?.label || sourceField }],
    };
    setTargetLookup(newLookup);
    updateNode(nodeId, { targetLookup: newLookup });
  };

  // 타겟 조회 제거
  const handleRemoveTargetLookup = () => {
    setTargetLookup(undefined);
    updateNode(nodeId, { targetLookup: undefined });
    // target 타입 조건들을 field로 변경
    const newConditions = conditions.map((c) =>
      (c as any).valueType === "target" ? { ...c, valueType: "field" } : c
    );
    setConditions(newConditions);
    updateNode(nodeId, { conditions: newConditions });
  };

  return (
    <div>
      <div className="space-y-4 p-4 pb-8">
        {/* 기본 정보 */}
        <div>
          <h3 className="mb-3 text-sm font-semibold">기본 정보</h3>

          <div className="space-y-3">
            <div>
              <Label htmlFor="displayName" className="text-xs">
                표시 이름
              </Label>
              <Input
                id="displayName"
                value={displayName}
                onChange={(e) => handleDisplayNameChange(e.target.value)}
                className="mt-1"
                placeholder="노드 표시 이름"
              />
            </div>

            <div>
              <Label htmlFor="logic" className="text-xs">
                조건 로직
              </Label>
              <Select value={logic} onValueChange={handleLogicChange}>
                <SelectTrigger className="mt-1">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="AND">AND (모두 충족)</SelectItem>
                  <SelectItem value="OR">OR (하나라도 충족)</SelectItem>
                </SelectContent>
              </Select>
            </div>
          </div>
        </div>

        {/* 타겟 조회 (DB 기존값 비교) */}
        <div>
          <div className="mb-2 flex items-center justify-between">
            <h3 className="text-sm font-semibold">
              <Database className="mr-1 inline h-3.5 w-3.5" />
              타겟 조회 (DB 기존값)
            </h3>
          </div>

          {!targetLookup ? (
            <div className="space-y-2">
              <div className="rounded border border-dashed p-3 text-center text-xs text-muted-foreground/70">
                DB의 기존값과 비교하려면 타겟 테이블을 설정하세요.
              </div>
              <Button
                size="sm"
                variant="outline"
                className="h-7 w-full text-xs"
                onClick={async () => {
                  await ensureTablesLoaded();
                  setTargetLookup({ tableName: "", lookupKeys: [] });
                }}
              >
                <Database className="mr-1 h-3 w-3" />
                타겟 조회 설정
              </Button>
            </div>
          ) : (
            <div className="space-y-2 rounded border bg-amber-50 p-3">
              <div className="flex items-center justify-between">
                <span className="text-xs font-medium text-orange-700">타겟 테이블</span>
                <Button
                  size="sm"
                  variant="ghost"
                  onClick={handleRemoveTargetLookup}
                  className="h-5 px-1 text-xs text-amber-500 hover:text-orange-700"
                >
                  제거
                </Button>
              </div>

              {/* 테이블 선택 */}
              {allTables.length > 0 ? (
                <TableCombobox
                  tables={allTables}
                  value={targetLookup.tableName}
                  onSelect={handleTargetLookupTableChange}
                  placeholder="비교할 테이블 검색..."
                />
              ) : (
                <div className="rounded border border-dashed bg-muted p-2 text-center text-xs text-muted-foreground/70">
                  테이블 로딩 중...
                </div>
              )}

              {/* 키 필드 매핑 */}
              {targetLookup.tableName && (
                <div className="space-y-1.5">
                  <Label className="text-xs text-amber-600">조회 키 (소스 → 타겟)</Label>
                  <div className="flex items-center gap-1.5">
                    <Select
                      value={targetLookup.lookupKeys?.[0]?.sourceField || ""}
                      onValueChange={(val) => {
                        const targetField = targetLookup.lookupKeys?.[0]?.targetField || "";
                        handleTargetLookupKeyChange(val, targetField);
                      }}
                    >
                      <SelectTrigger className="h-7 flex-1 text-xs">
                        <SelectValue placeholder="소스 필드" />
                      </SelectTrigger>
                      <SelectContent>
                        {availableFields.map((f) => (
                          <SelectItem key={f.name} value={f.name} className="text-xs">
                            {f.label || f.name}
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                    <span className="text-xs text-muted-foreground/70">=</span>
                    {targetLookupColumns.length > 0 ? (
                      <Select
                        value={targetLookup.lookupKeys?.[0]?.targetField || ""}
                        onValueChange={(val) => {
                          const sourceField = targetLookup.lookupKeys?.[0]?.sourceField || "";
                          handleTargetLookupKeyChange(sourceField, val);
                        }}
                      >
                        <SelectTrigger className="h-7 flex-1 text-xs">
                          <SelectValue placeholder="타겟 필드" />
                        </SelectTrigger>
                        <SelectContent>
                          {targetLookupColumns.map((c) => (
                            <SelectItem key={c.columnName} value={c.columnName} className="text-xs">
                              {c.columnLabel || c.columnName}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    ) : (
                      <div className="flex-1 rounded border border-dashed bg-muted p-1 text-center text-[10px] text-muted-foreground/70">
                        컬럼 로딩 중...
                      </div>
                    )}
                  </div>
                  <div className="rounded bg-amber-100 p-1.5 text-[10px] text-amber-600">
                    비교 값 타입에서 "타겟 필드 (DB 기존값)"을 선택하면 이 테이블의 기존값과 비교합니다.
                  </div>
                </div>
              )}
            </div>
          )}
        </div>

        {/* 조건식 */}
        <div>
          <div className="mb-2 flex items-center justify-between">
            <h3 className="text-sm font-semibold">조건식</h3>
            <Button size="sm" variant="outline" onClick={handleAddCondition} className="h-7">
              <Plus className="mr-1 h-3 w-3" />
              추가
            </Button>
          </div>

          {conditions.length > 0 ? (
            <div className="space-y-2">
              {conditions.map((condition, index) => (
                <div key={index} className="rounded border bg-amber-50 p-3">
                  <div className="mb-2 flex items-center justify-between">
                    <div className="flex items-center gap-2">
                      <span className="text-xs font-medium text-yellow-700">조건 #{index + 1}</span>
                      {index > 0 && (
                        <span className="rounded bg-yellow-200 px-1.5 py-0.5 text-xs font-semibold text-yellow-800">
                          {logic}
                        </span>
                      )}
                    </div>
                    <Button
                      size="sm"
                      variant="ghost"
                      onClick={() => handleRemoveCondition(index)}
                      className="h-6 w-6 p-0"
                    >
                      <Trash2 className="h-3 w-3" />
                    </Button>
                  </div>

                  <div className="space-y-2">
                    <div>
                      <Label className="text-xs text-muted-foreground">필드명</Label>
                      {availableFields.length > 0 ? (
                        <Select
                          value={condition.field}
                          onValueChange={(value) => handleConditionChange(index, "field", value)}
                        >
                          <SelectTrigger className="mt-1 h-8 text-xs">
                            <SelectValue placeholder="필드 선택" />
                          </SelectTrigger>
                          <SelectContent>
                            {availableFields.map((field) => (
                              <SelectItem key={field.name} value={field.name}>
                                {field.label || field.name}
                                {field.type && <span className="ml-2 text-xs text-muted-foreground/70">({field.type})</span>}
                              </SelectItem>
                            ))}
                          </SelectContent>
                        </Select>
                      ) : (
                        <div className="mt-1 rounded border border-dashed bg-muted p-2 text-center text-xs text-muted-foreground/70">
                          소스 노드를 연결하세요
                        </div>
                      )}
                    </div>

                    <div>
                      <Label className="text-xs text-muted-foreground">연산자</Label>
                      <Select
                        value={condition.operator}
                        onValueChange={(value) => handleConditionChange(index, "operator", value)}
                      >
                        <SelectTrigger className="mt-1 h-8 text-xs">
                          <SelectValue />
                        </SelectTrigger>
                        <SelectContent>
                          {OPERATORS.map((op) => (
                            <SelectItem key={op.value} value={op.value}>
                              {op.label}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    </div>

                    {/* EXISTS 연산자인 경우: 테이블/필드 선택 UI (검색 가능한 Combobox) */}
                    {isExistsOperator(condition.operator) && (
                      <>
                        <div>
                          <Label className="text-xs text-muted-foreground">
                            <Database className="mr-1 inline h-3 w-3" />
                            조회할 테이블
                          </Label>
                          {loadingTables ? (
                            <div className="mt-1 rounded border border-dashed bg-muted p-2 text-center text-xs text-muted-foreground/70">
                              테이블 목록 로딩 중...
                            </div>
                          ) : allTables.length > 0 ? (
                            <TableCombobox
                              tables={allTables}
                              value={(condition as any).lookupTable || ""}
                              onSelect={(value) => handleConditionChange(index, "lookupTable", value)}
                              placeholder="테이블 검색..."
                            />
                          ) : (
                            <div className="mt-1 rounded border border-dashed bg-muted p-2 text-center text-xs text-muted-foreground/70">
                              테이블 목록을 로드할 수 없습니다
                            </div>
                          )}
                        </div>

                        {(condition as any).lookupTable && (
                          <ColumnSelectSection
                            lookupTable={(condition as any).lookupTable}
                            lookupField={(condition as any).lookupField || ""}
                            tableColumnsCache={tableColumnsCache}
                            loadingColumns={loadingColumns}
                            loadTableColumns={loadTableColumns}
                            onSelect={(value) => handleConditionChange(index, "lookupField", value)}
                          />
                        )}

                        <div className="rounded bg-purple-50 p-2 text-xs text-purple-700">
                          {condition.operator === "EXISTS_IN"
                            ? `소스의 "${condition.field || "..."}" 값이 "${(condition as any).lookupTableLabel || "..."}" 테이블의 "${(condition as any).lookupFieldLabel || "..."}" 컬럼에 존재하면 TRUE`
                            : `소스의 "${condition.field || "..."}" 값이 "${(condition as any).lookupTableLabel || "..."}" 테이블의 "${(condition as any).lookupFieldLabel || "..."}" 컬럼에 존재하지 않으면 TRUE`}
                        </div>
                      </>
                    )}

                    {/* 일반 연산자인 경우: 기존 비교값 UI */}
                    {condition.operator !== "IS_NULL" &&
                      condition.operator !== "IS_NOT_NULL" &&
                      !isExistsOperator(condition.operator) && (
                        <>
                          <div>
                            <Label className="text-xs text-muted-foreground">비교 값 타입</Label>
                            <Select
                              value={(condition as any).valueType || "static"}
                              onValueChange={(value) => handleConditionChange(index, "valueType", value)}
                            >
                              <SelectTrigger className="mt-1 h-8 text-xs">
                                <SelectValue />
                              </SelectTrigger>
                              <SelectContent>
                                <SelectItem value="static">고정값</SelectItem>
                                <SelectItem value="field">필드 참조</SelectItem>
                                {targetLookup?.tableName && (
                                  <SelectItem value="target">타겟 필드 (DB 기존값)</SelectItem>
                                )}
                              </SelectContent>
                            </Select>
                          </div>

                          <div>
                            <Label className="text-xs text-muted-foreground">
                              {(condition as any).valueType === "target"
                                ? "타겟 필드 (DB 기존값)"
                                : (condition as any).valueType === "field"
                                  ? "비교 필드"
                                  : "비교 값"}
                            </Label>
                            {(condition as any).valueType === "target" ? (
                              // 타겟 필드 (DB 기존값): 타겟 테이블 컬럼에서 선택
                              targetLookupColumns.length > 0 ? (
                                <Select
                                  value={condition.value as string}
                                  onValueChange={(value) => handleConditionChange(index, "value", value)}
                                >
                                  <SelectTrigger className="mt-1 h-8 text-xs">
                                    <SelectValue placeholder="DB 필드 선택" />
                                  </SelectTrigger>
                                  <SelectContent>
                                    {targetLookupColumns.map((col) => (
                                      <SelectItem key={col.columnName} value={col.columnName}>
                                        {col.columnLabel || col.columnName}
                                        <span className="ml-2 text-xs text-muted-foreground/70">({col.dataType})</span>
                                      </SelectItem>
                                    ))}
                                  </SelectContent>
                                </Select>
                              ) : (
                                <div className="mt-1 rounded border border-dashed bg-muted p-2 text-center text-xs text-muted-foreground/70">
                                  타겟 조회를 먼저 설정하세요
                                </div>
                              )
                            ) : (condition as any).valueType === "field" ? (
                              // 필드 참조: 드롭다운으로 선택
                              availableFields.length > 0 ? (
                                <Select
                                  value={condition.value as string}
                                  onValueChange={(value) => handleConditionChange(index, "value", value)}
                                >
                                  <SelectTrigger className="mt-1 h-8 text-xs">
                                    <SelectValue placeholder="비교할 필드 선택" />
                                  </SelectTrigger>
                                  <SelectContent>
                                    {availableFields.map((field) => (
                                      <SelectItem key={field.name} value={field.name}>
                                        {field.label || field.name}
                                        {field.type && (
                                          <span className="ml-2 text-xs text-muted-foreground/70">({field.type})</span>
                                        )}
                                      </SelectItem>
                                    ))}
                                  </SelectContent>
                                </Select>
                              ) : (
                                <div className="mt-1 rounded border border-dashed bg-muted p-2 text-center text-xs text-muted-foreground/70">
                                  소스 노드를 연결하세요
                                </div>
                              )
                            ) : (
                              // 고정값: 직접 입력
                              <Input
                                value={condition.value as string}
                                onChange={(e) => handleConditionChange(index, "value", e.target.value)}
                                placeholder="비교할 값"
                                className="mt-1 h-8 text-xs"
                              />
                            )}
                          </div>
                        </>
                      )}
                  </div>
                </div>
              ))}
            </div>
          ) : (
            <div className="rounded border border-dashed p-4 text-center text-xs text-muted-foreground/70">
              조건식이 없습니다. "추가" 버튼을 클릭하세요.
            </div>
          )}
        </div>


        {/* 안내 */}
        <div className="space-y-2">
          <div className="rounded bg-primary/10 p-3 text-xs text-primary">
            <strong>소스 노드 연결</strong>: 테이블/외부DB 노드를 연결하면 자동으로 필드 목록이 표시됩니다.
          </div>
          <div className="rounded bg-emerald-50 p-3 text-xs text-emerald-700">
            <strong>비교 값 타입</strong>:<br />
            - <strong>고정값</strong>: 직접 입력한 값과 비교 (예: age &gt; 30)
            <br />- <strong>필드 참조</strong>: 다른 필드의 값과 비교 (예: 주문수량 &gt; 재고수량)
          </div>
          <div className="rounded bg-purple-50 p-3 text-xs text-purple-700">
            <strong>테이블 존재 여부 검사</strong>:<br />
            - <strong>다른 테이블에 존재함</strong>: 값이 다른 테이블에 있으면 TRUE
            <br />- <strong>다른 테이블에 존재하지 않음</strong>: 값이 다른 테이블에 없으면 TRUE
            <br />
            (예: 품명이 품목정보 테이블에 없으면 자동 등록)
          </div>
          <div className="rounded bg-amber-50 p-3 text-xs text-yellow-700">
            <strong>AND</strong>: 모든 조건이 참이어야 TRUE 출력
          </div>
          <div className="rounded bg-amber-50 p-3 text-xs text-yellow-700">
            <strong>OR</strong>: 하나라도 참이면 TRUE 출력
          </div>
          <div className="rounded bg-amber-50 p-3 text-xs text-yellow-700">
            TRUE 출력은 오른쪽 위, FALSE 출력은 오른쪽 아래입니다.
          </div>
        </div>
      </div>
    </div>
  );
}
