"use client"

import { useState, useRef, useCallback } from "react"
import { Button } from "@/components/ui/button"
import { Card } from "@/components/ui/card"
import { 
  Upload, 
  X, 
  Image as ImageIcon, 
  Loader2, 
  AlertCircle,
  Check,
  MoveUp,
  MoveDown,
  Eye
} from "lucide-react"
import { toast } from "@/hooks/use-toast"
import Image from "next/image"
import { cn } from "@/lib/utils"

interface FacilityImage {
  url: string
  isPrimary?: boolean
}

interface FacilityImageUploaderProps {
  images: string[]
  onImagesChange: (images: string[]) => void
  maxImages?: number
  maxSizeInMB?: number
}

export function FacilityImageUploader({
  images,
  onImagesChange,
  maxImages = 20,
  maxSizeInMB = 5
}: FacilityImageUploaderProps) {
  const [uploading, setUploading] = useState(false)
  const [uploadProgress, setUploadProgress] = useState<{ [key: string]: number }>({})
  const [dragActive, setDragActive] = useState(false)
  const [previewUrl, setPreviewUrl] = useState<string | null>(null)
  const fileInputRef = useRef<HTMLInputElement>(null)

  const handleDrag = useCallback((e: React.DragEvent) => {
    e.preventDefault()
    e.stopPropagation()
    if (e.type === "dragenter" || e.type === "dragover") {
      setDragActive(true)
    } else if (e.type === "dragleave") {
      setDragActive(false)
    }
  }, [])

  const validateFile = (file: File): string | null => {
    // Check file size
    const maxSizeBytes = maxSizeInMB * 1024 * 1024
    if (file.size > maxSizeBytes) {
      return `Image size exceeds ${maxSizeInMB}MB limit`
    }

    // Check file type
    const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/webp']
    if (!allowedTypes.includes(file.type)) {
      return `Only JPEG, PNG, and WebP images are allowed`
    }

    // Check max images
    if (images.length >= maxImages) {
      return `Maximum ${maxImages} images allowed`
    }

    return null
  }

  const uploadImage = async (file: File): Promise<string | null> => {
    const tempId = Math.random().toString(36)
    
    try {
      setUploadProgress(prev => ({ ...prev, [tempId]: 0 }))

      const formData = new FormData()
      formData.append('file', file)
      formData.append('type', 'facility-image')

      const token = typeof window !== 'undefined' ? localStorage.getItem('geezer_guide_token') : null

      setUploadProgress(prev => ({ ...prev, [tempId]: 30 }))

      const response = await fetch('/api/uploads', {
        method: 'POST',
        body: formData,
        headers: {
          ...(token ? { Authorization: `Bearer ${token}` } : {})
        }
      })

      setUploadProgress(prev => ({ ...prev, [tempId]: 70 }))

      if (!response.ok) {
        throw new Error('Upload failed')
      }

      const data = await response.json()

      if (!data.success || !data.data?.url) {
        throw new Error(data.message || 'Upload failed')
      }

      setUploadProgress(prev => ({ ...prev, [tempId]: 100 }))
      
      // Clean up progress after a delay
      setTimeout(() => {
        setUploadProgress(prev => {
          const newProgress = { ...prev }
          delete newProgress[tempId]
          return newProgress
        })
      }, 1000)

      return data.data.url
    } catch (error: any) {
      console.error('Image upload failed:', error)
      setUploadProgress(prev => {
        const newProgress = { ...prev }
        delete newProgress[tempId]
        return newProgress
      })
      throw error
    }
  }

  const handleFiles = async (files: FileList | File[]) => {
    const fileArray = Array.from(files)
    
    if (fileArray.length === 0) return

    // Check if adding these files would exceed max
    if (images.length + fileArray.length > maxImages) {
      toast({
        title: "Too many images",
        description: `You can only upload ${maxImages} images in total. Currently have ${images.length}.`,
        variant: "destructive"
      })
      return
    }

    setUploading(true)
    const successfulUploads: string[] = []
    const errors: string[] = []

    for (const file of fileArray) {
      const validationError = validateFile(file)
      if (validationError) {
        errors.push(`${file.name}: ${validationError}`)
        continue
      }

      try {
        const url = await uploadImage(file)
        if (url) {
          successfulUploads.push(url)
        }
      } catch (error: any) {
        errors.push(`${file.name}: ${error.message || 'Upload failed'}`)
      }
    }

    if (successfulUploads.length > 0) {
      onImagesChange([...images, ...successfulUploads])
      toast({
        title: "Success",
        description: `${successfulUploads.length} image(s) uploaded successfully`
      })
    }

    if (errors.length > 0) {
      toast({
        title: "Some uploads failed",
        description: errors.slice(0, 3).join('\n') + (errors.length > 3 ? `\n...and ${errors.length - 3} more` : ''),
        variant: "destructive"
      })
    }

    setUploading(false)
  }

  const handleDrop = useCallback((e: React.DragEvent) => {
    e.preventDefault()
    e.stopPropagation()
    setDragActive(false)

    const files = e.dataTransfer.files
    if (files && files.length > 0) {
      handleFiles(files)
    }
  }, [images, maxImages])

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    e.preventDefault()
    if (e.target.files && e.target.files.length > 0) {
      handleFiles(e.target.files)
    }
  }

  const removeImage = (index: number) => {
    const newImages = images.filter((_, i) => i !== index)
    onImagesChange(newImages)
    toast({
      title: "Image removed",
      description: "Image has been removed from your facility"
    })
  }

  const moveImage = (index: number, direction: 'up' | 'down') => {
    const newImages = [...images]
    const newIndex = direction === 'up' ? index - 1 : index + 1
    
    if (newIndex < 0 || newIndex >= images.length) return
    
    [newImages[index], newImages[newIndex]] = [newImages[newIndex], newImages[index]]
    onImagesChange(newImages)
  }

  const hasUploading = Object.keys(uploadProgress).length > 0

  return (
    <div className="space-y-4">
      {/* Upload Area */}
      <div
        onDragEnter={handleDrag}
        onDragLeave={handleDrag}
        onDragOver={handleDrag}
        onDrop={handleDrop}
        className={cn(
          "relative border-2 border-dashed rounded-xl p-8 text-center transition-all",
          dragActive 
            ? "border-blue-500 bg-blue-50" 
            : "border-gray-300 hover:border-gray-400 bg-gray-50",
          uploading && "opacity-50 pointer-events-none"
        )}
      >
        <input
          ref={fileInputRef}
          type="file"
          accept="image/jpeg,image/jpg,image/png,image/webp"
          multiple
          onChange={handleChange}
          className="hidden"
          disabled={uploading || images.length >= maxImages}
        />

        <div className="flex flex-col items-center gap-3">
          {uploading || hasUploading ? (
            <>
              <Loader2 className="h-12 w-12 text-blue-600 animate-spin" />
              <p className="text-sm font-medium text-gray-700">
                Uploading images...
              </p>
              {Object.keys(uploadProgress).length > 0 && (
                <div className="w-full max-w-xs space-y-2">
                  {Object.entries(uploadProgress).map(([id, progress]) => (
                    <div key={id} className="space-y-1">
                      <div className="flex items-center justify-between text-xs text-gray-600">
                        <span>Uploading...</span>
                        <span>{progress}%</span>
                      </div>
                      <div className="h-2 bg-gray-200 rounded-full overflow-hidden">
                        <div 
                          className="h-full bg-blue-600 transition-all duration-300"
                          style={{ width: `${progress}%` }}
                        />
                      </div>
                    </div>
                  ))}
                </div>
              )}
            </>
          ) : (
            <>
              <div className="p-4 bg-blue-100 rounded-full">
                <Upload className="h-8 w-8 text-blue-600" />
              </div>
              <div>
                <p className="text-sm font-medium text-gray-900 mb-1">
                  Drop images here or click to browse
                </p>
                <p className="text-xs text-gray-600">
                  JPEG, PNG, WebP up to {maxSizeInMB}MB each
                </p>
                <p className="text-xs text-gray-500 mt-1">
                  {images.length} / {maxImages} images uploaded
                </p>
              </div>
              <Button
                type="button"
                onClick={() => fileInputRef.current?.click()}
                disabled={uploading || images.length >= maxImages}
                className="mt-2"
              >
                <Upload className="h-4 w-4 mr-2" />
                Select Images
              </Button>
            </>
          )}
        </div>
      </div>

      {/* Image Grid */}
      {images.length > 0 && (
        <div>
          <div className="flex items-center justify-between mb-3">
            <h4 className="text-sm font-medium text-gray-900">
              Facility Images ({images.length})
            </h4>
            {images.length > 0 && (
              <p className="text-xs text-gray-600">
                First image will be the primary image
              </p>
            )}
          </div>
          
          <div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
            {images.map((imageUrl, index) => (
              <Card 
                key={index} 
                className="relative group overflow-hidden border-2 hover:border-blue-300 transition-all"
              >
                {/* Primary Badge */}
                {index === 0 && (
                  <div className="absolute top-2 left-2 z-10">
                    <span className="bg-blue-600 text-white text-xs font-semibold px-2 py-1 rounded-full flex items-center gap-1 shadow-sm">
                      <Check className="h-3 w-3" />
                      Primary
                    </span>
                  </div>
                )}

                {/* Image */}
                <div className="aspect-video relative bg-gray-100">
                  <Image
                    src={imageUrl}
                    alt={`Facility image ${index + 1}`}
                    fill
                    className="object-cover"
                    sizes="(max-width: 768px) 50vw, (max-width: 1200px) 33vw, 25vw"
                  />
                </div>

                {/* Actions Overlay */}
                <div className="absolute inset-0 bg-black/60 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center gap-2">
                  <Button
                    type="button"
                    size="sm"
                    variant="secondary"
                    onClick={() => setPreviewUrl(imageUrl)}
                    className="h-8 w-8 p-0"
                  >
                    <Eye className="h-4 w-4" />
                  </Button>
                  
                  {index > 0 && (
                    <Button
                      type="button"
                      size="sm"
                      variant="secondary"
                      onClick={() => moveImage(index, 'up')}
                      className="h-8 w-8 p-0"
                    >
                      <MoveUp className="h-4 w-4" />
                    </Button>
                  )}
                  
                  {index < images.length - 1 && (
                    <Button
                      type="button"
                      size="sm"
                      variant="secondary"
                      onClick={() => moveImage(index, 'down')}
                      className="h-8 w-8 p-0"
                    >
                      <MoveDown className="h-4 w-4" />
                    </Button>
                  )}
                  
                  <Button
                    type="button"
                    size="sm"
                    variant="destructive"
                    onClick={() => removeImage(index)}
                    className="h-8 w-8 p-0"
                  >
                    <X className="h-4 w-4" />
                  </Button>
                </div>
              </Card>
            ))}
          </div>
        </div>
      )}

      {/* Preview Modal */}
      {previewUrl && (
        <div 
          className="fixed inset-0 z-50 bg-black/80 flex items-center justify-center p-4"
          onClick={() => setPreviewUrl(null)}
        >
          <div className="relative max-w-4xl max-h-[90vh] w-full">
            <Button
              variant="secondary"
              size="sm"
              className="absolute top-4 right-4 z-10"
              onClick={() => setPreviewUrl(null)}
            >
              <X className="h-4 w-4" />
            </Button>
            <Image
              src={previewUrl}
              alt="Preview"
              width={1200}
              height={800}
              className="w-full h-auto rounded-lg"
            />
          </div>
        </div>
      )}

      {/* Help Text */}
      {images.length === 0 && (
        <div className="flex items-start gap-2 p-3 bg-blue-50 border border-blue-200 rounded-lg">
          <AlertCircle className="h-4 w-4 text-blue-600 mt-0.5 flex-shrink-0" />
          <div className="text-xs text-blue-800">
            <p className="font-medium mb-1">Tips for great facility photos:</p>
            <ul className="list-disc list-inside space-y-0.5 text-blue-700">
              <li>Use high-resolution images (min 1200x800px)</li>
              <li>Show different areas: rooms, common areas, outdoor spaces</li>
              <li>Ensure good lighting and clean spaces</li>
              <li>First image appears as primary in search results</li>
            </ul>
          </div>
        </div>
      )}
    </div>
  )
}

