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

/**
 * High-performance hook for watching rapidly changing values.
 *
 * This hook:
 * - Calls getValue() in useAnimationFrame to check for changes
 * - Maintains both localValue (state) and localValueRef (ref)
 * - Only triggers a re-render when the value actually changes
 * - Ideal for values that update at screen refresh rate (e.g., knob positions, EQ dots)
 *
 * @param getValue - Function that returns the current value
 * @param enabled - Whether to poll for changes (default: true)
 * @returns The current value (state) that triggers re-renders on change
 */
export function useRealtimeValue<T>(
  getValue: () => T,
  enabled: boolean = true
): T {
  const localValueRef = useRef<T>(getValue());
  const [localValue, setLocalValue] = useState<T>(localValueRef.current);

  useEffect(() => {
    if (!enabled) return;

    let rafId: number;

    const update = () => {
      const newValue = getValue();

      // Only update if value has changed
      // Use simple equality check - for objects, consumer should ensure
      // stable references or use a custom comparison
      if (newValue !== localValueRef.current) {
        localValueRef.current = newValue;
        setLocalValue(newValue);
      }

      rafId = requestAnimationFrame(update);
    };

    update();

    return () => {
      cancelAnimationFrame(rafId);
    };
  }, [getValue, enabled]);

  return localValue;
}
