/**
 * @deprecated Use `InfiniteListLoader` from `@material-hu/components/composed-components/InfiniteListLoader`
 * (IntersectionObserver-based load-more) or `VirtualizedList` from
 * `@material-hu/components/composed-components/VirtualizedList` (react-window, for large lists).
 * Note: `InfiniteListLoader` is already in use in some files — check before migrating each consumer.
 */
import { FC, ReactElement, ReactNode, RefObject, useEffect } from 'react';
import { useInView } from 'react-intersection-observer';
import { InfiniteQueryObserverBaseResult } from 'react-query';

import Box from '@material-hu/mui/Box';
import CircularProgress from '@material-hu/mui/CircularProgress';

import List, { ListProps } from './List';

export type InfiniteListProps = ListProps &
  Pick<
    InfiniteQueryObserverBaseResult,
    'isFetchingNextPage' | 'hasNextPage' | 'fetchNextPage'
  > & {
    withEnd?: boolean;
    children: ReactNode;
    totalPages?: number;
    isEmpty?: boolean;
    rootRef?: RefObject<Element | null>;
    renderSkeleton?: ReactElement<any, any>;
  };

const InfiniteList: FC<InfiniteListProps> = props => {
  const {
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
    children,
    isLoading,
    isEmpty,
    renderSkeleton,
    rootRef,
    ...listProps
  } = props;
  const [ref, inView] = useInView({
    threshold: 0,
    root: rootRef?.current ?? null,
    rootMargin: '200px 0px',
  });

  useEffect(() => {
    if (inView && hasNextPage && !isEmpty && !isFetchingNextPage) {
      fetchNextPage();
    }
  }, [inView, hasNextPage, isEmpty, isFetchingNextPage, fetchNextPage]);

  return (
    <List
      isLoading={isLoading}
      isEmpty={isEmpty}
      {...listProps}
    >
      {children}
      {!isLoading && (
        <Box
          sx={{ height: '2px' }}
          className="loadingMoreRef"
          ref={ref}
        />
      )}
      {isFetchingNextPage &&
        (renderSkeleton || (
          <Box sx={{ textAlign: 'center', my: 1 }}>
            <CircularProgress />
          </Box>
        ))}
    </List>
  );
};

export default InfiniteList;
