import { useEffect, useRef } from 'react';
import useResizeObserver from "../../../hooks/useResizeObserver/index.js";
const useTickerScrollAnimation = opts => {
  const {
    disableScroll = false,
    duration = 20000
  } = opts;
  const scroll = useRef();
  const animationRef = useRef();
  const headerRef = useRef();
  const [scrollRef, [width]] = useResizeObserver({
    ref: scroll
  });

  // set up animation
  useEffect(() => {
    if (!animationRef.current) return undefined;
    const {
      x: initialX,
      width: contentWidth
    } = animationRef.current.getBoundingClientRect();
    const animationDistance = contentWidth - width;
    if (animationDistance < 0) return undefined;
    const timing = {
      duration: animationDistance / 20 * 1000,
      delay: 0,
      iterations: Infinity,
      fill: 'forwards'
    };
    const keyframes = [{
      transform: 'translateX(0px)',
      easing: 'linear',
      offset: 0
    }, {
      /**
       * Set our final keyframe so that we scroll the full width of the
       * scrollable content minus the width of the scroll container. This
       * will end up with the right edge of the content aligning with the
       * right edge of the container.
       */
      transform: `translateX(calc(-100% + ${width}px))`,
      easing: 'linear',
      offset: 1
    }];
    const animation = animationRef.current.animate(keyframes, timing);

    /**
     * When we hover over the scoll container (or anything causes us to want to
     * stop the animation), we get the current client bounding position of the
     * scolling content, which takes the current animated transform into
     * account, and use that to set the `scrollLeft` value of the scrolling
     * container. We pause the animation and reset its current time to 0 so
     * that there's no translation on top of the scroll.
     */
    const pauseAnimation = () => {
      const {
        x
      } = animationRef.current.getBoundingClientRect();
      scroll.current.scrollLeft = -x + initialX;
      animation.pause();
      animation.currentTime = 0;
    };

    /**
     * When we want to continue the animation, we retrieve the current
     * `scollLeft` of the scroll container to take into account any manual
     * scroling by the user, and use it to compute the percentage of possible
     * scrolling that it's done (as a function of the scollable content's
     * width and the scrollable container's width. Reset the scroll to 0 so
     * that we're starting back at a simple case and set the animation's time
     * to the scroll percentage times the duration of the animation before
     * starting the animation again.
     *
     * Note that you could also add a delay with a `setTimeout` here -- though
     * if you did that you would want to make sure to cancel the timeout if the
     * user hovers back in before the timer runs out.
     */
    const playAnimation = () => {
      const {
        scrollLeft
      } = scroll.current;
      const scrollMax = animationRef.current.offsetWidth - scroll.current.offsetWidth;
      const scrollPct = scrollLeft / scrollMax || 0;
      scroll.current.scrollLeft = 0;
      animation.currentTime = scrollPct * duration;
      animation.play();
    };

    /**
     * Using `mouseenter` and `mouseleave` to start/stop the animation, but we
     * should also consider tap on mobile. Maybe on mobile it's simpler to just
     * not restart the animation at all once we've stopped it since there's not
     * the same "hover out" concept.
     */

    if (!disableScroll) {
      scroll.current.addEventListener('mouseenter', pauseAnimation);
      scroll.current.addEventListener('touchstart', pauseAnimation);
      scroll.current.addEventListener('focus', pauseAnimation);
      scroll.current.addEventListener('mouseleave', playAnimation);
      scroll.current.addEventListener('touchend', playAnimation);
      scroll.current.addEventListener('blur', playAnimation);
    }
    return () => {
      if (!scroll.current) return;
      if (!disableScroll) {
        scroll.current.removeEventListener('mouseenter', pauseAnimation);
        scroll.current.removeEventListener('touchstart', pauseAnimation);
        scroll.current.removeEventListener('focus', pauseAnimation);
        scroll.current.removeEventListener('mouseleave', playAnimation);
        scroll.current.removeEventListener('touchend', playAnimation);
        scroll.current.removeEventListener('blur', playAnimation);
      }
    };
  }, [width, duration, disableScroll]);
  return [scrollRef, animationRef, headerRef];
};
export default useTickerScrollAnimation;