import { useState, useEffect, useCallback, useRef } from 'react';

interface UseSearchableDataOptions<T> {
  open: boolean;
  fetchData: (query: string) => Promise<T[]>;
  searchMode: 'debounce' | 'enter';
  debounceDelay: number;
  validateSearch?: (query: string) => boolean;
  loadOnOpen: boolean;
}

interface UseSearchableDataReturn<T> {
  searchQuery: string;
  setSearchQuery: (query: string) => void;
  items: T[];
  isLoading: boolean;
  error: string | null;
  triggerSearch: () => void;
  handleSearchKeyDown: (e: React.KeyboardEvent) => void;
}

export function useSearchableData<T>({
  open,
  fetchData,
  searchMode,
  debounceDelay,
  validateSearch,
  loadOnOpen,
}: UseSearchableDataOptions<T>): UseSearchableDataReturn<T> {
  const [searchQuery, setSearchQuery] = useState('');
  const [items, setItems] = useState<T[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const prevOpenRef = useRef(false);

  // 실제 API 호출
  const doFetch = useCallback(async (query: string) => {
    setIsLoading(true);
    setError(null);
    try {
      const data = await fetchData(query);
      setItems(data);
    } catch (err) {
      console.error('[useSearchableData] fetch error:', err);
      setError('데이터를 불러오는데 실패했습니다.');
      setItems([]);
    } finally {
      setIsLoading(false);
    }
  }, [fetchData]);

  // 모달 열릴 때 초기화 + loadOnOpen
  useEffect(() => {
    if (open && !prevOpenRef.current) {
      // 방금 열림
      setSearchQuery('');
      setError(null);
      if (loadOnOpen) {
        doFetch('');
      } else {
        setItems([]);
      }
    }
    if (!open && prevOpenRef.current) {
      // 방금 닫힘
      setItems([]);
      setSearchQuery('');
      setError(null);
    }
    prevOpenRef.current = open;
  }, [open, loadOnOpen, doFetch]);

  // 디바운스 모드: 검색어 변경 시 자동 검색
  useEffect(() => {
    if (!open || searchMode !== 'debounce') return;

    // 검색어가 비어있고 loadOnOpen이면 이미 로드됨 → 스킵
    if (!searchQuery && loadOnOpen) return;

    // 검색어가 비어있고 loadOnOpen이 아니면 → 결과 초기화
    if (!searchQuery && !loadOnOpen) {
      setItems([]);
      return;
    }

    // 유효성 검사
    if (validateSearch && !validateSearch(searchQuery)) {
      setItems([]);
      return;
    }

    const timer = setTimeout(() => {
      doFetch(searchQuery);
    }, debounceDelay);

    return () => clearTimeout(timer);
  }, [searchQuery, open, searchMode, debounceDelay, validateSearch, doFetch, loadOnOpen]);

  // 수동 검색 트리거 (enter 모드)
  const triggerSearch = useCallback(() => {
    doFetch(searchQuery);
  }, [searchQuery, doFetch]);

  const handleSearchKeyDown = useCallback((e: React.KeyboardEvent) => {
    if (e.key === 'Enter') {
      triggerSearch();
    }
  }, [triggerSearch]);

  return {
    searchQuery,
    setSearchQuery,
    items,
    isLoading,
    error,
    triggerSearch,
    handleSearchKeyDown,
  };
}
