import { useRef, useEffect, useMemo } from 'react';
import { debounce } from 'lodash';

/**
 * Hook that creates a stable debounced callback with fresh closure access.
 * Solves the problem of debounce recreation when dependencies change.
 *
 * Pattern: useRef stores latest callback, useMemo creates debounce once.
 * Source: https://www.developerway.com/posts/debouncing-in-react
 *
 * @param {Function} callback - The callback to debounce
 * @param {number} delay - Debounce delay in ms (default: 500)
 * @returns {Function} Debounced function that always uses latest callback
 */
export const useDebounceCallback = (callback, delay = 500) => {
  const callbackRef = useRef(callback);

  // Always keep ref current with latest callback
  useEffect(() => {
    callbackRef.current = callback;
  }, [callback]);

  // Create debounced function once - never recreated
  const debouncedFn = useMemo(
    () =>
      debounce((...args) => {
        if (callbackRef.current) {
          callbackRef.current(...args);
        }
      }, delay),
    [delay] // Only recreate if delay changes
  );

  // Cleanup on unmount
  useEffect(() => {
    return () => debouncedFn.cancel();
  }, [debouncedFn]);

  return debouncedFn;
};

export default useDebounceCallback;
