import { useRef, useEffect, useCallback } from 'react';
import useIsVisible from "../useIsVisible/index.js";
const useScrollPercentCallback = function useScrollPercentCallback(opts = {}) {
  const defaultRef = useRef();
  const {
    ref = defaultRef,
    callback,
    dependencies = [],
    speed = 50,
    fps = 60
  } = opts;
  const cb = useCallback(callback, [...dependencies]);
  const {
    isVisible
  } = useIsVisible({
    ref
  });
  useEffect(() => {
    // Animation state variables
    let targetScrollPct = 0;
    let currentScrollPct = targetScrollPct;
    let animationStart;
    let timer;
    if (!ref.current || !isVisible) return undefined;
    const handleScroll = () => {
      const {
        innerHeight
      } = window;
      const {
        top,
        height
      } = ref.current.getBoundingClientRect();
      const start = 0;
      const end = -1 * height + innerHeight;
      const distance = end - start;
      const t = (top - start) / distance;
      const pct = Math.max(0, Math.min(1, t));
      targetScrollPct = pct;
    };
    const handleMove = ts => {
      if (animationStart === undefined) {
        animationStart = ts;
      }
      if (ts - animationStart < 1000 / fps) {
        timer = window.requestAnimationFrame(handleMove);
        return;
      }
      const dt = ts - animationStart;
      animationStart = ts;
      currentScrollPct += (targetScrollPct - currentScrollPct) * (1 - Math.exp(-1 * dt * speed));
      cb(currentScrollPct);
      if (currentScrollPct !== targetScrollPct) {
        timer = window.requestAnimationFrame(handleMove);
      }
    };

    // Update the `targetScrollPct` as the user scrolls
    handleScroll();
    window.addEventListener('scroll', handleScroll, {
      passive: true
    });

    // Animate towards the current target
    timer = window.requestAnimationFrame(handleMove);
    return () => {
      window.removeEventListener('scroll', handleScroll);
      window.cancelAnimationFrame(timer);
    };
  }, [cb, isVisible, fps]);
  return ref;
};
export default useScrollPercentCallback;