"use client";

import React, { useState, useEffect, useRef } from "react";
import { Input } from "@/components/ui/input";
import { X, Loader2, ChevronDown } from "lucide-react";
import { Button } from "@/components/ui/button";
import { useEntitySearch } from "../entity-search-input/useEntitySearch";
import { EntitySearchResult } from "../entity-search-input/types";
import { cn } from "@/lib/utils";
import { AutocompleteSearchInputConfig } from "./types";
import { ComponentRendererProps } from "../../DynamicComponentRenderer";

export interface AutocompleteSearchInputProps extends ComponentRendererProps {
  config?: AutocompleteSearchInputConfig;
  tableName?: string;
  displayField?: string;
  valueField?: string;
  searchFields?: string[];
  filterCondition?: Record<string, any>;
  placeholder?: string;
  showAdditionalInfo?: boolean;
  additionalFields?: string[];
}

export function AutocompleteSearchInputComponent({
  component,
  config,
  tableName: propTableName,
  displayField: propDisplayField,
  valueField: propValueField,
  searchFields: propSearchFields,
  filterCondition = {},
  placeholder: propPlaceholder,
  disabled = false,
  value,
  onChange,
  className,
  isInteractive = false,
  onFormDataChange,
  formData,
}: AutocompleteSearchInputProps) {
  // config prop 우선, 없으면 개별 prop 사용
  const tableName = config?.tableName || propTableName || "";
  const displayField = config?.displayField || propDisplayField || "";
  const displayFields = config?.displayFields || (displayField ? [displayField] : []); // 다중 표시 필드
  const displaySeparator = config?.displaySeparator || " → "; // 구분자

  // valueField 결정: fieldMappings 기반으로 추론 (config.valueField가 fieldMappings에 없으면 무시)
  const getValueField = () => {
    // fieldMappings가 있으면 그 안에서 추론 (가장 신뢰할 수 있는 소스)
    if (config?.fieldMappings && config.fieldMappings.length > 0) {
      // config.valueField가 fieldMappings의 sourceField에 있으면 사용
      if (config?.valueField) {
        const hasValueFieldInMappings = config.fieldMappings.some((m: any) => m.sourceField === config.valueField);
        if (hasValueFieldInMappings) {
          return config.valueField;
        }
        // fieldMappings에 없으면 무시하고 추론
      }

      // _code 또는 _id로 끝나는 필드 우선 (보통 PK나 코드 필드)
      const codeMapping = config.fieldMappings.find(
        (m: any) => m.sourceField?.endsWith("_code") || m.sourceField?.endsWith("_id"),
      );
      if (codeMapping) {
        return codeMapping.sourceField;
      }

      // 없으면 첫 번째 매핑 사용
      return config.fieldMappings[0].sourceField || "";
    }

    // fieldMappings가 없으면 기존 방식
    if (config?.valueField) return config.valueField;
    if (propValueField) return propValueField;

    return "";
  };
  const valueField = getValueField();

  const searchFields = config?.searchFields || propSearchFields || displayFields; // 검색 필드도 다중 표시 필드 사용
  const placeholder = config?.placeholder || propPlaceholder || "검색...";

  // 다중 필드 값을 조합하여 표시 문자열 생성
  const getDisplayValue = (item: EntitySearchResult): string => {
    if (displayFields.length > 1) {
      // 여러 필드를 구분자로 조합
      const values = displayFields
        .map((field) => item[field])
        .filter((v) => v !== null && v !== undefined && v !== "")
        .map((v) => String(v));
      return values.join(displaySeparator);
    }
    // 단일 필드
    return item[displayField] || "";
  };

  const [inputValue, setInputValue] = useState("");
  const [isOpen, setIsOpen] = useState(false);
  const [selectedData, setSelectedData] = useState<EntitySearchResult | null>(null);
  const containerRef = useRef<HTMLDivElement>(null);

  const { searchText, setSearchText, results, loading, clearSearch } = useEntitySearch({
    tableName,
    searchFields,
    filterCondition,
  });

  // 선택된 데이터를 ref로도 유지 (리렌더링 시 초기화 방지)
  const selectedDataRef = useRef<EntitySearchResult | null>(null);
  const inputValueRef = useRef<string>("");
  const initialValueLoadedRef = useRef<string | null>(null); // 초기값 로드 추적

  // formData에서 현재 값 가져오기 (isInteractive 모드)
  // 우선순위: 1) component.columnName, 2) fieldMappings에서 valueField에 매핑된 targetField
  const getCurrentValue = () => {
    if (!isInteractive || !formData) {
      return value;
    }

    // 1. component.columnName으로 직접 바인딩된 경우
    if (component?.columnName && formData[component.columnName] !== undefined) {
      return formData[component.columnName];
    }

    // 2. fieldMappings에서 valueField와 매핑된 targetField에서 값 가져오기
    if (config?.fieldMappings && Array.isArray(config.fieldMappings)) {
      const valueFieldMapping = config.fieldMappings.find((mapping: any) => mapping.sourceField === valueField);

      if (valueFieldMapping) {
        const targetField = valueFieldMapping.targetField || valueFieldMapping.targetColumn;

        if (targetField && formData[targetField] !== undefined) {
          return formData[targetField];
        }
      }
    }

    return value;
  };

  const currentValue = getCurrentValue();

  // selectedData 변경 시 ref도 업데이트
  useEffect(() => {
    if (selectedData) {
      selectedDataRef.current = selectedData;
      inputValueRef.current = inputValue;
    }
  }, [selectedData, inputValue]);

  // 리렌더링 시 ref에서 값 복원
  useEffect(() => {
    if (!selectedData && selectedDataRef.current) {
      setSelectedData(selectedDataRef.current);
      setInputValue(inputValueRef.current);
    }
  }, []);

  // 초기값이 있을 때 해당 값의 표시 텍스트를 조회하여 설정
  useEffect(() => {
    const loadInitialDisplayValue = async () => {
      // 이미 로드된 값이거나, 값이 없거나, 이미 선택된 데이터가 있으면 스킵
      if (!currentValue || selectedData || selectedDataRef.current) {
        return;
      }

      // 이미 같은 값을 로드한 적이 있으면 스킵
      if (initialValueLoadedRef.current === currentValue) {
        return;
      }

      // 테이블명과 필드 정보가 없으면 스킵
      if (!tableName || !valueField) {
        return;
      }

      console.log("🔄 AutocompleteSearchInput 초기값 로드:", {
        currentValue,
        tableName,
        valueField,
        displayFields,
      });

      try {
        // API를 통해 해당 값의 표시 텍스트 조회
        const { apiClient } = await import("@/lib/api/client");
        const filterConditionWithValue = {
          ...filterCondition,
          [valueField]: currentValue,
        };

        const params = new URLSearchParams({
          searchText: "",
          searchFields: searchFields.join(","),
          filterCondition: JSON.stringify(filterConditionWithValue),
          page: "1",
          limit: "10",
        });

        const response = await apiClient.get<{ success: boolean; data: EntitySearchResult[] }>(
          `/entity-search/${tableName}?${params.toString()}`,
        );

        if (response.data.success && response.data.data && response.data.data.length > 0) {
          const matchedItem = response.data.data.find(
            (item: EntitySearchResult) => String(item[valueField]) === String(currentValue),
          );

          if (matchedItem) {
            const displayText = getDisplayValue(matchedItem);
            console.log("✅ 초기값 표시 텍스트 로드 성공:", {
              currentValue,
              displayText,
              matchedItem,
            });

            setSelectedData(matchedItem);
            setInputValue(displayText);
            selectedDataRef.current = matchedItem;
            inputValueRef.current = displayText;
            initialValueLoadedRef.current = currentValue;
          }
        }
      } catch (error) {
        console.error("❌ 초기값 표시 텍스트 로드 실패:", error);
      }
    };

    loadInitialDisplayValue();
  }, [currentValue, tableName, valueField, displayFields, filterCondition, searchFields, selectedData]);

  // value가 변경되면 표시값 업데이트 - 단, selectedData가 있으면 유지
  useEffect(() => {
    // selectedData가 있으면 표시값 유지 (사용자가 방금 선택한 경우)
    if (selectedData || selectedDataRef.current) {
      return;
    }

    if (!currentValue) {
      setInputValue("");
      initialValueLoadedRef.current = null; // 값이 없어지면 초기화
    }
  }, [currentValue, selectedData]);

  // 외부 클릭 감지
  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (containerRef.current && !containerRef.current.contains(event.target as Node)) {
        setIsOpen(false);
      }
    };

    document.addEventListener("mousedown", handleClickOutside);
    return () => document.removeEventListener("mousedown", handleClickOutside);
  }, []);

  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const newValue = e.target.value;
    setInputValue(newValue);
    setSearchText(newValue);
    setIsOpen(true);
  };

  const handleSelect = (item: EntitySearchResult) => {
    setSelectedData(item);
    setInputValue(getDisplayValue(item));

    console.log("🔍 AutocompleteSearchInput handleSelect:", {
      item,
      valueField,
      value: item[valueField],
      config,
      isInteractive,
      hasOnFormDataChange: !!onFormDataChange,
      columnName: component?.columnName,
    });

    // isInteractive 모드에서만 저장
    if (isInteractive && onFormDataChange) {
      // 필드 매핑 처리
      if (config?.fieldMappings && Array.isArray(config.fieldMappings)) {
        console.log("📋 필드 매핑 처리 시작:", config.fieldMappings);

        config.fieldMappings.forEach((mapping: any, index: number) => {
          const targetField = mapping.targetField || mapping.targetColumn;

          console.log(`  매핑 ${index + 1}:`, {
            sourceField: mapping.sourceField,
            targetField,
            label: mapping.label,
          });

          if (mapping.sourceField && targetField) {
            const sourceValue = item[mapping.sourceField];

            console.log(`    값: ${mapping.sourceField} = ${sourceValue}`);

            if (sourceValue !== undefined) {
              console.log(`    ✅ 저장: ${targetField} = ${sourceValue}`);
              onFormDataChange(targetField, sourceValue);
            } else {
              console.warn(`    ⚠️ sourceField "${mapping.sourceField}"의 값이 undefined입니다`);
            }
          } else {
            console.warn(`    ⚠️ 매핑 불완전: sourceField=${mapping.sourceField}, targetField=${targetField}`);
          }
        });
      }

      // 기본 필드 저장 (columnName이 설정된 경우)
      if (component?.columnName) {
        console.log(`💾 기본 필드 저장: ${component.columnName} = ${item[valueField]}`);
        onFormDataChange(component.columnName, item[valueField]);
      }
    }

    // onChange 콜백 호출 (호환성)
    onChange?.(item[valueField], item);

    setIsOpen(false);
  };

  const handleClear = () => {
    setInputValue("");
    setSelectedData(null);
    onChange?.(null, null);
    setIsOpen(false);
  };

  const handleInputFocus = () => {
    // 포커스 시 항상 검색 실행 (빈 값이면 전체 목록)
    if (!selectedData) {
      setSearchText(inputValue || "");
      setIsOpen(true);
    }
  };

  return (
    <div className={cn("relative", className)} ref={containerRef}>
      {/* 입력 필드 */}
      <div className="relative">
        <Input
          value={inputValue}
          onChange={handleInputChange}
          onFocus={handleInputFocus}
          placeholder={placeholder}
          disabled={disabled}
          className="!bg-background h-8 pr-16 text-xs sm:h-10 sm:text-sm"
        />
        <div className="absolute top-1/2 right-1 flex -translate-y-1/2 items-center gap-1">
          {loading && <Loader2 className="text-muted-foreground h-4 w-4 animate-spin" />}
          {inputValue && !disabled && (
            <Button type="button" variant="ghost" size="sm" onClick={handleClear} className="h-6 w-6 p-0">
              <X className="h-3 w-3" />
            </Button>
          )}
          <ChevronDown className="text-muted-foreground h-4 w-4" />
        </div>
      </div>

      {/* 드롭다운 결과 */}
      {isOpen && (results.length > 0 || loading) && (
        <div className="bg-background absolute z-[100] mt-1 max-h-[300px] w-full overflow-y-auto rounded-md border shadow-lg">
          {loading && results.length === 0 ? (
            <div className="text-muted-foreground p-4 text-center text-sm">
              <Loader2 className="mx-auto mb-2 h-4 w-4 animate-spin" />
              검색 중...
            </div>
          ) : results.length === 0 ? (
            <div className="text-muted-foreground p-4 text-center text-sm">검색 결과가 없습니다</div>
          ) : (
            <div className="py-1">
              {results.map((item, index) => (
                <button
                  key={index}
                  type="button"
                  onClick={() => handleSelect(item)}
                  className="hover:bg-accent w-full px-3 py-2 text-left text-xs transition-colors sm:text-sm"
                >
                  <div className="font-medium">{getDisplayValue(item)}</div>
                </button>
              ))}
            </div>
          )}
        </div>
      )}
    </div>
  );
}
