import {useCallback, useEffect, useState} from 'react';
import {addonManager} from '../api/addonManager';
import {ContentType, MetaPreview} from '../api/addonTypes';

const PAGE_SIZE = 20;

export function usePaginatedCatalog(
  addonId: string,
  type: ContentType,
  catalogId: string,
  extra?: Record<string, string>,
) {
  const [items, setItems] = useState<MetaPreview[]>([]);
  const [loading, setLoading] = useState(true);
  const [loadingMore, setLoadingMore] = useState(false);
  const [hasMore, setHasMore] = useState(true);
  const [skip, setSkip] = useState(0);

  const fetchPage = useCallback(
    async (pageSkip: number, reset: boolean) => {
      if (reset) setLoading(true);
      else setLoadingMore(true);

      try {
        const fetched = await addonManager.getCatalog(addonId, type, catalogId, {
          ...extra,
          skip: String(pageSkip),
        });

        if (reset) {
          setItems(fetched);
        } else {
          setItems(prev => {
            const ids = new Set(prev.map(i => i.id));
            return [...prev, ...fetched.filter(i => !ids.has(i.id))];
          });
        }

        setHasMore(fetched.length >= PAGE_SIZE);
        setSkip(pageSkip + PAGE_SIZE);
      } catch {
        setHasMore(false);
      } finally {
        setLoading(false);
        setLoadingMore(false);
      }
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [addonId, type, catalogId],
  );

  useEffect(() => {
    setSkip(0);
    fetchPage(0, true);
  }, [fetchPage]);

  const loadMore = useCallback(() => {
    if (!hasMore || loadingMore) return;
    fetchPage(skip, false);
  }, [hasMore, loadingMore, skip, fetchPage]);

  const refresh = useCallback(() => {
    setSkip(0);
    setHasMore(true);
    fetchPage(0, true);
  }, [fetchPage]);

  return {items, loading, loadingMore, hasMore, loadMore, refresh};
}
