import React, { useState } from "react";
import { invokeWithTracking } from "@/lib/edgeFunctionTracking";
import { handleError, getErrorMessage } from "@/lib/errorHandler";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Separator } from "@/components/ui/separator";
import { Progress } from "@/components/ui/progress";
import { UppyPhotoUploadLazy } from "./UppyPhotoUploadLazy";
import { PhotoCaptionEditor, PhotoWithCaption } from "./PhotoCaptionEditor";
import { supabase } from "@/lib/supabaseClient";
import { useAuth } from "@/hooks/useAuth";
import { useToast } from "@/hooks/use-toast";
import { Camera, CheckCircle, AlertCircle, Info, XCircle } from "lucide-react";
import { UppyPhotoSubmissionUploadProps } from "@/types/submissions";
import { withRetry, isRetryableError } from "@/lib/retryHelpers";
import { logger } from "@/lib/logger";
import { breadcrumb } from "@/lib/errorBreadcrumbs";
import { checkSubmissionRateLimit, recordSubmissionAttempt } from "@/lib/submissionRateLimiter";
import { sanitizeErrorMessage } from "@/lib/errorSanitizer";
import { reportBanEvasionAttempt } from "@/lib/pipelineAlerts";

/**
 * Photo upload pipeline configuration
 * Bulletproof retry and recovery settings
 */
const UPLOAD_CONFIG = {
  MAX_UPLOAD_ATTEMPTS: 3,
  MAX_DB_ATTEMPTS: 3,
  POLLING_TIMEOUT_SECONDS: 30,
  POLLING_INTERVAL_MS: 1000,
  BASE_RETRY_DELAY: 1000,
  MAX_RETRY_DELAY: 10000,
  ALLOW_PARTIAL_SUCCESS: true, // Allow submission even if some photos fail
} as const;

export function UppyPhotoSubmissionUpload({
  onSubmissionComplete,
  entityId,
  entityType,
  parentId,
}: UppyPhotoSubmissionUploadProps) {
  const [title, setTitle] = useState("");
  const [photos, setPhotos] = useState<PhotoWithCaption[]>([]);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [uploadProgress, setUploadProgress] = useState<{ current: number; total: number } | null>(null);
  const [failedPhotos, setFailedPhotos] = useState<Array<{ index: number; error: string }>>([]);
  const [orphanedCloudflareIds, setOrphanedCloudflareIds] = useState<string[]>([]);
  const { user } = useAuth();
  const { toast } = useToast();

  /**
   * ✅ CRITICAL FIX: Cleanup orphaned Cloudflare images
   * Called when DB transaction fails after successful uploads
   */
  const cleanupOrphanedImages = async (imageIds: string[]) => {
    if (imageIds.length === 0) return;
    
    logger.warn('Cleaning up orphaned images', { count: imageIds.length });
    
    try {
      await Promise.allSettled(
        imageIds.map(id => 
          invokeWithTracking('upload-image', { action: 'delete', imageId: id }, user?.id)
        )
      );
      logger.info('Orphaned images cleaned up', { count: imageIds.length });
    } catch (error) {
      // Non-blocking cleanup - log but don't fail
      logger.error('Failed to cleanup orphaned images', { 
        error: getErrorMessage(error), 
        imageIds 
      });
    }
  };

  const handleFilesSelected = (files: File[]) => {
    // Convert files to photo objects with object URLs for preview
    const newPhotos: PhotoWithCaption[] = files.map((file, index) => ({
      url: URL.createObjectURL(file), // Object URL for preview
      file, // Store the file for later upload
      caption: "",
      order: photos.length + index,
      uploadStatus: "pending" as const,
    }));
    setPhotos((prev) => [...prev, ...newPhotos]);
  };

  const handlePhotosChange = (updatedPhotos: PhotoWithCaption[]) => {
    setPhotos(updatedPhotos);
  };

  const handleRemovePhoto = (index: number) => {
    setPhotos((prev) => {
      const photo = prev[index];
      // Revoke object URL if it exists
      if (photo.file && photo.url.startsWith("blob:")) {
        URL.revokeObjectURL(photo.url);
      }
      return prev.filter((_, i) => i !== index);
    });
  };

  const handleSubmit = async () => {
    if (!user) {
      toast({
        variant: "destructive",
        title: "Authentication Required",
        description: "Please sign in to submit photos.",
      });
      return;
    }

    if (photos.length === 0) {
      toast({
        variant: "destructive",
        title: "No Photos",
        description: "Please upload at least one photo before submitting.",
      });
      return;
    }

    setIsSubmitting(true);

    // ✅ Declare uploadedPhotos outside try block for error handling scope
    const uploadedPhotos: PhotoWithCaption[] = [];

    try {
      // ✅ Phase 4: Rate limiting check
      const rateLimit = checkSubmissionRateLimit(user.id);
      if (!rateLimit.allowed) {
        const sanitizedMessage = sanitizeErrorMessage(rateLimit.reason || 'Rate limit exceeded');
        logger.warn('[RateLimit] Photo submission blocked', {
          userId: user.id,
          reason: rateLimit.reason
        });
        throw new Error(sanitizedMessage);
      }
      recordSubmissionAttempt(user.id);

      // ✅ Phase 4: Breadcrumb tracking
      breadcrumb.userAction('Start photo submission', 'handleSubmit', {
        photoCount: photos.length,
        entityType,
        entityId,
        userId: user.id
      });

      // ✅ Phase 4: Ban check with retry
      breadcrumb.apiCall('profiles', 'SELECT');
      const profile = await withRetry(
        async () => {
          const { data, error } = await supabase
            .from('profiles')
            .select('banned')
            .eq('user_id', user.id)
            .single();
          
          if (error) throw error;
          return data;
        },
        { maxAttempts: 2 }
      );

      if (profile?.banned) {
        // Report ban evasion attempt
        reportBanEvasionAttempt(user.id, 'photo_upload').catch(() => {
          // Non-blocking - don't fail if alert fails
        });
        throw new Error('Account suspended. Contact support for assistance.');
      }

      // ✅ Phase 4: Validate photos before processing
      if (photos.some(p => !p.file)) {
        throw new Error('All photos must have valid files');
      }

      breadcrumb.userAction('Upload images', 'handleSubmit', {
        totalImages: photos.length
      });
      
      // ✅ Phase 4: Upload all photos with bulletproof error recovery
      const photosToUpload = photos.filter((p) => p.file);
      const uploadFailures: Array<{ index: number; error: string; photo: PhotoWithCaption }> = [];

      if (photosToUpload.length > 0) {
        setUploadProgress({ current: 0, total: photosToUpload.length });
        setFailedPhotos([]);

        for (let i = 0; i < photosToUpload.length; i++) {
          const photo = photosToUpload[i];
          const photoIndex = photos.indexOf(photo);
          setUploadProgress({ current: i + 1, total: photosToUpload.length });

          // Update status
          setPhotos((prev) => prev.map((p) => (p === photo ? { ...p, uploadStatus: "uploading" as const } : p)));

          try {
            // ✅ Bulletproof: Explicit retry configuration with exponential backoff
            const cloudflareResult = await withRetry(
              async () => {
                // Get upload URL from edge function
                const { data: uploadData, error: uploadError } = await invokeWithTracking(
                  "upload-image",
                  { metadata: { requireSignedURLs: false }, variant: "public" },
                  user?.id,
                );

                if (uploadError) throw uploadError;

                const { uploadURL, id: cloudflareId } = uploadData;

                // Upload file to Cloudflare
                if (!photo.file) {
                  throw new Error("Photo file is missing");
                }
                const formData = new FormData();
                formData.append("file", photo.file);

                const uploadResponse = await fetch(uploadURL, {
                  method: "POST",
                  body: formData,
                });

                if (!uploadResponse.ok) {
                  const errorText = await uploadResponse.text().catch(() => 'Unknown error');
                  throw new Error(`Cloudflare upload failed: ${errorText}`);
                }

                // ✅ Bulletproof: Configurable polling with timeout
                let attempts = 0;
                const maxAttempts = UPLOAD_CONFIG.POLLING_TIMEOUT_SECONDS;
                let cloudflareUrl = "";

                while (attempts < maxAttempts) {
                  const {
                    data: { session },
                  } = await supabase.auth.getSession();
                  const supabaseUrl = "https://api.thrillwiki.com";
                  const statusResponse = await fetch(`${supabaseUrl}/functions/v1/upload-image?id=${cloudflareId}`, {
                    headers: {
                      Authorization: `Bearer ${session?.access_token || ""}`,
                      apikey:
                        "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InlkdnRtbnJzenlicW5iY3FiZGN5Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTgzMjYzNTYsImV4cCI6MjA3MzkwMjM1Nn0.DM3oyapd_omP5ZzIlrT0H9qBsiQBxBRgw2tYuqgXKX4",
                    },
                  });

                  if (statusResponse.ok) {
                    const status = await statusResponse.json();
                    if (status.uploaded && status.urls) {
                      cloudflareUrl = status.urls.public;
                      break;
                    }
                  }

                  await new Promise((resolve) => setTimeout(resolve, UPLOAD_CONFIG.POLLING_INTERVAL_MS));
                  attempts++;
                }

                if (!cloudflareUrl) {
                  // Track orphaned upload for cleanup
                  setOrphanedCloudflareIds(prev => [...prev, cloudflareId]);
                  throw new Error("Upload processing timeout - image may be uploaded but not ready");
                }

                return { cloudflareUrl, cloudflareId };
              },
              {
                maxAttempts: UPLOAD_CONFIG.MAX_UPLOAD_ATTEMPTS,
                baseDelay: UPLOAD_CONFIG.BASE_RETRY_DELAY,
                maxDelay: UPLOAD_CONFIG.MAX_RETRY_DELAY,
                shouldRetry: (error) => {
                  // ✅ Bulletproof: Intelligent retry logic
                  if (error instanceof Error) {
                    const message = error.message.toLowerCase();
                    // Don't retry validation errors or file too large
                    if (message.includes('file is missing')) return false;
                    if (message.includes('too large')) return false;
                    if (message.includes('invalid file type')) return false;
                  }
                  return isRetryableError(error);
                },
                onRetry: (attempt, error, delay) => {
                  logger.warn('Retrying photo upload', { 
                    attempt,
                    maxAttempts: UPLOAD_CONFIG.MAX_UPLOAD_ATTEMPTS,
                    delay, 
                    fileName: photo.file?.name,
                    error: error instanceof Error ? error.message : String(error)
                  });
                  
                  // Emit event for UI indicator
                  window.dispatchEvent(new CustomEvent('submission-retry', {
                    detail: { 
                      id: crypto.randomUUID(),
                      attempt, 
                      maxAttempts: UPLOAD_CONFIG.MAX_UPLOAD_ATTEMPTS, 
                      delay, 
                      type: `photo upload: ${photo.file?.name || 'unnamed'}` 
                    }
                  }));
                }
              }
            );

            // Revoke object URL
            URL.revokeObjectURL(photo.url);

            uploadedPhotos.push({
              ...photo,
              url: cloudflareResult.cloudflareUrl,
              cloudflare_id: cloudflareResult.cloudflareId,
              uploadStatus: "uploaded" as const,
            });

            // Update status
            setPhotos((prev) =>
              prev.map((p) => (p === photo ? { 
                ...p, 
                url: cloudflareResult.cloudflareUrl, 
                cloudflare_id: cloudflareResult.cloudflareId,
                uploadStatus: "uploaded" as const 
              } : p)),
            );

            logger.info('Photo uploaded successfully', {
              fileName: photo.file?.name,
              cloudflareId: cloudflareResult.cloudflareId,
              photoIndex: i + 1,
              totalPhotos: photosToUpload.length
            });

          } catch (error: unknown) {
            const errorMsg = sanitizeErrorMessage(error);
            
            logger.error('Photo upload failed after all retries', {
              fileName: photo.file?.name,
              photoIndex: i + 1,
              error: errorMsg,
              retriesExhausted: true
            });

            handleError(error, {
              action: 'Upload Photo',
              userId: user.id,
              metadata: { 
                photoTitle: photo.title, 
                photoOrder: photo.order, 
                fileName: photo.file?.name,
                retriesExhausted: true 
              }
            });

            // ✅ Graceful degradation: Track failure but continue
            uploadFailures.push({ index: photoIndex, error: errorMsg, photo });
            setFailedPhotos(prev => [...prev, { index: photoIndex, error: errorMsg }]);
            setPhotos((prev) => prev.map((p) => (p === photo ? { ...p, uploadStatus: "failed" as const } : p)));

            // ✅ Graceful degradation: Only throw if no partial success allowed
            if (!UPLOAD_CONFIG.ALLOW_PARTIAL_SUCCESS) {
              throw new Error(`Failed to upload ${photo.title || photo.file?.name || "photo"}: ${errorMsg}`);
            }
          }
        }
      }

      // ✅ Graceful degradation: Check if we have any successful uploads
      if (uploadedPhotos.length === 0 && photosToUpload.length > 0) {
        throw new Error('All photo uploads failed. Please check your connection and try again.');
      }

      setUploadProgress(null);

      // ✅ Graceful degradation: Log upload summary
      logger.info('Photo upload phase complete', {
        totalPhotos: photosToUpload.length,
        successfulUploads: uploadedPhotos.length,
        failedUploads: uploadFailures.length,
        allowPartialSuccess: UPLOAD_CONFIG.ALLOW_PARTIAL_SUCCESS
      });

      // ✅ Phase 4: Validate uploaded photos before DB insertion
      breadcrumb.userAction('Validate photos', 'handleSubmit', {
        uploadedCount: uploadedPhotos.length,
        failedCount: uploadFailures.length
      });

      // Only include successfully uploaded photos
      const successfulPhotos = photos.filter(p => 
        !p.file || // Already uploaded (no file)
        uploadedPhotos.some(up => up.order === p.order) // Successfully uploaded
      );
      
      successfulPhotos.forEach((photo, index) => {
        if (!photo.url) {
          throw new Error(`Photo ${index + 1}: Missing URL`);
        }
        if (photo.uploadStatus === 'uploaded' && !photo.url.includes('/images/')) {
          throw new Error(`Photo ${index + 1}: Invalid Cloudflare URL format`);
        }
      });

      // ✅ Bulletproof: Create submission records with explicit retry configuration
      breadcrumb.apiCall('create_submission_with_items', 'RPC');
      await withRetry(
        async () => {
          // Create content_submission record first
          const { data: submissionData, error: submissionError } = await supabase
            .from("content_submissions")
            .insert({
              user_id: user.id,
              submission_type: "photo",
              content: {
                partialSuccess: uploadFailures.length > 0,
                successfulPhotos: uploadedPhotos.length,
                failedPhotos: uploadFailures.length
              },
            })
            .select()
            .single();

          if (submissionError || !submissionData) {
            // ✅ Orphan cleanup: If DB fails, track uploaded images for cleanup
            uploadedPhotos.forEach(p => {
              if (p.cloudflare_id) {
                setOrphanedCloudflareIds(prev => [...prev, p.cloudflare_id!]);
              }
            });
            throw submissionError || new Error("Failed to create submission record");
          }

          // Create photo_submission record
          const { data: photoSubmissionData, error: photoSubmissionError } = await supabase
            .from("photo_submissions")
            .insert({
              submission_id: submissionData.id,
              entity_type: entityType,
              entity_id: entityId,
              parent_id: parentId || null,
              title: title.trim() || null,
            })
            .select()
            .single();

          if (photoSubmissionError || !photoSubmissionData) {
            throw photoSubmissionError || new Error("Failed to create photo submission");
          }

          // ✅ CRITICAL FIX: Create submission_items record for moderation queue
          const { error: submissionItemError } = await supabase
            .from('submission_items')
            .insert({
              submission_id: submissionData.id,
              item_type: 'photo',
              action_type: 'create',
              status: 'pending',
              order_index: 0,
              photo_submission_id: photoSubmissionData.id
            });

          if (submissionItemError) {
            throw submissionItemError;
          }

          // Insert only successful photo items
          const photoItems = successfulPhotos.map((photo, index) => ({
            photo_submission_id: photoSubmissionData.id,
            cloudflare_image_id: photo.cloudflare_id || photo.url.split("/").slice(-2, -1)[0] || "",
            cloudflare_image_url: photo.url,
            caption: photo.caption.trim() || null,
            title: photo.title?.trim() || null,
            filename: photo.file?.name || null,
            order_index: index,
            file_size: photo.file?.size || null,
            mime_type: photo.file?.type || null,
          }));

          const { error: itemsError } = await supabase.from("photo_submission_items").insert(photoItems);

          if (itemsError) {
            throw itemsError;
          }

          logger.info('Photo submission created successfully', {
            submissionId: submissionData.id,
            photoCount: photoItems.length
          });
        },
        {
          maxAttempts: UPLOAD_CONFIG.MAX_DB_ATTEMPTS,
          baseDelay: UPLOAD_CONFIG.BASE_RETRY_DELAY,
          maxDelay: UPLOAD_CONFIG.MAX_RETRY_DELAY,
          shouldRetry: (error) => {
            // ✅ Bulletproof: Intelligent retry for DB operations
            if (error && typeof error === 'object') {
              const pgError = error as { code?: string };
              // Don't retry unique constraint violations or foreign key errors
              if (pgError.code === '23505') return false; // unique_violation
              if (pgError.code === '23503') return false; // foreign_key_violation
            }
            return isRetryableError(error);
          },
          onRetry: (attempt, error, delay) => {
            logger.warn('Retrying photo submission DB insertion', { 
              attempt,
              maxAttempts: UPLOAD_CONFIG.MAX_DB_ATTEMPTS,
              delay,
              error: error instanceof Error ? error.message : String(error)
            });
            
            window.dispatchEvent(new CustomEvent('submission-retry', {
              detail: { 
                id: crypto.randomUUID(),
                attempt, 
                maxAttempts: UPLOAD_CONFIG.MAX_DB_ATTEMPTS, 
                delay, 
                type: 'photo submission database' 
              }
            }));
          }
        }
      );

      // ✅ Graceful degradation: Inform user about partial success
      if (uploadFailures.length > 0) {
        toast({
          title: "Partial Submission Successful",
          description: `${uploadedPhotos.length} photo(s) submitted successfully. ${uploadFailures.length} photo(s) failed to upload.`,
          variant: "default",
        });
        
        logger.warn('Partial photo submission success', {
          successCount: uploadedPhotos.length,
          failureCount: uploadFailures.length,
          failures: uploadFailures.map(f => ({ index: f.index, error: f.error }))
        });
      } else {
        toast({
          title: "Submission Successful",
          description: "Your photos have been submitted for review. Thank you for contributing!",
        });
      }

      // ✅ Cleanup: Revoke blob URLs
      photos.forEach((photo) => {
        if (photo.url.startsWith("blob:")) {
          URL.revokeObjectURL(photo.url);
        }
      });

      // ✅ Cleanup: Log orphaned Cloudflare images for manual cleanup
      if (orphanedCloudflareIds.length > 0) {
        logger.warn('Orphaned Cloudflare images detected', {
          cloudflareIds: orphanedCloudflareIds,
          count: orphanedCloudflareIds.length,
          note: 'These images were uploaded but submission failed - manual cleanup may be needed'
        });
      }

      setTitle("");
      setPhotos([]);
      setFailedPhotos([]);
      setOrphanedCloudflareIds([]);
      onSubmissionComplete?.();
    } catch (error: unknown) {
      const errorMsg = sanitizeErrorMessage(error);
      
      // ✅ CRITICAL FIX: Cleanup orphaned images on failure
      if (orphanedCloudflareIds.length > 0) {
        cleanupOrphanedImages(orphanedCloudflareIds).catch(() => {
          // Non-blocking - log already handled in cleanupOrphanedImages
        });
      }
      
      logger.error('Photo submission failed', {
        error: errorMsg,
        photoCount: photos.length,
        uploadedCount: uploadedPhotos.length,
        orphanedIds: orphanedCloudflareIds,
        retriesExhausted: true
      });

      handleError(error, {
        action: 'Submit Photo Submission',
        userId: user?.id,
        metadata: { 
          entityType, 
          entityId, 
          photoCount: photos.length,
          uploadedPhotos: uploadedPhotos.length,
          failedPhotos: failedPhotos.length,
          orphanedCloudflareIds: orphanedCloudflareIds.length,
          retriesExhausted: true 
        }
      });

      toast({
        variant: "destructive",
        title: "Submission Failed",
        description: errorMsg || "There was an error submitting your photos. Please try again.",
      });
    } finally {
      setIsSubmitting(false);
      setUploadProgress(null);
    }
  };

  // Cleanup on unmount
  React.useEffect(() => {
    return () => {
      photos.forEach((photo) => {
        if (photo.url.startsWith("blob:")) {
          URL.revokeObjectURL(photo.url);
        }
      });
    };
  }, []);

  const metadata = {
    submissionType: "photo",
    entityId,
    entityType,
    parentId,
    userId: user?.id,
  };

  return (
    <Card className="w-full max-w-2xl mx-auto shadow-lg border-accent/20 bg-accent/5">
      <CardHeader className="text-center space-y-4">
        <div className="mx-auto w-16 h-16 bg-accent/10 border-2 border-accent/30 rounded-full flex items-center justify-center">
          <Camera className="w-8 h-8 text-accent" />
        </div>
        <div>
          <CardTitle className="text-2xl text-accent">Submit Photos</CardTitle>
          <CardDescription className="text-base mt-2">
            Share your photos with the community. All submissions will be reviewed before being published.
          </CardDescription>
        </div>
      </CardHeader>

      <CardContent className="space-y-6">
        <div className="bg-muted/50 rounded-lg p-4 border border-border">
          <div className="flex items-start gap-3">
            <Info className="w-5 h-5 text-accent mt-0.5 flex-shrink-0" />
            <div className="space-y-2 text-sm">
              <p className="font-medium">Submission Guidelines:</p>
              <ul className="space-y-1 text-muted-foreground">
                <li>• Photos should be clear and well-lit</li>
                <li>• Maximum 10 images per submission</li>
                <li>• Each image up to 25MB in size</li>
                <li>• Review process takes 24-48 hours</li>
              </ul>
            </div>
          </div>
        </div>

        <Separator />

        <div className="space-y-2">
          <Label htmlFor="title" className="text-base font-medium">
            Title <span className="text-muted-foreground">(optional)</span>
          </Label>
          <Input
            id="title"
            value={title}
            onChange={(e) => setTitle(e.target.value)}
            placeholder="Give your photos a descriptive title (optional)"
            maxLength={100}
            disabled={isSubmitting}
            className="transition-all duration-200 focus:ring-2 focus:ring-primary/20"
          />
          <p className="text-sm text-muted-foreground">{title.length}/100 characters</p>
        </div>

        <div className="space-y-3">
          <div className="flex items-center justify-between">
            <Label className="text-base font-medium">Photos *</Label>
            {photos.length > 0 && (
              <Badge variant="secondary" className="text-xs">
                {photos.length} photo{photos.length !== 1 ? "s" : ""} selected
              </Badge>
            )}
          </div>
          <UppyPhotoUploadLazy
            onFilesSelected={handleFilesSelected}
            deferUpload={true}
            maxFiles={10}
            maxSizeMB={25}
            metadata={metadata}
            variant="public"
            showPreview={false}
            size="default"
            enableDragDrop={true}
            disabled={isSubmitting}
          />
        </div>

        {photos.length > 0 && (
          <>
            <Separator />
            <PhotoCaptionEditor
              photos={photos}
              onPhotosChange={handlePhotosChange}
              onRemovePhoto={handleRemovePhoto}
              maxCaptionLength={200}
            />
          </>
        )}

        <Separator />

        <div className="space-y-4">
          {uploadProgress && (
            <div className="space-y-2">
              <div className="flex items-center justify-between text-sm">
                <span className="font-medium">Uploading photos...</span>
                <span className="text-muted-foreground">
                  {uploadProgress.current} of {uploadProgress.total}
                </span>
              </div>
              <Progress value={(uploadProgress.current / uploadProgress.total) * 100} />
              {failedPhotos.length > 0 && (
                <div className="flex items-start gap-2 text-sm text-destructive bg-destructive/10 p-2 rounded">
                  <XCircle className="w-4 h-4 mt-0.5 flex-shrink-0" />
                  <span>{failedPhotos.length} photo(s) failed - submission will continue with successful uploads</span>
                </div>
              )}
            </div>
          )}

          <Button
            onClick={handleSubmit}
            disabled={isSubmitting || photos.length === 0}
            className="w-full h-12 text-base font-medium bg-accent hover:bg-accent/90 text-accent-foreground"
            size="lg"
          >
            {isSubmitting ? (
              <div className="flex items-center gap-2">
                <div className="w-4 h-4 border-2 border-primary-foreground/30 border-t-primary-foreground rounded-full animate-spin" />
                {uploadProgress ? `Uploading ${uploadProgress.current}/${uploadProgress.total}...` : "Submitting..."}
              </div>
            ) : (
              <div className="flex items-center gap-2">
                <CheckCircle className="w-5 h-5" />
                Submit {photos.length} Photo{photos.length !== 1 ? "s" : ""}
              </div>
            )}
          </Button>

          <div className="flex items-center justify-center gap-2 text-sm text-muted-foreground">
            <AlertCircle className="w-4 h-4" />
            <span>Your submission will be reviewed and published within 24-48 hours</span>
          </div>
        </div>
      </CardContent>
    </Card>
  );
}
