import { Fragment, type ReactNode, useEffect } from 'react';
import { useInView } from 'react-intersection-observer';

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

import SurveyListSkeleton from './SurveyListSkeleton';

type SurveyListProps<T> = {
  items: T[];
  isLoading: boolean;
  isFetchingNextPage: boolean;
  hasNextPage: boolean | undefined;
  fetchNextPage: () => void;
  renderItem: (item: T) => ReactNode;
  keyExtractor: (item: T) => string | number;
};

const SurveyList = <T,>({
  items,
  isLoading,
  isFetchingNextPage,
  hasNextPage,
  fetchNextPage,
  renderItem,
  keyExtractor,
}: SurveyListProps<T>) => {
  const [ref, inView] = useInView({ threshold: 0 });

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

  if (isLoading) {
    return <SurveyListSkeleton />;
  }

  return (
    <Stack sx={{ gap: 2 }}>
      {items.map((item, index) => {
        const isLast = index === items.length - 1;
        return (
          <Fragment key={keyExtractor(item)}>
            {renderItem(item)}
            {isLast && hasNextPage && (
              <Box
                ref={ref}
                sx={{ height: '1px' }}
              />
            )}
          </Fragment>
        );
      })}
      {isFetchingNextPage && <SurveyListSkeleton />}
    </Stack>
  );
};

export default SurveyList;
