import React, { useMemo } from 'react';
import { bem } from 'utils/bem';
import { Skeleton } from 'common-v2/components/skeleton';
import { SInfiniteScroll, BEM_CLASS } from './s-infinite-scroll';
import { throttle } from 'lodash';
import { THROTTLE_MS } from './constants';

interface InfiniteScrollProps {
  className?: string;
  children: React.ReactElement | React.ReactElement[];
  loader?: React.ReactElement;
  onScrollEnd(): void;
  isLoading?: boolean;
  isActive: boolean;
}

const classes = bem(BEM_CLASS);

export const InfiniteScroll = React.memo(
  React.forwardRef(
    (
      { className, children, onScrollEnd, loader, isLoading, isActive }: InfiniteScrollProps,
      ref: React.Ref<HTMLDivElement>
    ) => {
      const onScroll = useMemo(
        () =>
          throttle(
            ({ nativeEvent }: React.UIEvent<HTMLDivElement>) => {
              const { target } = nativeEvent;

              if (!isActive || isLoading || !(target instanceof HTMLDivElement)) return;

              const { offsetHeight, scrollHeight, scrollTop } = target;

              if (scrollTop > 0 && scrollTop >= scrollHeight - offsetHeight) {
                onScrollEnd();
              }
            },
            THROTTLE_MS,
            { trailing: true }
          ),
        [isActive, isLoading, onScrollEnd]
      );

      return (
        <SInfiniteScroll ref={ref} className={className} onScroll={onScroll}>
          {children}
          {isLoading && (
            <div className={classes('loader')}>
              {loader ?? (
                <Skeleton width="100%" height="25px">
                  <rect x="0" y="0" rx="2px" ry="2px" width="100%" height="25px" />
                </Skeleton>
              )}
            </div>
          )}
        </SInfiniteScroll>
      );
    }
  )
);
