import {
  useEffect, useLayoutEffect, useRef, useCallback,
} from 'react';
import invariant from 'tiny-invariant';
import memoize from 'memoize-one';
import { maxScrollTop } from './util';

// eslint-disable-next-line no-param-reassign
const defaultRunScroll = memoize((domRef) => (offset) => { domRef.current.scrollTop = offset; });
const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;

export default (domRef, {
  initialScroll = null,
  inaccuracy = 0,
  runScroll = defaultRunScroll(domRef),
} = {}) => {
  const wasScrolled = useRef(null);

  const isScrolled = useCallback(
    () => Math.ceil(domRef.current.scrollTop) >= maxScrollTop(domRef.current) - inaccuracy,
    [inaccuracy],
  );

  useEffect(() => {
    const ref = domRef.current;
    const onScroll = () => { wasScrolled.current = isScrolled(); };
    
    ref.addEventListener('scroll', onScroll);
    
    return () => { ref.removeEventListener('scroll', onScroll); };
  }, []);

  const scroll = useCallback((position) => {
    invariant(domRef.current !== null, `Trying to scroll to the bottom, but no element was found.
      Did you call this scrollBottom before the component with this hook finished mounting?`);

    const offset = Math.min(maxScrollTop(domRef.current), position);
    runScroll(offset);
  }, [runScroll]);

  const scrollBottom = useCallback(() => {
    scroll(Infinity);
  }, [scroll]);

  const stayScrolled = useCallback(() => {
    if (wasScrolled.current) scrollBottom();

    return wasScrolled.current;
  }, [scrollBottom]);

  useIsomorphicLayoutEffect(() => {
    if (initialScroll !== null) {
      scroll(initialScroll);
    }

    wasScrolled.current = isScrolled();
  }, []);

  return {
    scroll,
    stayScrolled,
    scrollBottom,
    isScrolled,
  };
};

@@ -756,40 +756,8 @@
 %3E %7B%0A
-    const ref = domRef.current;%0A
     
@@ -820,20 +820,16 @@
 d(); %7D;%0A
-    
 %0A    ref
@@ -871,16 +871,86 @@
 l);%0A    
+// in react 17 the cleanup can happen after the element gets unmounted
 %0A    ret
@@ -963,13 +963,23 @@
  =%3E 
-%7B ref
+domRef.current?
 .rem
@@ -1015,19 +1015,16 @@
 Scroll);
- %7D;
 %0A  %7D, %5B%5D

Update fix