import React, { useState, useEffect } from 'react';
import { Button } from '@/components/ui/button';
import { Upload, Star, CreditCard, Trash2, ImagePlus } from 'lucide-react';
import { Badge } from '@/components/ui/badge';
import {
  ContextMenu,
  ContextMenuContent,
  ContextMenuItem,
  ContextMenuSeparator,
  ContextMenuTrigger,
} from '@/components/ui/context-menu';
import { DragDropZone } from './DragDropZone';
import { supabase } from '@/integrations/supabase/client';
import { toast } from '@/hooks/use-toast';
import { Skeleton } from '@/components/ui/skeleton';
import { Alert, AlertDescription } from '@/components/ui/alert';
import { getErrorMessage } from '@/lib/errorHandler';
import { logger } from '@/lib/logger';

export interface UploadedImage {
  url: string;
  cloudflare_id?: string;
  file?: File;
  isLocal?: boolean;
  caption?: string;
}

export interface ImageAssignments {
  uploaded: UploadedImage[];
  banner_assignment?: number | null;
  card_assignment?: number | null;
}

interface EntityMultiImageUploaderProps {
  mode: 'create' | 'edit';
  value: ImageAssignments;
  onChange: (assignments: ImageAssignments) => void;
  entityId?: string;
  entityType?: string;
  currentBannerUrl?: string;
  currentCardUrl?: string;
}

export function EntityMultiImageUploader({
  mode,
  value,
  onChange,
  entityType = 'entity',
  entityId,
  currentBannerUrl,
  currentCardUrl
}: EntityMultiImageUploaderProps) {
  const maxImages = mode === 'create' ? 5 : 0; // No uploads allowed in edit mode
  const canUpload = mode === 'create';
  const [loadingPhotos, setLoadingPhotos] = useState(false);

  // Fetch existing photos when in edit mode
  useEffect(() => {
    if (mode === 'edit' && entityId && entityType) {
      fetchEntityPhotos();
    }
  }, [mode, entityId, entityType]);

  // Cleanup blob URLs when component unmounts or images change
  useEffect(() => {
    const currentImages = value.uploaded;
    
    return () => {
      // Revoke all blob URLs on cleanup
      currentImages.forEach(image => {
        if (image.isLocal && image.url.startsWith('blob:')) {
          try {
            URL.revokeObjectURL(image.url);
          } catch (error: unknown) {
            logger.error('Failed to revoke object URL', { error: getErrorMessage(error) });
          }
        }
      });
    };
  }, [value.uploaded]);

  const fetchEntityPhotos = async () => {
    setLoadingPhotos(true);
    try {
      const { data, error } = await supabase
        .from('photos')
        .select('id, cloudflare_image_url, cloudflare_image_id, caption, title')
        .eq('entity_type', entityType)
        .eq('entity_id', entityId || '')
        .order('created_at', { ascending: false });

      if (error) throw error;

      // Map to UploadedImage format
      const mappedPhotos: UploadedImage[] = data?.map(photo => ({
        url: photo.cloudflare_image_url,
        cloudflare_id: photo.cloudflare_image_id,
        caption: photo.caption || photo.title || '',
        isLocal: false,
      })) || [];

      // Find banner and card indices based on currentBannerUrl/currentCardUrl
      const bannerIndex = mappedPhotos.findIndex(p => p.url === currentBannerUrl);
      const cardIndex = mappedPhotos.findIndex(p => p.url === currentCardUrl);

      // Initialize with existing photos and current assignments
      onChange({
        uploaded: mappedPhotos,
        banner_assignment: bannerIndex >= 0 ? bannerIndex : null,
        card_assignment: cardIndex >= 0 ? cardIndex : null,
      });
    } catch (error: unknown) {
      toast({
        title: 'Error',
        description: getErrorMessage(error),
        variant: 'destructive',
      });
    } finally {
      setLoadingPhotos(false);
    }
  };

  const handleFilesAdded = (files: File[]) => {
    // Block uploads entirely in edit mode
    if (!canUpload) {
      toast({
        title: 'Upload Not Allowed',
        description: 'Photos cannot be added during edits. Use the photo gallery to submit additional photos.',
        variant: 'destructive',
      });
      return;
    }

    const currentCount = value.uploaded.length;
    const availableSlots = maxImages - currentCount;
    
    if (availableSlots <= 0) {
      return;
    }

    const filesToAdd = files.slice(0, availableSlots);
    const newImages: UploadedImage[] = filesToAdd.map(file => ({
      url: URL.createObjectURL(file),
      file,
      isLocal: true,
    }));

    const updatedUploaded = [...value.uploaded, ...newImages];
    const updatedValue: ImageAssignments = {
      uploaded: updatedUploaded,
      banner_assignment: value.banner_assignment,
      card_assignment: value.card_assignment,
    };

    // Auto-assign banner if not set
    if (updatedValue.banner_assignment === undefined || updatedValue.banner_assignment === null) {
      if (updatedUploaded.length > 0) {
        updatedValue.banner_assignment = 0;
      }
    }

    // Auto-assign card if not set
    if (updatedValue.card_assignment === undefined || updatedValue.card_assignment === null) {
      if (updatedUploaded.length > 0) {
        updatedValue.card_assignment = 0;
      }
    }

    onChange(updatedValue);
  };

  const handleAssignRole = (index: number, role: 'banner' | 'card') => {
    const updatedValue: ImageAssignments = {
      ...value,
      [role === 'banner' ? 'banner_assignment' : 'card_assignment']: index,
    };
    onChange(updatedValue);
  };

  const handleRemoveImage = (index: number) => {
    const imageToRemove = value.uploaded[index];
    
    // Revoke object URL if it's a local file
    if (imageToRemove.isLocal && imageToRemove.url.startsWith('blob:')) {
      URL.revokeObjectURL(imageToRemove.url);
    }

    const updatedUploaded = value.uploaded.filter((_, i) => i !== index);
    
    const updatedValue: ImageAssignments = {
      uploaded: updatedUploaded,
      banner_assignment: value.banner_assignment === index 
        ? (updatedUploaded.length > 0 ? 0 : null)
        : value.banner_assignment !== null && value.banner_assignment !== undefined && value.banner_assignment > index
        ? value.banner_assignment - 1
        : value.banner_assignment,
      card_assignment: value.card_assignment === index
        ? (updatedUploaded.length > 0 ? 0 : null)
        : value.card_assignment !== null && value.card_assignment !== undefined && value.card_assignment > index
        ? value.card_assignment - 1
        : value.card_assignment,
    };
    
    onChange(updatedValue);
  };

  const renderImageCard = (image: UploadedImage, index: number) => {
    const isBanner = value.banner_assignment === index;
    const isCard = value.card_assignment === index;
    const isExisting = !image.isLocal;

    return (
      <ContextMenu key={index}>
        <ContextMenuTrigger>
          <div className="relative group cursor-context-menu">
            <div className={`aspect-[4/3] rounded-lg overflow-hidden border-2 ${
              isExisting ? 'border-blue-400' : 'border-border'
            } bg-muted`}>
              <img
                src={image.url}
                alt={`Upload ${index + 1}`}
                className="w-full h-full object-cover"
              />
            </div>
            
            {/* Role badges - always visible */}
            <div className="absolute top-2 left-2 flex gap-1 flex-wrap">
              {isBanner && (
                <Badge variant="default" className="gap-1">
                  <Star className="h-3 w-3" />
                  Banner
                </Badge>
              )}
              {isCard && (
                <Badge variant="secondary" className="gap-1">
                  <CreditCard className="h-3 w-3" />
                  Card
                </Badge>
              )}
              {isExisting && (
                <Badge variant="outline" className="bg-blue-100 dark:bg-blue-900">
                  Existing
                </Badge>
              )}
              {image.isLocal && (
                <Badge variant="outline" className="bg-background/80">
                  Not uploaded
                </Badge>
              )}
            </div>

            {/* Remove button - only for new uploads */}
            {image.isLocal && (
              <Button
                size="icon"
                variant="destructive"
                className="absolute top-2 right-2 opacity-0 group-hover:opacity-100 h-8 w-8"
                onClick={(e) => {
                  e.stopPropagation();
                  handleRemoveImage(index);
                }}
              >
                <Trash2 className="w-4 h-4" />
              </Button>
            )}

            {/* Hover hint */}
            <div className="absolute inset-0 bg-black/0 group-hover:bg-black/10 transition-colors rounded-lg flex items-center justify-center">
              <p className="text-background text-xs opacity-0 group-hover:opacity-100 transition-opacity font-medium">
                Right-click for options
              </p>
            </div>
          </div>
        </ContextMenuTrigger>
        
        <ContextMenuContent>
          <ContextMenuItem 
            onClick={() => handleAssignRole(index, 'banner')}
            disabled={isBanner}
          >
            <Star className="mr-2 h-4 w-4" />
            {isBanner ? 'Banner (Current)' : 'Set as Banner'}
          </ContextMenuItem>
          
          <ContextMenuItem 
            onClick={() => handleAssignRole(index, 'card')}
            disabled={isCard}
          >
            <CreditCard className="mr-2 h-4 w-4" />
            {isCard ? 'Card (Current)' : 'Set as Card'}
          </ContextMenuItem>
          
          {image.isLocal && (
            <>
              <ContextMenuSeparator />
              <ContextMenuItem 
                onClick={() => handleRemoveImage(index)}
                className="text-destructive focus:text-destructive"
              >
                <Trash2 className="mr-2 h-4 w-4" />
                Remove Image
              </ContextMenuItem>
            </>
          )}
        </ContextMenuContent>
      </ContextMenu>
    );
  };

  const getHelperText = () => {
    if (value.uploaded.length === 0) {
      return 'Upload images to get started. Images will be uploaded when you submit the form.';
    }
    
    const existingCount = value.uploaded.filter(img => !img.isLocal).length;
    const newCount = value.uploaded.filter(img => img.isLocal).length;
    const parts: string[] = [];
    
    if (mode === 'edit' && existingCount > 0) {
      parts.push(`${existingCount} existing photo${existingCount !== 1 ? 's' : ''}`);
    }
    
    if (newCount > 0) {
      parts.push(`${newCount} new image${newCount > 1 ? 's' : ''} ready to upload`);
    }
    
    parts.push('Right-click to assign banner/card roles');
    
    return parts.join(' • ');
  };

  // Loading state
  if (loadingPhotos) {
    return (
      <div className="space-y-4">
        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
          {[1, 2, 3].map((i) => (
            <Skeleton key={i} className="aspect-[4/3] rounded-lg" />
          ))}
        </div>
        <p className="text-sm text-muted-foreground">Loading existing photos...</p>
      </div>
    );
  }

  // Empty state: show large drag & drop zone (create only) or message (edit)
  if (value.uploaded.length === 0) {
    if (mode === 'edit') {
      return (
        <Alert>
          <AlertDescription>
            No existing photos found. Photos can only be added during entity creation. Use the photo gallery to submit additional photos after creation.
          </AlertDescription>
        </Alert>
      );
    }

    return (
      <div className="space-y-4">
        <DragDropZone
          onFilesAdded={handleFilesAdded}
          maxFiles={maxImages}
          maxSizeMB={25}
          allowedFileTypes={['image/*']}
        />
        <div className="text-sm text-muted-foreground space-y-1">
          <p>• Right-click images to set as banner or card</p>
          <p>• Images will be uploaded when you submit the form</p>
        </div>
      </div>
    );
  }

  // With images: show grid + compact upload area (create only) or read-only (edit)
  return (
    <div className="space-y-4">
      {/* Edit mode notice */}
      {mode === 'edit' && (
        <Alert>
          <AlertDescription>
            Photos cannot be added during edits. You can reassign banner/card roles below. Use the photo gallery to submit additional photos.
          </AlertDescription>
        </Alert>
      )}

      {/* Image Grid */}
      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
        {value.uploaded.map((image, index) => renderImageCard(image, index))}
      </div>

      {/* Compact Upload Area - Create mode only */}
      {canUpload && value.uploaded.length < maxImages && (
        <DragDropZone
          onFilesAdded={handleFilesAdded}
          maxFiles={maxImages - value.uploaded.length}
          maxSizeMB={25}
          allowedFileTypes={['image/*']}
          className="p-6"
        >
          <div className="text-center space-y-2">
            <ImagePlus className="w-8 h-8 mx-auto text-muted-foreground" />
            <p className="text-sm font-medium">Add More Images</p>
            <p className="text-xs text-muted-foreground">
              Drag & drop or click to browse ({value.uploaded.length}/{maxImages})
            </p>
          </div>
        </DragDropZone>
      )}

      {/* Helper Text */}
      <div className="space-y-2 text-sm text-muted-foreground">
        <p className="font-medium">{getHelperText()}</p>
        <div className="space-y-1 pl-4 border-l-2 border-border">
          <p>
            <strong>Banner:</strong> Main header image for the {entityType} detail page
            {value.banner_assignment !== null && value.banner_assignment !== undefined && ` (Image ${value.banner_assignment + 1})`}
          </p>
          <p>
            <strong>Card:</strong> Thumbnail in {entityType} listings and search results
            {value.card_assignment !== null && value.card_assignment !== undefined && ` (Image ${value.card_assignment + 1})`}
          </p>
        </div>
      </div>
    </div>
  );
}
