import { useCallback, useRef, useEffect } from 'react';
import { useTabVisibility } from './useTabVisibility';

/**
 * Edge 3.3: Hook to manage long-running operations that should continue when tab is hidden
 * Ensures operations continue correctly when tab is switched or becomes hidden
 *
 * @param operation - The long-running operation function
 * @param options - Configuration options
 * @returns Object with operation control functions
 *
 * @example
 * ```typescript
 * const { start, stop, isRunning } = useLongRunningOperation(
 *   async () => {
 *     await processLargeFile();
 *   },
 *   {
 *     continueWhenHidden: true,
 *     onComplete: () => console.log('Done'),
 *     onError: (error) => console.error(error),
 *   }
 * );
 *
 * // Start operation
 * start();
 * ```
 */
export function useLongRunningOperation<T = void>(
  operation: () => Promise<T>,
  options: {
    continueWhenHidden?: boolean; // Continue operation when tab is hidden (default: true)
    onComplete?: (result: T) => void;
    onError?: (error: Error) => void;
    onStart?: () => void;
    onStop?: () => void;
  } = {},
) {
  const {
    continueWhenHidden = true,
    onComplete,
    onError,
    onStart,
    onStop,
  } = options;

  const isRunningRef = useRef(false);
  const abortControllerRef = useRef<AbortController | null>(null);
  const { isVisible } = useTabVisibility();

  /**
   * Start the long-running operation
   */
  const start = useCallback(async () => {
    // Edge 3.3: Don't start if already running
    if (isRunningRef.current) {
      return;
    }

    // Edge 3.3: Don't start if tab is hidden and continueWhenHidden is false
    if (!isVisible && !continueWhenHidden) {
      return;
    }

    isRunningRef.current = true;
    abortControllerRef.current = new AbortController();
    onStart?.();

    try {
      const result = await operation();
      onComplete?.(result);
      return result;
    } catch (error) {
      // Edge 3.3: Only handle error if not aborted
      if (error instanceof Error && error.name !== 'AbortError') {
        onError?.(error);
      }
      throw error;
    } finally {
      isRunningRef.current = false;
      abortControllerRef.current = null;
    }
  }, [operation, isVisible, continueWhenHidden, onComplete, onError, onStart]);

  /**
   * Stop the long-running operation
   */
  const stop = useCallback(() => {
    if (abortControllerRef.current) {
      abortControllerRef.current.abort();
      abortControllerRef.current = null;
    }
    isRunningRef.current = false;
    onStop?.();
  }, [onStop]);

  /**
   * Check if operation is currently running
   */
  const isRunning = useCallback(() => {
    return isRunningRef.current;
  }, []);

  // Edge 3.3: Cleanup on unmount
  useEffect(() => {
    return () => {
      stop();
    };
  }, [stop]);

  return {
    start,
    stop,
    isRunning,
  };
}
