import { useCallback, useRef } from 'react';

interface IUseScrollOnDragProps {
  containerRef: React.RefObject<HTMLDivElement>;
  threshold: number;
  scrollStep: number;
}

export const useScrollOnDrag = ({
  containerRef,
  threshold,
  scrollStep,
}: IUseScrollOnDragProps) => {
  const animationFrameId = useRef<number | null>(null);

  const startScrolling = useCallback(
    (clientY: number) => {
      const scroll = () => {
        if (containerRef.current) {
          const { top, bottom } = containerRef.current.getBoundingClientRect();

          const maxScrollTop =
            containerRef.current.scrollHeight -
            containerRef.current.clientHeight;
          const distanceFromTop = clientY - top;
          const distanceFromBottom = bottom - clientY;

          if (
            distanceFromTop < threshold &&
            containerRef.current.scrollTop > 0
          ) {
            containerRef.current.scrollTop -= scrollStep;
            animationFrameId.current = requestAnimationFrame(scroll);
          } else if (
            distanceFromBottom < threshold &&
            containerRef.current.scrollTop < maxScrollTop
          ) {
            containerRef.current.scrollTop += scrollStep;
            animationFrameId.current = requestAnimationFrame(scroll);
          } else {
            // Check if we are near the bottom of the container
            if (containerRef.current.scrollTop >= maxScrollTop) {
              // You can perform any action here when the scroll hits the bottom.
            } else {
              // Check if we are near the top of the container
              if (containerRef.current.scrollTop <= 0) {
                // You can perform any action here when the scroll hits the top.
              }
            }
            // Stop scrolling if neither condition is met
            stopScrolling();
          }
        }
      };

      const stopScrolling = () => {
        if (animationFrameId.current !== null) {
          cancelAnimationFrame(animationFrameId.current);
          animationFrameId.current = null;
        }
      };

      //@ts-ignore
      cancelAnimationFrame(animationFrameId.current); // Cancel any existing animation frame
      animationFrameId.current = requestAnimationFrame(scroll);
    },
    [containerRef, threshold, scrollStep]
  );

  const stopScrolling = useCallback(() => {
    if (animationFrameId.current !== null) {
      cancelAnimationFrame(animationFrameId.current);
      animationFrameId.current = null;
    }
  }, []);

  return { startScrolling, stopScrolling };
};
