import React, { Dispatch, FC, ReactNode, RefObject, SetStateAction } from 'react';
import { useColumnReverseInfiniteScroll } from '../require/react-helper';
import Retry from './retry';

export interface InfiniteScrollProps {
	infiniteScrollElementRef: RefObject<HTMLDivElement>;
	fetchRetryCallable: () => Promise<void>;
	fetchAboveCallable: () => Promise<void>;
	fetchBelowCallable: () => Promise<void>;
	setScrollRatio: Dispatch<SetStateAction<number>>;
	ends: { hasMoreAbove: boolean, hasMoreBelow: boolean } | null;
	fetchError: unknown | null;
	fetchAboveError: unknown | null;
	fetchBelowError: unknown | null;
	fetchErrorMessage: string;
	fetchAboveErrorMessage: string;
	fetchBelowErrorMessage: string;
	children: ReactNode;
}

// Implements convenient features such as 'try again' components
const InfiniteScroll: FC<InfiniteScrollProps> = (props: InfiniteScrollProps) => {
	const {
		infiniteScrollElementRef,
		fetchRetryCallable,
		fetchAboveCallable,
		fetchBelowCallable, 
		setScrollRatio,
		ends,
		fetchError,
		fetchAboveError,
		fetchBelowError,
		fetchErrorMessage,
		fetchAboveErrorMessage,
		fetchBelowErrorMessage,
		children
	} = props;

	const [
		updateScrollCallable,
		fetchAboveRetry,
		fetchBelowRetry
	] = useColumnReverseInfiniteScroll(
		600,
		ends,
		fetchAboveCallable,
		fetchBelowCallable,
		setScrollRatio
	);

	return (
		<div className="infinite-scroll-scroll-base" ref={infiniteScrollElementRef} onScroll={updateScrollCallable}>
			<div className="infinite-scroll-elements">
				<Retry error={fetchAboveError} text={fetchAboveErrorMessage} retryFunc={fetchAboveRetry} />
				{children}
				<Retry error={fetchError} text={fetchErrorMessage} retryFunc={fetchRetryCallable} />
				<Retry error={fetchBelowError} text={fetchBelowErrorMessage} retryFunc={fetchBelowRetry} />
			</div>
		</div>
	)
};

export default InfiniteScroll;

