import { useState, useEffect, useRef, useCallback } from 'react';

/**
 * useTimeout
 *
 * @param {Function} cb - callback function inside setTimeout
 * @param {number} delay - delay in ms
 * @param {boolean} [immediate] - determines whether the timeout is invoked immediately
 *
 * @return {Function|undefined}
 */
export function useTimeout(cb, delay, immediate = true) {
  const saveCb = useRef();
  const [timeoutId, setTimeoutId] = useState(null);

  useEffect(() => {
    saveCb.current = cb;
  }, [cb]);

  useEffect(() => {
    if (timeoutId !== 'start') {
      return undefined;
    }

    const id = setTimeout(() => {
      saveCb.current();
    }, delay);

    setTimeoutId(id);

    return () => {
      clearTimeout(timeoutId);
    };
  }, [delay, timeoutId]);

  const startTimeout = useCallback(() => {
    clearTimeout(timeoutId);
    setTimeoutId('start');
  }, [timeoutId]);

  if (immediate) {
    startTimeout();
  }

  return startTimeout;
}