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

export type RefreshInterval = 'off' | '5s' | '10s' | '30s' | '1m' | '5m';

export interface UseRefreshIntervalOptions {
  /** Initial interval (default: 'off') */
  initialInterval?: RefreshInterval;
  /** Callback function to execute on each refresh */
  onRefresh: () => void | Promise<void>;
  /** Whether the refresh is currently enabled */
  enabled?: boolean;
}

export interface UseRefreshIntervalReturn {
  /** Current interval setting */
  interval: RefreshInterval;
  /** Set the refresh interval */
  setInterval: (interval: RefreshInterval) => void;
  /** Time until next refresh in seconds (null if off) */
  timeUntilRefresh: number | null;
  /** Whether a refresh is currently in progress */
  isRefreshing: boolean;
  /** Manually trigger a refresh */
  refresh: () => Promise<void>;
  /** Pause the interval */
  pause: () => void;
  /** Resume the interval */
  resume: () => void;
  /** Whether the interval is paused */
  isPaused: boolean;
}

function getIntervalMs(interval: RefreshInterval): number | null {
  switch (interval) {
    case '5s':
      return 5000;
    case '10s':
      return 10000;
    case '30s':
      return 30000;
    case '1m':
      return 60000;
    case '5m':
      return 300000;
    case 'off':
    default:
      return null;
  }
}

/**
 * Hook for managing auto-refresh intervals in dashboards
 */
export function useRefreshInterval(options: UseRefreshIntervalOptions): UseRefreshIntervalReturn {
  const { initialInterval = 'off', onRefresh, enabled = true } = options;

  const [interval, setIntervalState] = useState<RefreshInterval>(initialInterval);
  const [timeUntilRefresh, setTimeUntilRefresh] = useState<number | null>(null);
  const [isRefreshing, setIsRefreshing] = useState(false);
  const [isPaused, setIsPaused] = useState(false);

  const onRefreshRef = useRef(onRefresh);
  const intervalIdRef = useRef<ReturnType<typeof setInterval> | null>(null);
  const countdownIdRef = useRef<ReturnType<typeof setInterval> | null>(null);

  // Update ref when onRefresh changes
  useEffect(() => {
    onRefreshRef.current = onRefresh;
  }, [onRefresh]);

  const refresh = useCallback(async () => {
    if (isRefreshing) return;

    setIsRefreshing(true);
    try {
      await onRefreshRef.current();
    } finally {
      setIsRefreshing(false);
    }
  }, [isRefreshing]);

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

  const startIntervals = useCallback(() => {
    const ms = getIntervalMs(interval);
    if (!ms || !enabled || isPaused) {
      setTimeUntilRefresh(null);
      return;
    }

    // Set initial countdown
    setTimeUntilRefresh(Math.floor(ms / 1000));

    // Start countdown timer (updates every second)
    countdownIdRef.current = setInterval(() => {
      setTimeUntilRefresh((prev) => {
        if (prev === null || prev <= 1) {
          return Math.floor(ms / 1000);
        }
        return prev - 1;
      });
    }, 1000);

    // Start refresh interval
    intervalIdRef.current = setInterval(() => {
      refresh();
    }, ms);
  }, [interval, enabled, isPaused, refresh]);

  // Set up intervals when settings change
  useEffect(() => {
    clearIntervals();
    startIntervals();

    return () => {
      clearIntervals();
    };
  }, [clearIntervals, startIntervals]);

  const setInterval = useCallback((newInterval: RefreshInterval) => {
    setIntervalState(newInterval);
  }, []);

  const pause = useCallback(() => {
    setIsPaused(true);
    clearIntervals();
    setTimeUntilRefresh(null);
  }, [clearIntervals]);

  const resume = useCallback(() => {
    setIsPaused(false);
  }, []);

  return {
    interval,
    setInterval,
    timeUntilRefresh,
    isRefreshing,
    refresh,
    pause,
    resume,
    isPaused,
  };
}
