import { useEffect, useState } from 'react';

// hook based off: https://typeofnan.dev/writing-a-custom-react-usedebounce-hook-with-typescript/

/**
 * Updates a value using the debounce strategy.
 * Commonly used with the useEffect hook to check when the returned 'debouncedValue' has been updated
 * @param initialValue starting value
 * @param time setTimeout delay time
 * @example
 * const [debouncedValue, setVal, val] = useDebounce<string>('intialValue', 500);
 * const func = () => setVal('newValue');
 * useEffect(() => {
 * console.log(debouncedValue);
 * }, [debouncedValue]);
 */
export const useDebounce = <T,>(
  initialValue: T,
  time: number,
): [T, React.Dispatch<T>, T] => {
  const [value, setValue] = useState<T>(initialValue);
  const [debouncedValue, setDebouncedValue] = useState<T>(initialValue);

  useEffect(() => {
    const debounce = setTimeout(() => {
      setDebouncedValue(value);
    }, time);
    // remove timeout when component is unmounted
    return () => {
      clearTimeout(debounce);
    };
  }, [value, time]);

  return [debouncedValue, setValue, value];
};
