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

interface UseRefreshIntervalOptions {
  /** Interval in milliseconds (0 to disable) */
  interval: number;
  /** Callback to execute on each interval */
  onRefresh: () => void | Promise<void>;
  /** Whether to start paused */
  startPaused?: boolean;
  /** Whether to run immediately on mount */
  immediate?: boolean;
}

interface UseRefreshIntervalReturn {
  /** Whether the interval is currently active */
  isActive: boolean;
  /** Pause the interval */
  pause: () => void;
  /** Resume the interval */
  resume: () => void;
  /** Manually trigger a refresh */
  refresh: () => void;
  /** Time until next refresh in ms */
  timeUntilRefresh: number;
}

export function useRefreshInterval(
  options: UseRefreshIntervalOptions
): UseRefreshIntervalReturn {
  const { interval, onRefresh, startPaused = false, immediate = true } = options;

  const [isActive, setIsActive] = useState(!startPaused && interval > 0);
  const [timeUntilRefresh, setTimeUntilRefresh] = useState(interval);
  const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);
  const countdownRef = useRef<ReturnType<typeof setInterval> | null>(null);
  const onRefreshRef = useRef(onRefresh);

  // Keep callback ref up to date
  useEffect(() => {
    onRefreshRef.current = onRefresh;
  }, [onRefresh]);

  const clearIntervals = useCallback(() => {
    if (intervalRef.current) {
      clearInterval(intervalRef.current);
      intervalRef.current = null;
    }
    if (countdownRef.current) {
      clearInterval(countdownRef.current);
      countdownRef.current = null;
    }
  }, []);

  const startIntervals = useCallback(() => {
    clearIntervals();

    if (interval <= 0) return;

    setTimeUntilRefresh(interval);

    intervalRef.current = setInterval(() => {
      onRefreshRef.current();
      setTimeUntilRefresh(interval);
    }, interval);

    countdownRef.current = setInterval(() => {
      setTimeUntilRefresh((prev) => Math.max(0, prev - 1000));
    }, 1000);
  }, [interval, clearIntervals]);

  const pause = useCallback(() => {
    setIsActive(false);
    clearIntervals();
  }, [clearIntervals]);

  const resume = useCallback(() => {
    if (interval > 0) {
      setIsActive(true);
      startIntervals();
    }
  }, [interval, startIntervals]);

  const refresh = useCallback(() => {
    onRefreshRef.current();
    if (isActive) {
      startIntervals();
    }
  }, [isActive, startIntervals]);

  // Initial setup
  useEffect(() => {
    if (immediate) {
      onRefreshRef.current();
    }

    if (!startPaused && interval > 0) {
      startIntervals();
    }

    return clearIntervals;
  }, [immediate, startPaused, interval, startIntervals, clearIntervals]);

  // Handle interval changes
  useEffect(() => {
    if (isActive && interval > 0) {
      startIntervals();
    } else if (interval <= 0) {
      clearIntervals();
      setIsActive(false);
    }
  }, [interval, isActive, startIntervals, clearIntervals]);

  return {
    isActive,
    pause,
    resume,
    refresh,
    timeUntilRefresh,
  };
}
