import { useState, useCallback } from 'react';
import { toast } from '@/hooks/use-toast';

interface RetryOptions {
  maxAttempts?: number;
  delayMs?: number;
  exponentialBackoff?: boolean;
  onProgress?: (attempt: number, maxAttempts: number) => void;
}

export function useRetryProgress() {
  const [isRetrying, setIsRetrying] = useState(false);
  const [currentAttempt, setCurrentAttempt] = useState(0);
  const [abortController, setAbortController] = useState<AbortController | null>(null);

  const retryWithProgress = useCallback(
    async <T,>(
      operation: () => Promise<T>,
      options: RetryOptions = {}
    ): Promise<T> => {
      const {
        maxAttempts = 3,
        delayMs = 1000,
        exponentialBackoff = true,
        onProgress,
      } = options;

      setIsRetrying(true);
      const controller = new AbortController();
      setAbortController(controller);

      let lastError: Error | null = null;
      let toastId: string | undefined;

      for (let attempt = 1; attempt <= maxAttempts; attempt++) {
        if (controller.signal.aborted) {
          throw new Error('Operation cancelled');
        }

        setCurrentAttempt(attempt);
        onProgress?.(attempt, maxAttempts);

        // Show progress toast
        if (attempt > 1) {
          const delay = exponentialBackoff ? delayMs * Math.pow(2, attempt - 2) : delayMs;
          const countdown = Math.ceil(delay / 1000);

          toast({
            title: `Retrying (${attempt}/${maxAttempts})`,
            description: `Waiting ${countdown}s before retry...`,
            duration: delay,
          });

          await new Promise(resolve => setTimeout(resolve, delay));
        }

        try {
          const result = await operation();
          
          setIsRetrying(false);
          setCurrentAttempt(0);
          setAbortController(null);

          // Show success toast
          toast({
            title: "Success",
            description: attempt > 1 
              ? `Operation succeeded on attempt ${attempt}`
              : 'Operation completed successfully',
            duration: 3000,
          });

          return result;
        } catch (error) {
          lastError = error instanceof Error ? error : new Error(String(error));
          
          if (attempt < maxAttempts) {
            toast({
              title: `Attempt ${attempt} Failed`,
              description: `${lastError.message}. Retrying...`,
              duration: 2000,
            });
          }
        }
      }

      // All attempts failed
      setIsRetrying(false);
      setCurrentAttempt(0);
      setAbortController(null);

      toast({
        variant: 'destructive',
        title: "All Retries Failed",
        description: `Failed after ${maxAttempts} attempts: ${lastError?.message}`,
        duration: 5000,
      });

      throw lastError;
    },
    []
  );

  const cancel = useCallback(() => {
    if (abortController) {
      abortController.abort();
      setAbortController(null);
      setIsRetrying(false);
      setCurrentAttempt(0);

      toast({
        title: 'Cancelled',
        description: 'Retry operation cancelled',
        duration: 2000,
      });
    }
  }, [abortController]);

  return {
    retryWithProgress,
    isRetrying,
    currentAttempt,
    cancel,
  };
}
