import { useEffect, useState } from 'react';
import throttle from 'lodash/throttle';

/**
 * @name useCheckoutLoader
 * @description We use the "effect" hook to add/remove an "emitter" instance
 * to our Modal component. By passing the "setter" from our React State we
 * can get a live subscription to the state
 */
const useScrollDirection = () => {
  const threshhold = 30;
  const triggerBottom = 100;
  const triggerTop = 100;
  const triggerDistance = 150;

  const [bottom, setBottom] = useState(false);
  const [direction, setDirection] = useState(false);
  const [position, setPosition] = useState(0);
  const [top, setTop] = useState(false);

  const onScroll = (_event: any) => {
    const root = document.documentElement;
    const { clientHeight, scrollTop, scrollHeight } = root;

    const remainder = scrollHeight - clientHeight - scrollTop;
    const isBottom = remainder <= triggerBottom;
    const isTop = scrollTop <= threshhold;
    const isSignificant = Math.abs(scrollTop - position) > triggerDistance;

    const nearBottom = remainder <= triggerBottom;
    const nearTop = scrollTop <= triggerTop;
    const isException = nearBottom || nearTop;

    if (isException) {
      if (nearTop && !top) {
        setBottom(false);
        setTop(true);
      } else if (nearBottom && !bottom) {
        setBottom(true);
        setTop(false);
      }

      return;
    }

    // Required travel distance
    if (isSignificant) {
      const isDownward = scrollTop > position;

      // Edge-cases
      if (top !== isTop) setTop(isTop);
      else if (bottom !== isBottom) setBottom(isBottom);

      // Account for negative scrolling (mobile)
      setPosition(scrollTop <= 0 ? 0 : scrollTop);
      setDirection(isDownward);
    }
  };

  const throttledResize = throttle(onScroll, 100, {
    leading: true,
    trailing: true
  });

  useEffect(() => {
    window.addEventListener('scroll', throttledResize);

    return () => {
      window.removeEventListener('scroll', throttledResize);
    };
  });

  return {
    bottom,
    direction,
    position,
    top
  };
};

export { useScrollDirection };
