import React, {
  createContext,
  useContext,
  useEffect,
  useRef,
  useState,
  useCallback,
} from "react";
import { getAutoComplete, AutoCompleteItem } from "@/apis/autoCompleteApi";

type DiscoveryContextType = {
  query: string;
  setQuery: (q: string) => void;
  suggestions: AutoCompleteItem[];
  loading: boolean;
  error: string | null;
  clear: () => void;
};

const DiscoveryContext = createContext<DiscoveryContextType | null>(null);

export const DiscoveryProvider = ({
  children,
}: {
  children: React.ReactNode;
}) => {
  const [query, setQuery] = useState("");
  const [suggestions, setSuggestions] = useState<AutoCompleteItem[]>([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const abortRef = useRef<AbortController | null>(null);
  const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);
  const cacheRef = useRef<Record<string, AutoCompleteItem[]>>({});

  const fetchSuggestions = useCallback((q: string) => {
    if (abortRef.current) abortRef.current.abort();
    if (!q.trim()) {
      setSuggestions([]);
      setLoading(false);
      return;
    }
    const cached = cacheRef.current[q];
    if (cached) {
      setSuggestions(cached);
      setLoading(false);
      return;
    }
    const controller = new AbortController();
    abortRef.current = controller;
    setLoading(true);
    setError(null);
    getAutoComplete(q, 10, controller.signal)
      .then((items) => {
        cacheRef.current[q] = items;
        setSuggestions(items);
      })
      .catch((e) => {
        if (controller.signal.aborted) return;
        setError(e.message || "Fehler");
      })
      .finally(() => {
        if (!controller.signal.aborted) setLoading(false);
      });
  }, []);

  useEffect(() => {
    if (debounceRef.current) clearTimeout(debounceRef.current);
    debounceRef.current = setTimeout(() => fetchSuggestions(query), 300);
    return () => {
      if (debounceRef.current) clearTimeout(debounceRef.current);
    };
  }, [query, fetchSuggestions]);

  const clear = () => {
    setQuery("");
    setSuggestions([]);
    setError(null);
  };

  return (
    <DiscoveryContext.Provider
      value={{ query, setQuery, suggestions, loading, error, clear }}
    >
      {children}
    </DiscoveryContext.Provider>
  );
};

export const useDiscoveryContext = () => {
  const ctx = useContext(DiscoveryContext);
  if (!ctx)
    throw new Error(
      "useDiscoveryContext must be used within DiscoveryProvider"
    );
  return ctx;
};
