"use client";

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

import { useEffect, useState } from "react";
import { Plus, Trash2 } from "lucide-react";
import { Label } from "@/components/ui/label";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { useFlowEditorStore } from "@/lib/stores/flowEditorStore";
import type { ConditionNodeData } from "@/types/node-editor";

// 필드 정의
interface FieldDefinition {
  name: string;
  label?: string;
  type?: 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" },
] as const;

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[]>([]);

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

  // 🔥 연결된 소스 노드의 필드를 재귀적으로 수집
  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 = () => {
    setConditions([
      ...conditions,
      {
        field: "",
        operator: "EQUALS",
        value: "",
        valueType: "static", // "static" (고정값) 또는 "field" (필드 참조)
      },
    ]);
  };

  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 = (index: number, field: string, value: any) => {
    const newConditions = [...conditions];
    newConditions[index] = { ...newConditions[index], [field]: value };
    setConditions(newConditions);
    updateNode(nodeId, {
      conditions: newConditions,
    });
  };

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

  return (
    <ScrollArea className="h-full">
      <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>

        {/* 조건식 */}
        <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-yellow-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-gray-600">필드명</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-gray-400">({field.type})</span>}
                              </SelectItem>
                            ))}
                          </SelectContent>
                        </Select>
                      ) : (
                        <div className="mt-1 rounded border border-dashed bg-gray-50 p-2 text-center text-xs text-gray-400">
                          소스 노드를 연결하세요
                        </div>
                      )}
                    </div>

                    <div>
                      <Label className="text-xs text-gray-600">연산자</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>

                    {condition.operator !== "IS_NULL" && condition.operator !== "IS_NOT_NULL" && (
                      <>
                        <div>
                          <Label className="text-xs text-gray-600">비교 값 타입</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>
                            </SelectContent>
                          </Select>
                        </div>

                        <div>
                          <Label className="text-xs text-gray-600">
                            {(condition as any).valueType === "field" ? "비교 필드" : "비교 값"}
                          </Label>
                          {(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-gray-400">({field.type})</span>}
                                    </SelectItem>
                                  ))}
                                </SelectContent>
                              </Select>
                            ) : (
                              <div className="mt-1 rounded border border-dashed bg-gray-50 p-2 text-center text-xs text-gray-400">
                                소스 노드를 연결하세요
                              </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-gray-400">
              조건식이 없습니다. "추가" 버튼을 클릭하세요.
            </div>
          )}
        </div>


        {/* 안내 */}
        <div className="space-y-2">
          <div className="rounded bg-blue-50 p-3 text-xs text-blue-700">
            🔌 <strong>소스 노드 연결</strong>: 테이블/외부DB 노드를 연결하면 자동으로 필드 목록이 표시됩니다.
          </div>
          <div className="rounded bg-green-50 p-3 text-xs text-green-700">
            🔄 <strong>비교 값 타입</strong>:<br />• <strong>고정값</strong>: 직접 입력한 값과 비교 (예: age &gt; 30)
            <br />• <strong>필드 참조</strong>: 다른 필드의 값과 비교 (예: 주문수량 &gt; 재고수량)
          </div>
          <div className="rounded bg-yellow-50 p-3 text-xs text-yellow-700">
            💡 <strong>AND</strong>: 모든 조건이 참이어야 TRUE 출력
          </div>
          <div className="rounded bg-yellow-50 p-3 text-xs text-yellow-700">
            💡 <strong>OR</strong>: 하나라도 참이면 TRUE 출력
          </div>
          <div className="rounded bg-yellow-50 p-3 text-xs text-yellow-700">
            ⚡ TRUE 출력은 오른쪽 위, FALSE 출력은 오른쪽 아래입니다.
          </div>
        </div>
      </div>
    </ScrollArea>
  );
}
