'use client'

import React, { useState, useRef, useCallback } from 'react'
import { Button } from '@/components/ui/button'
import { Upload, Image as ImageIcon, X } from 'lucide-react'
import { cn } from '@/lib/utils'
import Image from 'next/image'
import { useToast } from '@/hooks/use-toast'

interface ImageUploadProps {
  value?: string | File
  onChange: (value: File | null) => void
  className?: string
  label?: string
  disabled?: boolean
  aspectRatio?: 'video' | 'square' | 'auto'
  currentImage?: string
}

const ImageUpload: React.FC<ImageUploadProps> = ({
  value,
  onChange,
  className,
  label = 'Upload Cover Image',
  disabled = false,
  aspectRatio = 'video',
}) => {
  const [isUploading, setIsUploading] = useState(false)
  const [previewUrl, setPreviewUrl] = useState<string | null>(null)
  const [isDragging, setIsDragging] = useState(false)
  const fileInputRef = useRef<HTMLInputElement>(null)
  const { toast } = useToast()

  // Create preview URL when value changes
  React.useEffect(() => {
    if (value instanceof File) {
      const url = URL.createObjectURL(value)
      setPreviewUrl(url)
      return () => URL.revokeObjectURL(url)
    } else if (typeof value === 'string') {
      setPreviewUrl(value)
    } else {
      setPreviewUrl(null)
    }
  }, [value])

  const validateFile = React.useCallback(
    (file: File): boolean => {
      // Check file type
      if (!file.type.startsWith('image/')) {
        toast({
          title: 'Invalid file type',
          description: 'Please select an image file (JPEG, PNG, GIF, WebP)',
          variant: 'destructive',
        })
        return false
      }

      // Check file size (5MB limit)
      const maxSize = 5 * 1024 * 1024 // 5MB
      if (file.size > maxSize) {
        toast({
          title: 'File too large',
          description: 'Please select an image smaller than 5MB',
          variant: 'destructive',
        })
        return false
      }

      return true
    },
    [toast]
  )

  const handleFile = useCallback(
    async (file: File) => {
      if (!validateFile(file)) return

      try {
        setIsUploading(true)
        onChange(file)
        toast({
          title: 'Image selected',
          description: 'Cover image has been updated',
        })
      } catch (error) {
        console.error('Failed to handle file:', error)
        toast({
          title: 'Upload failed',
          description: 'Failed to process the image',
          variant: 'destructive',
        })
      } finally {
        setIsUploading(false)
      }
    },
    [onChange, toast, validateFile]
  )

  const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0]
    if (!file) return

    await handleFile(file)

    // Clear the input value to allow uploading the same file again
    if (fileInputRef.current) {
      fileInputRef.current.value = ''
    }
  }

  const handleClick = (e: React.MouseEvent) => {
    e.preventDefault()
    e.stopPropagation()
    if (!disabled) {
      fileInputRef.current?.click()
    }
  }

  const handleRemove = (e: React.MouseEvent) => {
    e.preventDefault()
    e.stopPropagation()
    onChange(null)
    setPreviewUrl(null)
    toast({
      title: 'Image removed',
      description: 'Cover image has been removed',
    })
  }

  const handleDragOver = (e: React.DragEvent) => {
    e.preventDefault()
    e.stopPropagation()
    if (!disabled) {
      setIsDragging(true)
    }
  }

  const handleDragLeave = (e: React.DragEvent) => {
    e.preventDefault()
    e.stopPropagation()
    setIsDragging(false)
  }

  const handleDrop = async (e: React.DragEvent) => {
    e.preventDefault()
    e.stopPropagation()
    setIsDragging(false)

    if (disabled) return

    const files = Array.from(e.dataTransfer.files)
    const file = files[0]

    if (file) {
      await handleFile(file)
    }
  }

  const getAspectRatioClass = () => {
    switch (aspectRatio) {
      case 'video':
        return 'aspect-video'
      case 'square':
        return 'aspect-square'
      default:
        return 'min-h-[200px]'
    }
  }

  return (
    <div className={cn('space-y-4', className)}>
      <input
        type="file"
        className="hidden"
        ref={fileInputRef}
        onChange={handleFileChange}
        accept="image/*"
        disabled={disabled}
      />

      {previewUrl ? (
        <div
          className={cn(
            'relative overflow-hidden rounded-lg bg-muted border-2 border-dashed border-transparent',
            getAspectRatioClass()
          )}
        >
          <Image
            src={previewUrl}
            alt="Cover image preview"
            fill
            className="object-cover"
            sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
          />
          <div className="absolute inset-0 bg-black/0 hover:bg-black/10 transition-colors">
            <div className="absolute top-2 right-2 flex gap-2">
              <Button
                type="button"
                variant="secondary"
                size="sm"
                onClick={handleClick}
                disabled={disabled || isUploading}
                className="bg-white/90 hover:bg-white"
              >
                Change
              </Button>
              <Button
                type="button"
                variant="destructive"
                size="sm"
                onClick={handleRemove}
                disabled={disabled || isUploading}
                className="bg-red-500/90 hover:bg-red-500"
              >
                <X className="w-4 h-4" />
              </Button>
            </div>
          </div>
        </div>
      ) : (
        <div
          className={cn(
            'flex cursor-pointer flex-col items-center justify-center rounded-lg border-2 border-dashed p-8 transition-all duration-200',
            getAspectRatioClass(),
            isDragging
              ? 'border-primary bg-primary/5 scale-[1.02]'
              : 'border-muted-foreground/25 hover:border-primary/50 hover:bg-muted/50',
            disabled && 'cursor-not-allowed opacity-50'
          )}
          onClick={handleClick}
          onKeyDown={(e) => {
            if (e.key === 'Enter' || e.key === ' ') {
              e.preventDefault()
              handleClick(e as unknown as React.MouseEvent)
            }
          }}
          onDragOver={handleDragOver}
          onDragLeave={handleDragLeave}
          onDrop={handleDrop}
          role="button"
          tabIndex={disabled ? -1 : 0}
          aria-label={`${label} - click to browse or drag and drop`}
        >
          {isUploading ? (
            <div className="flex flex-col items-center justify-center gap-3">
              <div className="h-8 w-8 animate-spin rounded-full border-2 border-primary border-t-transparent"></div>
              <p className="text-sm font-medium">Uploading image...</p>
            </div>
          ) : (
            <div className="flex flex-col items-center justify-center gap-3">
              <div className="rounded-full bg-muted p-4">
                {isDragging ? (
                  <Upload className="w-6 h-6 text-primary" />
                ) : (
                  <ImageIcon className="w-6 h-6 text-muted-foreground" />
                )}
              </div>
              <div className="text-center">
                <p className="font-medium text-foreground">{label}</p>
                <p className="text-sm text-muted-foreground mt-1">
                  {isDragging ? 'Drop your image here' : 'Click to browse or drag and drop'}
                </p>
                <p className="text-xs text-muted-foreground mt-1">
                  Supports JPEG, PNG, GIF, WebP (max 5MB)
                </p>
              </div>
            </div>
          )}
        </div>
      )}
    </div>
  )
}

export default ImageUpload
