import React, { useState, useEffect, useRef } from 'react';
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { Progress } from '@/components/ui/progress';
import { Button } from '@/components/ui/button';
import { CheckCircle, AlertCircle, Loader2 } from 'lucide-react';
import { cn } from '@/lib/utils';

type AnimationPhase = 'progressing' | 'waiting' | 'completing' | 'completed' | 'hiding';

interface ProgressModalProps {
  isOpen: boolean;
  onClose: () => void;

  // State from useCancellableGeneration hook
  isActive: boolean;
  isComplete: boolean;
  hasError: boolean;
  isCancelling: boolean;
  taskId: string | null;

  // Customization
  title: string;
  description: string;
  icon?: React.ReactNode;
  errorMessage?: string;

  // Callbacks
  onCancel?: () => void;
  onComplete?: () => void;

  // Optional operation-specific details
  currentItem?: string;
  completedCount?: number;
  totalCount?: number;
}

export const ProgressModal: React.FC<ProgressModalProps> = ({
  isOpen,
  onClose,
  isActive,
  isComplete,
  hasError,
  isCancelling,
  taskId,
  title,
  description,
  icon,
  errorMessage,
  onCancel,
  onComplete,
  currentItem,
  completedCount,
  totalCount
}) => {
  const [progress, setProgress] = useState(0);
  const [phase, setPhase] = useState<AnimationPhase>('progressing');
  const [internalComplete, setInternalComplete] = useState(false);

  const timerRef = useRef<NodeJS.Timeout | null>(null);
  const phaseTimerRef = useRef<NodeJS.Timeout | null>(null);
  const animationStartedRef = useRef(false);
  const progressRef = useRef(0);
  const stateRef = useRef({ isComplete, hasError, isCancelling });
  stateRef.current = { isComplete, hasError, isCancelling };

  // Clear all timers helper
  const clearAllTimers = () => {
    if (timerRef.current) {
      clearInterval(timerRef.current);
      timerRef.current = null;
    }
    if (phaseTimerRef.current) {
      clearTimeout(phaseTimerRef.current);
      phaseTimerRef.current = null;
    }
  };

  // Reset state when modal opens
  useEffect(() => {
    if (isOpen && isActive) {
      clearAllTimers();
      setProgress(0);
      progressRef.current = 0;
      setPhase('progressing');
      setInternalComplete(false);
      animationStartedRef.current = false;
    }
  }, [isOpen, isActive]);

  // Animate to completion from current progress
  const animateToCompletion = (fromProgress: number) => {
    clearAllTimers();
    setPhase('completing');

    // Animate quickly to 100% over 500ms
    const remainingProgress = 100 - fromProgress;
    const completionInterval = 50;
    const totalSteps = 500 / completionInterval;
    const progressPerStep = remainingProgress / totalSteps;

    let step = 0;
    timerRef.current = setInterval(() => {
      step++;
      const newProgress = fromProgress + (progressPerStep * step);

      if (newProgress >= 100 || step >= totalSteps) {
        setProgress(100);
        setPhase('completed');
        setInternalComplete(true);
        clearAllTimers();

        // Auto-dismiss after 2.5 seconds
        phaseTimerRef.current = setTimeout(() => {
          setPhase('hiding');
          setTimeout(() => {
            onComplete?.();
            onClose();
          }, 300);
        }, 2500);
      } else {
        setProgress(newProgress);
      }
    }, completionInterval);
  };

  // Main effect to handle progress animation
  useEffect(() => {
    // Only start animation once when conditions are met
    if (isOpen && isActive && phase === 'progressing' && !animationStartedRef.current) {
      animationStartedRef.current = true;

      // Start progress animation to 90% over 54 seconds
      const progressPerUpdate = 90 / 540;

      timerRef.current = setInterval(() => {
        // Check if we should stop
        if (stateRef.current.isComplete || stateRef.current.hasError || stateRef.current.isCancelling) {
          clearAllTimers();
          return;
        }

        progressRef.current += progressPerUpdate;

        if (progressRef.current >= 90) {
          setProgress(90);
          progressRef.current = 90;
          setPhase('waiting');
          clearAllTimers();
        } else {
          setProgress(progressRef.current);
        }
      }, 100);
    }

    // Cleanup only on unmount or when modal closes
    return () => {
      if (!isOpen) {
        clearAllTimers();
        animationStartedRef.current = false;
      }
    };
  }, [isOpen, isActive, phase]);

  // Handle completion
  useEffect(() => {
    if (isComplete && !internalComplete && (phase === 'progressing' || phase === 'waiting')) {
      animateToCompletion(progressRef.current);
    }
  }, [isComplete, phase, internalComplete]);

  // Handle cancellation
  useEffect(() => {
    if (isCancelling && (phase === 'progressing' || phase === 'waiting')) {
      clearAllTimers();
    }
  }, [isCancelling, phase]);

  // Handle cancellation completed (modal closes)
  useEffect(() => {
    if (!isCancelling && !isActive && isOpen && !isComplete && !hasError) {
      // Cancellation completed - close after brief delay
      setTimeout(() => {
        onClose();
      }, 1000);
    }
  }, [isCancelling, isActive, isOpen, isComplete, hasError, onClose]);

  // Cleanup on unmount
  useEffect(() => {
    return () => {
      clearAllTimers();
    };
  }, []);

  const handleCancel = () => {
    if (onCancel && !isCancelling && taskId && !taskId.startsWith('temp-')) {
      onCancel();
    }
  };

  // Prevent closing during operation
  const handleOpenChange = (open: boolean) => {
    if (!open && (internalComplete || hasError)) {
      onClose();
    }
    // Don't allow closing during active operation
  };

  const getStatusLabel = () => {
    if (isCancelling) return 'Cancelling...';
    if (hasError) return 'Operation failed';
    if (internalComplete) return 'Completed successfully!';
    if (phase === 'waiting') return 'Finalizing...';
    if (currentItem) return currentItem;
    return 'Processing...';
  };

  const getIcon = () => {
    if (hasError) return <AlertCircle className="h-5 w-5 text-red-500" />;
    if (internalComplete) return <CheckCircle className="h-5 w-5 text-green-500" />;
    if (icon) return icon;
    return <Loader2 className="h-5 w-5 text-blue-500 animate-spin" />;
  };

  const canCancel = !internalComplete && !hasError && taskId && !taskId.startsWith('temp-') && !isCancelling;

  return (
    <Dialog open={isOpen} onOpenChange={handleOpenChange}>
      <DialogContent
        className="sm:max-w-md"
        onPointerDownOutside={(e) => {
          // Prevent closing by clicking outside during operation
          if (!internalComplete && !hasError) {
            e.preventDefault();
          }
        }}
        onEscapeKeyDown={(e) => {
          // Prevent closing with Escape during operation
          if (!internalComplete && !hasError) {
            e.preventDefault();
          }
        }}
      >
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2">
            {getIcon()}
            {title}
          </DialogTitle>
          <DialogDescription>
            {description}
          </DialogDescription>
        </DialogHeader>

        <div className="space-y-4">
          {/* Progress Bar */}
          <div className="space-y-2">
            <Progress
              value={progress}
              className={cn(
                "w-full transition-all duration-200",
                hasError && "opacity-75",
                isCancelling && "opacity-60",
                internalComplete && "[&>div]:bg-green-500"
              )}
            />
            <div className="flex justify-between text-sm text-muted-foreground">
              <span>{Math.round(progress)}%</span>
              {totalCount !== undefined && completedCount !== undefined && (
                <span>{completedCount}/{totalCount}</span>
              )}
            </div>
          </div>

          {/* Current Status */}
          <div className="space-y-1">
            <div className={cn(
              "text-sm font-medium",
              hasError && "text-red-600",
              isCancelling && "text-orange-600",
              internalComplete && "text-green-600"
            )}>
              {getStatusLabel()}
            </div>
          </div>

          {/* Error Message */}
          {hasError && errorMessage && (
            <div className="p-3 bg-red-50 border border-red-200 rounded-md">
              <div className="text-sm text-red-800">
                {errorMessage}
              </div>
            </div>
          )}

          {/* Success Message */}
          {internalComplete && !hasError && (
            <div className="p-3 bg-green-50 border border-green-200 rounded-md">
              <div className="text-sm text-green-800">
                Operation completed successfully!
              </div>
            </div>
          )}

          {/* Action Buttons */}
          <div className="flex justify-between">
            <div>
              {/* Cancel Button */}
              {canCancel && (
                <Button
                  variant="outline"
                  onClick={handleCancel}
                  disabled={isCancelling}
                  className="text-muted-foreground hover:text-destructive hover:border-destructive"
                >
                  {isCancelling ? 'Cancelling...' : 'Cancel'}
                </Button>
              )}
              {isCancelling && (
                <div className="text-sm text-orange-600">
                  Cancelling operation...
                </div>
              )}
            </div>

            <div>
              {/* Close Button - only show when complete or error */}
              {(internalComplete || hasError) && (
                <Button
                  variant="outline"
                  onClick={onClose}
                >
                  Close
                </Button>
              )}
            </div>
          </div>
        </div>
      </DialogContent>
    </Dialog>
  );
};

export default ProgressModal;
