'use client';

import { useEffect, useMemo, useState } from 'react';

import { CREATOR_SEARCH_MIN_QUERY_LENGTH } from '@/components/creators/creatorSearchConfig';

export type CreatorSearchListItem = {
  id?: number;
  alkotoAzonosito?: string;
  nev?: string | null;
  szakma?: string | null;
  profilkep?: { key?: string | null } | null;
  hasCoords?: boolean;
  [key: string]: unknown;
};

interface UseCreatorSearchOptions<TItem> {
  query: string;
  enabled?: boolean;
  minQueryLength?: number;
  debounceMs?: number;
  endpoint?: string;
  transformResults?: (items: CreatorSearchListItem[]) => TItem[];
  onError?: (error: unknown) => void;
}

interface UseCreatorSearchResult<TItem> {
  results: TItem[];
  loading: boolean;
  trimmedQuery: string;
  isQueryTooShort: boolean;
}

export const useCreatorSearch = <TItem = CreatorSearchListItem>({
  query,
  enabled = true,
  minQueryLength = CREATOR_SEARCH_MIN_QUERY_LENGTH,
  debounceMs = 250,
  endpoint = '/api/get-creator-list',
  transformResults,
  onError,
}: UseCreatorSearchOptions<TItem>): UseCreatorSearchResult<TItem> => {
  const [results, setResults] = useState<TItem[]>([]);
  const [loading, setLoading] = useState(false);

  const trimmedQuery = useMemo(() => query.trim(), [query]);
  const isQueryTooShort = trimmedQuery.length < minQueryLength;

  useEffect(() => {
    if (!enabled || isQueryTooShort) {
      setResults([]);
      setLoading(false);
      return;
    }

    const controller = new AbortController();
    const timeout = window.setTimeout(async () => {
      try {
        setLoading(true);
        const response = await fetch(`${endpoint}?q=${encodeURIComponent(trimmedQuery)}`, {
          signal: controller.signal,
        });

        if (!response.ok) {
          setResults([]);
          return;
        }

        const payload = await response.json();
        const list = Array.isArray(payload) ? (payload as CreatorSearchListItem[]) : [];
        const nextResults = transformResults
          ? transformResults(list)
          : (list as unknown as TItem[]);

        setResults(nextResults);
      } catch (error) {
        if ((error as { name?: string })?.name === 'AbortError') return;

        setResults([]);
        onError?.(error);
      } finally {
        setLoading(false);
      }
    }, debounceMs);

    return () => {
      controller.abort();
      window.clearTimeout(timeout);
    };
  }, [debounceMs, enabled, endpoint, isQueryTooShort, onError, transformResults, trimmedQuery]);

  return {
    results,
    loading,
    trimmedQuery,
    isQueryTooShort,
  };
};
