"use client";

/**
 * 참조 테이블 조회 노드 속성 편집
 */

import { useEffect, useState, useCallback } from "react";
import { Plus, Trash2, 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 { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command";
import { cn } from "@/lib/utils";
import { useFlowEditorStore } from "@/lib/stores/flowEditorStore";
import type { ReferenceLookupNodeData } from "@/types/node-editor";
import { tableTypeApi } from "@/lib/api/screen";

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

interface ReferenceLookupPropertiesProps {
  nodeId: string;
  data: ReferenceLookupNodeData;
}

const OPERATORS = [
  { value: "=", label: "같음 (=)" },
  { value: "!=", label: "같지 않음 (≠)" },
  { value: ">", label: "보다 큼 (>)" },
  { value: "<", label: "보다 작음 (<)" },
  { value: ">=", label: "크거나 같음 (≥)" },
  { value: "<=", label: "작거나 같음 (≤)" },
  { value: "LIKE", label: "포함 (LIKE)" },
  { value: "IN", label: "IN" },
] as const;

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

  // 상태
  const [displayName, setDisplayName] = useState(data.displayName || "참조 조회");
  const [referenceTable, setReferenceTable] = useState(data.referenceTable || "");
  const [referenceTableLabel, setReferenceTableLabel] = useState(data.referenceTableLabel || "");
  const [joinConditions, setJoinConditions] = useState(data.joinConditions || []);
  const [whereConditions, setWhereConditions] = useState(data.whereConditions || []);
  const [outputFields, setOutputFields] = useState(data.outputFields || []);

  // 소스 필드 수집
  const [sourceFields, setSourceFields] = useState<FieldDefinition[]>([]);

  // 참조 테이블 관련
  const [tables, setTables] = useState<any[]>([]);
  const [tablesLoading, setTablesLoading] = useState(false);
  const [tablesOpen, setTablesOpen] = useState(false);
  const [referenceColumns, setReferenceColumns] = useState<FieldDefinition[]>([]);
  const [columnsLoading, setColumnsLoading] = useState(false);

  // Combobox 열림 상태 관리
  const [whereFieldOpenState, setWhereFieldOpenState] = useState<boolean[]>([]);

  // 데이터 변경 시 로컬 상태 동기화
  useEffect(() => {
    setDisplayName(data.displayName || "참조 조회");
    setReferenceTable(data.referenceTable || "");
    setReferenceTableLabel(data.referenceTableLabel || "");
    setJoinConditions(data.joinConditions || []);
    setWhereConditions(data.whereConditions || []);
    setOutputFields(data.outputFields || []);
  }, [data]);

  // whereConditions 변경 시 whereFieldOpenState 초기화
  useEffect(() => {
    setWhereFieldOpenState(new Array(whereConditions.length).fill(false));
  }, [whereConditions.length]);

  // 🔍 소스 필드 수집 (업스트림 노드에서)
  useEffect(() => {
    const incomingEdges = edges.filter((e) => e.target === nodeId);
    const fields: FieldDefinition[] = [];

    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" && sourceData.fields) {
        fields.push(...sourceData.fields);
      } else if (sourceNode.type === "externalDBSource" && sourceData.outputFields) {
        fields.push(...sourceData.outputFields);
      }
    }

    setSourceFields(fields);
  }, [nodeId, nodes, edges]);

  // 📊 테이블 목록 로드
  useEffect(() => {
    loadTables();
  }, []);

  const loadTables = async () => {
    setTablesLoading(true);
    try {
      const data = await tableTypeApi.getTables();
      setTables(data);
    } catch (error) {
      console.error("테이블 로드 실패:", error);
    } finally {
      setTablesLoading(false);
    }
  };

  // 📋 참조 테이블 컬럼 로드
  useEffect(() => {
    if (referenceTable) {
      loadReferenceColumns();
    } else {
      setReferenceColumns([]);
    }
  }, [referenceTable]);

  const loadReferenceColumns = async () => {
    if (!referenceTable) return;

    setColumnsLoading(true);
    try {
      const cols = await tableTypeApi.getColumns(referenceTable);
      const formatted = cols.map((col: any) => ({
        name: col.columnName,
        type: col.dataType,
        label: col.displayName || col.columnName,
      }));
      setReferenceColumns(formatted);
    } catch (error) {
      console.error("컬럼 로드 실패:", error);
      setReferenceColumns([]);
    } finally {
      setColumnsLoading(false);
    }
  };

  // 테이블 선택 핸들러
  const handleTableSelect = (tableName: string) => {
    const selectedTable = tables.find((t) => t.tableName === tableName);
    if (selectedTable) {
      setReferenceTable(tableName);
      setReferenceTableLabel(selectedTable.label);
      setTablesOpen(false);

      // 기존 설정 초기화
      setJoinConditions([]);
      setWhereConditions([]);
      setOutputFields([]);
    }
  };

  // 조인 조건 추가
  const handleAddJoinCondition = () => {
    setJoinConditions([
      ...joinConditions,
      {
        sourceField: "",
        referenceField: "",
      },
    ]);
  };

  const handleRemoveJoinCondition = (index: number) => {
    setJoinConditions(joinConditions.filter((_, i) => i !== index));
  };

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

    // 라벨도 함께 저장
    if (field === "sourceField") {
      const sourceField = sourceFields.find((f) => f.name === value);
      newConditions[index].sourceFieldLabel = sourceField?.label || value;
    } else if (field === "referenceField") {
      const refField = referenceColumns.find((f) => f.name === value);
      newConditions[index].referenceFieldLabel = refField?.label || value;
    }

    setJoinConditions(newConditions);
  };

  // WHERE 조건 추가
  const handleAddWhereCondition = () => {
    const newConditions = [
      ...whereConditions,
      {
        field: "",
        operator: "=",
        value: "",
        valueType: "static",
      },
    ];
    setWhereConditions(newConditions);
    setWhereFieldOpenState(new Array(newConditions.length).fill(false));
  };

  const handleRemoveWhereCondition = (index: number) => {
    const newConditions = whereConditions.filter((_, i) => i !== index);
    setWhereConditions(newConditions);
    setWhereFieldOpenState(new Array(newConditions.length).fill(false));
  };

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

    // 라벨도 함께 저장
    if (field === "field") {
      const refField = referenceColumns.find((f) => f.name === value);
      newConditions[index].fieldLabel = refField?.label || value;
    }

    setWhereConditions(newConditions);
  };

  // 출력 필드 추가
  const handleAddOutputField = () => {
    setOutputFields([
      ...outputFields,
      {
        fieldName: "",
        alias: "",
      },
    ]);
  };

  const handleRemoveOutputField = (index: number) => {
    setOutputFields(outputFields.filter((_, i) => i !== index));
  };

  const handleOutputFieldChange = (index: number, field: string, value: any) => {
    const newFields = [...outputFields];
    newFields[index] = { ...newFields[index], [field]: value };

    // 라벨도 함께 저장
    if (field === "fieldName") {
      const refField = referenceColumns.find((f) => f.name === value);
      newFields[index].fieldLabel = refField?.label || value;
      // alias 자동 설정
      if (!newFields[index].alias) {
        newFields[index].alias = `ref_${value}`;
      }
    }

    setOutputFields(newFields);
  };

  const handleSave = () => {
    updateNode(nodeId, {
      displayName,
      referenceTable,
      referenceTableLabel,
      joinConditions,
      whereConditions,
      outputFields,
    });
  };

  const selectedTableLabel = tables.find((t) => t.tableName === referenceTable)?.label || referenceTable;

  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) => setDisplayName(e.target.value)}
                className="mt-1"
                placeholder="노드 표시 이름"
              />
            </div>

            {/* 참조 테이블 선택 */}
            <div>
              <Label className="text-xs">참조 테이블</Label>
              <Popover open={tablesOpen} onOpenChange={setTablesOpen}>
                <PopoverTrigger asChild>
                  <Button
                    variant="outline"
                    role="combobox"
                    aria-expanded={tablesOpen}
                    className="mt-1 w-full justify-between"
                    disabled={tablesLoading}
                  >
                    {tablesLoading ? (
                      <span className="text-muted-foreground">로딩 중...</span>
                    ) : referenceTable ? (
                      <span className="truncate">{selectedTableLabel}</span>
                    ) : (
                      <span className="text-muted-foreground">테이블 선택...</span>
                    )}
                    <Search className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                  </Button>
                </PopoverTrigger>
                <PopoverContent className="w-[320px] p-0" align="start">
                  <Command>
                    <CommandInput placeholder="테이블 검색..." className="h-9" />
                    <CommandList>
                      <CommandEmpty>검색 결과가 없습니다.</CommandEmpty>
                      <CommandGroup>
                        <ScrollArea className="h-[300px]">
                          {tables.map((table) => (
                            <CommandItem
                              key={table.tableName}
                              value={`${table.label} ${table.tableName} ${table.description}`}
                              onSelect={() => handleTableSelect(table.tableName)}
                              className="cursor-pointer"
                            >
                              <Check
                                className={cn(
                                  "mr-2 h-4 w-4",
                                  referenceTable === table.tableName ? "opacity-100" : "opacity-0",
                                )}
                              />
                              <div className="flex flex-col">
                                <span className="font-medium">{table.label}</span>
                                {table.label !== table.tableName && (
                                  <span className="text-muted-foreground text-xs">{table.tableName}</span>
                                )}
                              </div>
                            </CommandItem>
                          ))}
                        </ScrollArea>
                      </CommandGroup>
                    </CommandList>
                  </Command>
                </PopoverContent>
              </Popover>
            </div>
          </div>
        </div>

        {/* 조인 조건 */}
        <div>
          <div className="mb-2 flex items-center justify-between">
            <h3 className="text-sm font-semibold">조인 조건 (FK 매핑)</h3>
            <Button
              size="sm"
              variant="outline"
              onClick={handleAddJoinCondition}
              className="h-7"
              disabled={!referenceTable}
            >
              <Plus className="mr-1 h-3 w-3" />
              추가
            </Button>
          </div>

          {joinConditions.length > 0 ? (
            <div className="space-y-2">
              {joinConditions.map((condition, index) => (
                <div key={index} className="rounded border bg-purple-50 p-3">
                  <div className="mb-2 flex items-center justify-between">
                    <span className="text-xs font-medium text-purple-700">조인 #{index + 1}</span>
                    <Button
                      size="sm"
                      variant="ghost"
                      onClick={() => handleRemoveJoinCondition(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-gray-600">소스 필드</Label>
                      <Select
                        value={condition.sourceField}
                        onValueChange={(value) => handleJoinConditionChange(index, "sourceField", value)}
                      >
                        <SelectTrigger className="mt-1 h-8 text-xs">
                          <SelectValue placeholder="소스 필드 선택" />
                        </SelectTrigger>
                        <SelectContent>
                          {sourceFields.map((field) => (
                            <SelectItem key={field.name} value={field.name}>
                              {field.label || field.name}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    </div>

                    <div>
                      <Label className="text-xs text-gray-600">참조 필드</Label>
                      <Select
                        value={condition.referenceField}
                        onValueChange={(value) => handleJoinConditionChange(index, "referenceField", value)}
                      >
                        <SelectTrigger className="mt-1 h-8 text-xs">
                          <SelectValue placeholder="참조 필드 선택" />
                        </SelectTrigger>
                        <SelectContent>
                          {referenceColumns.map((field) => (
                            <SelectItem key={field.name} value={field.name}>
                              {field.label || field.name}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    </div>
                  </div>
                </div>
              ))}
            </div>
          ) : (
            <div className="rounded border border-dashed p-4 text-center text-xs text-gray-400">
              조인 조건을 추가하세요 (필수)
            </div>
          )}
        </div>

        {/* WHERE 조건 */}
        <div>
          <div className="mb-2 flex items-center justify-between">
            <h3 className="text-sm font-semibold">WHERE 조건 (선택사항)</h3>
            <Button
              size="sm"
              variant="outline"
              onClick={handleAddWhereCondition}
              className="h-7"
              disabled={!referenceTable}
            >
              <Plus className="mr-1 h-3 w-3" />
              추가
            </Button>
          </div>

          {whereConditions.length > 0 && (
            <div className="space-y-2">
              {whereConditions.map((condition, index) => (
                <div key={index} className="rounded border bg-yellow-50 p-3">
                  <div className="mb-2 flex items-center justify-between">
                    <span className="text-xs font-medium text-yellow-700">WHERE #{index + 1}</span>
                    <Button
                      size="sm"
                      variant="ghost"
                      onClick={() => handleRemoveWhereCondition(index)}
                      className="h-6 w-6 p-0"
                    >
                      <Trash2 className="h-3 w-3" />
                    </Button>
                  </div>

                  <div className="space-y-2">
                    {/* 필드 - Combobox */}
                    <div>
                      <Label className="text-xs text-gray-600">필드</Label>
                      <Popover
                        open={whereFieldOpenState[index]}
                        onOpenChange={(open) => {
                          const newState = [...whereFieldOpenState];
                          newState[index] = open;
                          setWhereFieldOpenState(newState);
                        }}
                      >
                        <PopoverTrigger asChild>
                          <Button
                            variant="outline"
                            role="combobox"
                            aria-expanded={whereFieldOpenState[index]}
                            className="mt-1 h-8 w-full justify-between text-xs sm:h-10 sm:text-sm"
                          >
                            {condition.field
                              ? (() => {
                                  const field = referenceColumns.find((f) => f.name === condition.field);
                                  return (
                                    <div className="flex items-center justify-between gap-2 overflow-hidden">
                                      <span className="truncate">{field?.label || condition.field}</span>
                                      {field?.type && (
                                        <span className="text-muted-foreground text-xs">{field.type}</span>
                                      )}
                                    </div>
                                  );
                                })()
                              : "필드 선택"}
                            <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                          </Button>
                        </PopoverTrigger>
                        <PopoverContent
                          className="p-0"
                          style={{ width: "var(--radix-popover-trigger-width)" }}
                          align="start"
                        >
                          <Command>
                            <CommandInput placeholder="필드 검색..." className="text-xs sm:text-sm" />
                            <CommandList>
                              <CommandEmpty className="text-xs sm:text-sm">필드를 찾을 수 없습니다.</CommandEmpty>
                              <CommandGroup>
                                {referenceColumns.map((field) => (
                                  <CommandItem
                                    key={field.name}
                                    value={field.name}
                                    onSelect={(currentValue) => {
                                      handleWhereConditionChange(index, "field", currentValue);
                                      const newState = [...whereFieldOpenState];
                                      newState[index] = false;
                                      setWhereFieldOpenState(newState);
                                    }}
                                    className="text-xs sm:text-sm"
                                  >
                                    <Check
                                      className={cn(
                                        "mr-2 h-4 w-4",
                                        condition.field === field.name ? "opacity-100" : "opacity-0",
                                      )}
                                    />
                                    <div className="flex flex-col">
                                      <span className="font-medium">{field.label || field.name}</span>
                                      {field.type && (
                                        <span className="text-muted-foreground text-[10px]">{field.type}</span>
                                      )}
                                    </div>
                                  </CommandItem>
                                ))}
                              </CommandGroup>
                            </CommandList>
                          </Command>
                        </PopoverContent>
                      </Popover>
                    </div>

                    <div>
                      <Label className="text-xs text-gray-600">연산자</Label>
                      <Select
                        value={condition.operator}
                        onValueChange={(value) => handleWhereConditionChange(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>

                    <div>
                      <Label className="text-xs text-gray-600">값 타입</Label>
                      <Select
                        value={condition.valueType || "static"}
                        onValueChange={(value) => handleWhereConditionChange(index, "valueType", value)}
                      >
                        <SelectTrigger className="mt-1 h-8 text-xs">
                          <SelectValue />
                        </SelectTrigger>
                        <SelectContent>
                          <SelectItem value="static">고정값</SelectItem>
                          <SelectItem value="field">소스 필드 참조</SelectItem>
                        </SelectContent>
                      </Select>
                    </div>

                    <div>
                      <Label className="text-xs text-gray-600">
                        {condition.valueType === "field" ? "소스 필드" : "값"}
                      </Label>
                      {condition.valueType === "field" ? (
                        <Select
                          value={condition.value}
                          onValueChange={(value) => handleWhereConditionChange(index, "value", value)}
                        >
                          <SelectTrigger className="mt-1 h-8 text-xs">
                            <SelectValue placeholder="소스 필드 선택" />
                          </SelectTrigger>
                          <SelectContent>
                            {sourceFields.map((field) => (
                              <SelectItem key={field.name} value={field.name}>
                                {field.label || field.name}
                              </SelectItem>
                            ))}
                          </SelectContent>
                        </Select>
                      ) : (
                        <Input
                          value={condition.value}
                          onChange={(e) => handleWhereConditionChange(index, "value", e.target.value)}
                          placeholder="비교할 값"
                          className="mt-1 h-8 text-xs"
                        />
                      )}
                    </div>
                  </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={handleAddOutputField}
              className="h-7"
              disabled={!referenceTable}
            >
              <Plus className="mr-1 h-3 w-3" />
              추가
            </Button>
          </div>

          {outputFields.length > 0 ? (
            <div className="space-y-2">
              {outputFields.map((field, index) => (
                <div key={index} className="rounded border bg-blue-50 p-3">
                  <div className="mb-2 flex items-center justify-between">
                    <span className="text-xs font-medium text-blue-700">필드 #{index + 1}</span>
                    <Button
                      size="sm"
                      variant="ghost"
                      onClick={() => handleRemoveOutputField(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-gray-600">참조 테이블 필드</Label>
                      <Select
                        value={field.fieldName}
                        onValueChange={(value) => handleOutputFieldChange(index, "fieldName", value)}
                      >
                        <SelectTrigger className="mt-1 h-8 text-xs">
                          <SelectValue placeholder="필드 선택" />
                        </SelectTrigger>
                        <SelectContent>
                          {referenceColumns.map((col) => (
                            <SelectItem key={col.name} value={col.name}>
                              {col.label || col.name}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    </div>

                    <div>
                      <Label className="text-xs text-gray-600">별칭 (Alias)</Label>
                      <Input
                        value={field.alias}
                        onChange={(e) => handleOutputFieldChange(index, "alias", e.target.value)}
                        placeholder="ref_field_name"
                        className="mt-1 h-8 text-xs"
                      />
                    </div>
                  </div>
                </div>
              ))}
            </div>
          ) : (
            <div className="rounded border border-dashed p-4 text-center text-xs text-gray-400">
              출력 필드를 추가하세요 (필수)
            </div>
          )}
        </div>

        {/* 저장 버튼 */}

        {/* 안내 */}
        <div className="space-y-2">
          <div className="rounded bg-purple-50 p-3 text-xs text-purple-700">
            🔗 <strong>조인 조건</strong>: 소스 데이터와 참조 테이블을 연결하는 키 (예: customer_id → id)
          </div>
          <div className="rounded bg-yellow-50 p-3 text-xs text-yellow-700">
            ⚡ <strong>WHERE 조건</strong>: 참조 테이블에서 특정 조건의 데이터만 가져오기 (예: grade = 'VIP')
          </div>
          <div className="rounded bg-blue-50 p-3 text-xs text-blue-700">
            📤 <strong>출력 필드</strong>: 참조 테이블에서 가져올 필드 선택 (별칭으로 결과에 추가됨)
          </div>
        </div>
      </div>
    </div>
  );
}
