import { useState, useCallback, useRef, useEffect } from "react";
import type { PaginatedResponse } from "@/types";

interface UsePaginatedQueryOptions<T> {
  fetchFn: (cursor?: string) => Promise<PaginatedResponse<T>>;
}

interface UsePaginatedQueryResult<T> {
  items: T[];
  loading: boolean;
  error: string | null;
  hasMore: boolean;
  loadMore: () => Promise<void>;
  refresh: () => Promise<void>;
}

/**
 * Hook for paginated list fetching with infinite scroll support.
 */
export function usePaginatedQuery<T>({
  fetchFn,
}: UsePaginatedQueryOptions<T>): UsePaginatedQueryResult<T> {
  const [items, setItems] = useState<T[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [nextCursor, setNextCursor] = useState<string | null>(null);
  const loadingRef = useRef(false);

  const refresh = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const response = await fetchFn();
      setItems(response.results);
      setNextCursor(response.next);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to fetch data");
    } finally {
      setLoading(false);
    }
  }, [fetchFn]);

  const loadMore = useCallback(async () => {
    if (!nextCursor || loadingRef.current) return;
    loadingRef.current = true;
    try {
      const response = await fetchFn(nextCursor);
      setItems((prev) => [...prev, ...response.results]);
      setNextCursor(response.next);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to load more");
    } finally {
      loadingRef.current = false;
    }
  }, [nextCursor, fetchFn]);

  useEffect(() => {
    refresh();
  }, [refresh]);

  return {
    items,
    loading,
    error,
    hasMore: nextCursor !== null,
    loadMore,
    refresh,
  };
}