/**
 * 플로우 조건 빌더
 * 동적 조건 생성 UI
 */

import { useState, useEffect } from "react";
import { Plus, Trash2, Check, ChevronsUpDown } from "lucide-react";
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 { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Badge } from "@/components/ui/badge";
import { FlowConditionGroup, FlowCondition, ConditionOperator } from "@/types/flow";
import { getTableColumns } from "@/lib/api/tableManagement";
import { ExternalRestApiConnectionAPI } from "@/lib/api/externalRestApiConnection";
import { cn } from "@/lib/utils";

// 다중 REST API 연결 설정
interface RestApiConnectionConfig {
  connectionId: number;
  connectionName: string;
  endpoint: string;
  jsonPath: string;
  alias: string;
}

interface FlowConditionBuilderProps {
  flowId: number;
  tableName?: string; // 조회할 테이블명
  dbSourceType?: "internal" | "external" | "restapi" | "multi_restapi"; // DB 소스 타입
  dbConnectionId?: number; // 외부 DB 연결 ID
  restApiConnectionId?: number; // REST API 연결 ID (단일)
  restApiEndpoint?: string; // REST API 엔드포인트 (단일)
  restApiJsonPath?: string; // REST API JSON 경로 (단일)
  restApiConnections?: RestApiConnectionConfig[]; // 다중 REST API 설정
  condition?: FlowConditionGroup;
  onChange: (condition: FlowConditionGroup | undefined) => void;
}

const OPERATORS: { value: ConditionOperator; label: string }[] = [
  { 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: "in", label: "포함 (IN)" },
  { value: "not_in", label: "제외 (NOT IN)" },
  { value: "like", label: "유사 (LIKE)" },
  { value: "not_like", label: "유사하지 않음 (NOT LIKE)" },
  { value: "is_null", label: "NULL" },
  { value: "is_not_null", label: "NOT NULL" },
];

export function FlowConditionBuilder({
  flowId,
  tableName,
  dbSourceType = "internal",
  dbConnectionId,
  restApiConnectionId,
  restApiEndpoint,
  restApiJsonPath,
  restApiConnections,
  condition,
  onChange,
}: FlowConditionBuilderProps) {
  const [columns, setColumns] = useState<any[]>([]);
  const [loadingColumns, setLoadingColumns] = useState(false);
  const [conditionType, setConditionType] = useState<"AND" | "OR">(condition?.type || "AND");
  const [conditions, setConditions] = useState<FlowCondition[]>(condition?.conditions || []);
  const [columnComboboxOpen, setColumnComboboxOpen] = useState<Record<number, boolean>>({});

  // condition prop이 변경될 때 상태 동기화
  useEffect(() => {
    if (condition) {
      setConditionType(condition.type || "AND");
      setConditions(condition.conditions || []);
    } else {
      setConditionType("AND");
      setConditions([]);
    }
  }, [condition]);

  // 테이블 컬럼 로드 - 내부/외부 DB 및 REST API 모두 지원
  useEffect(() => {
    // REST API인 경우 tableName이 없어도 진행 가능
    if (!tableName && dbSourceType !== "restapi" && dbSourceType !== "multi_restapi") {
      setColumns([]);
      return;
    }

    const loadColumns = async () => {
      try {
        setLoadingColumns(true);
        console.log("🔍 [FlowConditionBuilder] Loading columns:", {
          tableName,
          dbSourceType,
          dbConnectionId,
          restApiConnectionId,
          restApiEndpoint,
          restApiJsonPath,
          restApiConnections,
        });

        // 다중 REST API인 경우
        if (dbSourceType === "multi_restapi" && restApiConnections && restApiConnections.length > 0) {
          try {
            console.log("🌐 [FlowConditionBuilder] 다중 REST API 컬럼 로드 시작:", restApiConnections);
            
            // 각 API에서 컬럼 정보 수집
            const allColumns: any[] = [];
            
            for (const config of restApiConnections) {
              try {
                const effectiveJsonPath = (!config.jsonPath || config.jsonPath === "data") ? "response" : config.jsonPath;
                
                const restApiData = await ExternalRestApiConnectionAPI.fetchData(
                  config.connectionId,
                  config.endpoint,
                  effectiveJsonPath,
                );
                
                if (restApiData.columns && restApiData.columns.length > 0) {
                  // 별칭 적용
                  const prefixedColumns = restApiData.columns.map((col) => ({
                    column_name: config.alias ? `${config.alias}${col.columnName}` : col.columnName,
                    data_type: col.dataType || "varchar",
                    displayName: `${col.columnLabel || col.columnName} (${config.connectionName})`,
                    sourceApi: config.connectionName,
                  }));
                  allColumns.push(...prefixedColumns);
                }
              } catch (apiError) {
                console.warn(`API ${config.connectionId} 컬럼 로드 실패:`, apiError);
              }
            }
            
            console.log("✅ [FlowConditionBuilder] 다중 REST API 컬럼 로드 완료:", allColumns.length, "items");
            setColumns(allColumns);
          } catch (multiApiError) {
            console.error("❌ 다중 REST API 컬럼 로드 실패:", multiApiError);
            setColumns([]);
          }
          return;
        }

        // 단일 REST API인 경우 (dbSourceType이 restapi이거나 tableName이 _restapi_로 시작)
        const isRestApi = dbSourceType === "restapi" || tableName?.startsWith("_restapi_");
        
        // tableName에서 REST API 연결 ID 추출 (restApiConnectionId가 없는 경우)
        let effectiveRestApiConnectionId = restApiConnectionId;
        if (isRestApi && !effectiveRestApiConnectionId && tableName) {
          const match = tableName.match(/_restapi_(\d+)/);
          if (match) {
            effectiveRestApiConnectionId = parseInt(match[1]);
            console.log("🔍 tableName에서 REST API 연결 ID 추출:", effectiveRestApiConnectionId);
          }
        }
        
        if (isRestApi && effectiveRestApiConnectionId) {
          try {
            // jsonPath가 "data"이거나 없으면 "response"로 변경 (thiratis API 응답 구조에 맞춤)
            const effectiveJsonPath = (!restApiJsonPath || restApiJsonPath === "data") ? "response" : restApiJsonPath;
            
            console.log("🌐 [FlowConditionBuilder] REST API 컬럼 로드 시작:", {
              connectionId: effectiveRestApiConnectionId,
              endpoint: restApiEndpoint,
              jsonPath: restApiJsonPath,
              effectiveJsonPath,
            });
            
            const restApiData = await ExternalRestApiConnectionAPI.fetchData(
              effectiveRestApiConnectionId,
              restApiEndpoint,
              effectiveJsonPath,
            );
            
            console.log("✅ [FlowConditionBuilder] REST API columns response:", restApiData);
            
            if (restApiData.columns && restApiData.columns.length > 0) {
              const columnList = restApiData.columns.map((col) => ({
                column_name: col.columnName,
                data_type: col.dataType || "varchar",
                displayName: col.columnLabel || col.columnName,
              }));
              console.log("✅ Setting REST API columns:", columnList.length, "items", columnList);
              setColumns(columnList);
            } else {
              console.warn("❌ No columns in REST API response");
              setColumns([]);
            }
          } catch (restApiError) {
            console.error("❌ REST API 컬럼 로드 실패:", restApiError);
            setColumns([]);
          }
          return;
        }

        // 외부 DB인 경우
        if (dbSourceType === "external" && dbConnectionId) {
          const token = localStorage.getItem("authToken");
          if (!token) {
            console.warn("토큰이 없습니다. 외부 DB 컬럼 목록을 조회할 수 없습니다.");
            setColumns([]);
            return;
          }

          const response = await fetch(
            `/api/multi-connection/connections/${dbConnectionId}/tables/${tableName}/columns`,
            {
              credentials: "include",
              headers: {
                Authorization: `Bearer ${token}`,
                "Content-Type": "application/json",
              },
            },
          ).catch((err) => {
            console.warn("외부 DB 컬럼 fetch 실패:", err);
            return null;
          });

          if (response && response.ok) {
            const result = await response.json();
            console.log("✅ [FlowConditionBuilder] External columns response:", result);

            if (result.success && result.data) {
              const columnList = Array.isArray(result.data)
                ? result.data.map((col: any) => ({
                    column_name: col.column_name || col.columnName || col.name,
                    data_type: col.data_type || col.dataType || col.type,
                  }))
                : [];
              console.log("✅ Setting external columns:", columnList.length, "items");
              setColumns(columnList);
            } else {
              console.warn("❌ No data in external columns response");
              setColumns([]);
            }
          } else {
            console.warn(`외부 DB 컬럼 조회 실패: ${response?.status}`);
            setColumns([]);
          }
        } else {
          // 내부 DB인 경우 (기존 로직)
          const response = await getTableColumns(tableName);
          console.log("📦 [FlowConditionBuilder] Internal columns response:", response);

          if (response.success && response.data?.columns) {
            const columnArray = Array.isArray(response.data.columns) ? response.data.columns : [];
            console.log("✅ Setting internal columns:", columnArray.length, "items");
            setColumns(columnArray);
          } else {
            console.error("❌ Failed to load internal columns:", response.message);
            setColumns([]);
          }
        }
      } catch (error) {
        console.error("❌ Exception loading columns:", error);
        setColumns([]);
      } finally {
        setLoadingColumns(false);
      }
    };

    loadColumns();
  }, [tableName, dbSourceType, dbConnectionId, restApiConnectionId, restApiEndpoint, restApiJsonPath]);

  // 조건 변경 시 부모에 전달
  useEffect(() => {
    if (conditions.length === 0) {
      onChange(undefined);
    } else {
      onChange({
        type: conditionType,
        conditions,
      });
    }
  }, [conditionType, conditions]);

  // 조건 추가
  const addCondition = () => {
    setConditions([
      ...conditions,
      {
        column: "",
        operator: "equals",
        value: "",
      },
    ]);
  };

  // 조건 수정
  const updateCondition = (index: number, field: keyof FlowCondition, value: any) => {
    const newConditions = [...conditions];
    newConditions[index] = {
      ...newConditions[index],
      [field]: value,
    };
    setConditions(newConditions);
  };

  // 조건 삭제
  const removeCondition = (index: number) => {
    setConditions(conditions.filter((_, i) => i !== index));
  };

  // value가 필요 없는 연산자 체크
  const needsValue = (operator: ConditionOperator) => {
    return operator !== "is_null" && operator !== "is_not_null";
  };

  return (
    <div className="space-y-4">
      {/* 조건 타입 선택 */}
      <div>
        <Label>조건 결합 방식</Label>
        <Select value={conditionType} onValueChange={(value) => setConditionType(value as "AND" | "OR")}>
          <SelectTrigger>
            <SelectValue />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="AND">AND (모든 조건 만족)</SelectItem>
            <SelectItem value="OR">OR (하나 이상 만족)</SelectItem>
          </SelectContent>
        </Select>
      </div>

      {/* 조건 목록 */}
      <div className="space-y-3">
        {conditions.length === 0 ? (
          <div className="text-muted-foreground rounded border-2 border-dashed py-4 text-center text-sm">
            조건이 없습니다
            <br />
            조건을 추가하여 데이터를 필터링하세요
          </div>
        ) : (
          conditions.map((cond, index) => (
            <div key={index} className="space-y-2 rounded border bg-muted p-3">
              {/* 조건 번호 및 삭제 버튼 */}
              <div className="flex items-center justify-between">
                <Badge variant="outline">조건 {index + 1}</Badge>
                <Button variant="ghost" size="sm" onClick={() => removeCondition(index)}>
                  <Trash2 className="h-4 w-4" />
                </Button>
              </div>

              {/* 컬럼 선택 */}
              <div>
                <Label className="text-xs">컬럼</Label>
                {loadingColumns ? (
                  <Input value="컬럼 로딩 중..." disabled className="h-8" />
                ) : !Array.isArray(columns) || columns.length === 0 ? (
                  <Input
                    value={cond.column}
                    onChange={(e) => updateCondition(index, "column", e.target.value)}
                    placeholder="테이블을 먼저 선택하세요"
                    className="h-8"
                  />
                ) : (
                  <Popover
                    open={columnComboboxOpen[index] || false}
                    onOpenChange={(open) => setColumnComboboxOpen({ ...columnComboboxOpen, [index]: open })}
                  >
                    <PopoverTrigger asChild>
                      <Button
                        variant="outline"
                        role="combobox"
                        aria-expanded={columnComboboxOpen[index] || false}
                        className="h-8 w-full justify-between text-xs font-normal"
                      >
                        {cond.column
                          ? (() => {
                              const col = columns.find((c) => (c.column_name || c.columnName) === cond.column);
                              const displayName = col?.displayName || col?.display_name || cond.column;
                              const dataType = col?.data_type || col?.dataType || "";
                              return (
                                <span className="flex items-center gap-2">
                                  <span className="font-medium">{displayName}</span>
                                  {dataType && <span className="text-muted-foreground">({dataType})</span>}
                                </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="컬럼 검색..." className="h-8 text-xs" />
                        <CommandList>
                          <CommandEmpty className="py-2 text-center text-xs text-muted-foreground">
                            컬럼을 찾을 수 없습니다.
                          </CommandEmpty>
                          <CommandGroup>
                            {columns.map((col, idx) => {
                              const columnName = col.column_name || col.columnName || "";
                              const dataType = col.data_type || col.dataType || "";
                              const displayName = col.displayName || col.display_name || columnName;

                              return (
                                <CommandItem
                                  key={`${columnName}-${idx}`}
                                  value={columnName}
                                  onSelect={(currentValue) => {
                                    updateCondition(index, "column", currentValue);
                                    setColumnComboboxOpen({ ...columnComboboxOpen, [index]: false });
                                  }}
                                  className="text-xs"
                                >
                                  <Check
                                    className={cn(
                                      "mr-2 h-3 w-3",
                                      cond.column === columnName ? "opacity-100" : "opacity-0",
                                    )}
                                  />
                                  <div className="flex items-center gap-2">
                                    <span className="font-medium">{displayName}</span>
                                    <span className="text-muted-foreground">({dataType})</span>
                                  </div>
                                </CommandItem>
                              );
                            })}
                          </CommandGroup>
                        </CommandList>
                      </Command>
                    </PopoverContent>
                  </Popover>
                )}
              </div>

              {/* 연산자 선택 */}
              <div>
                <Label className="text-xs">연산자</Label>
                <Select
                  value={cond.operator}
                  onValueChange={(value) => updateCondition(index, "operator", value as ConditionOperator)}
                >
                  <SelectTrigger className="h-8">
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    {OPERATORS.map((op) => (
                      <SelectItem key={op.value} value={op.value}>
                        {op.label}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>

              {/* 값 입력 */}
              {needsValue(cond.operator) && (
                <div>
                  <Label className="text-xs">값</Label>
                  <Input
                    value={cond.value || ""}
                    onChange={(e) => updateCondition(index, "value", e.target.value)}
                    placeholder="값 입력"
                    className="h-8"
                  />
                  {(cond.operator === "in" || cond.operator === "not_in") && (
                    <p className="text-muted-foreground mt-1 text-xs">쉼표(,)로 구분하여 여러 값 입력</p>
                  )}
                </div>
              )}
            </div>
          ))
        )}
      </div>

      {/* 조건 추가 버튼 */}
      <Button variant="outline" size="sm" onClick={addCondition} className="w-full">
        <Plus className="mr-2 h-4 w-4" />
        조건 추가
      </Button>

      {/* 조건 요약 */}
      {conditions.length > 0 && (
        <div className="rounded bg-primary/10 p-3 text-sm">
          <strong>조건 요약:</strong>
          <div className="mt-2 space-y-1">
            {conditions.map((cond, index) => (
              <div key={index} className="flex items-center gap-2">
                <Badge variant="secondary" className="text-xs">
                  {cond.column}
                </Badge>
                <span className="text-muted-foreground">
                  {OPERATORS.find((op) => op.value === cond.operator)?.label}
                </span>
                {needsValue(cond.operator) && <code className="rounded bg-white px-2 py-1 text-xs">{cond.value}</code>}
                {index < conditions.length - 1 && <Badge>{conditionType}</Badge>}
              </div>
            ))}
          </div>
        </div>
      )}
    </div>
  );
}
