"use client"

import * as React from "react"
import * as DialogPrimitive from "@radix-ui/react-dialog"
import { cva, type VariantProps } from "class-variance-authority"
import { X, ChevronLeft, ChevronRight, ZoomIn, ZoomOut, Download, Maximize2, Play, Pause, Volume2, VolumeX, Loader2 } from "lucide-react"
import { motion, AnimatePresence } from "framer-motion"

import { cn } from "../../lib/utils"

/**
 * Premium Lightbox Component
 * 
 * Advanced lightbox/modal for displaying images and videos with zoom,
 * navigation, fullscreen support, and smooth animations.
 * Perfect for galleries, product showcases, and media presentations.
 */

const lightboxVariants = cva(
  "fixed inset-0 z-50 flex items-center justify-center",
  {
    variants: {
      backdrop: {
        dark: "bg-black/95",
        blur: "bg-black/90 backdrop-blur-md",
        light: "bg-white/90",
        gradient: "bg-gradient-to-b from-black/95 to-black/80",
      },
    },
    defaultVariants: {
      backdrop: "blur",
    },
  }
)

interface MediaItem {
  type: "image" | "video"
  src: string
  alt?: string
  thumbnail?: string
  poster?: string
  title?: string
  description?: string
  category?: string
  date?: Date | number
  [key: string]: any
}

interface LightboxContextValue {
  items: MediaItem[]
  currentIndex: number
  setCurrentIndex: (index: number) => void
  isOpen: boolean
  setIsOpen: (open: boolean) => void
  zoom: number
  setZoom: (zoom: number) => void
}

const LightboxContext = React.createContext<LightboxContextValue | undefined>(undefined)

function useLightbox() {
  const context = React.useContext(LightboxContext)
  if (!context) {
    throw new Error("useLightbox must be used within a LightboxProvider")
  }
  return context
}

interface LightboxProviderProps {
  children: React.ReactNode
  items?: MediaItem[]
  defaultIndex?: number
}

function LightboxProvider({ children, items = [], defaultIndex = 0 }: LightboxProviderProps) {
  const [currentIndex, setCurrentIndex] = React.useState(defaultIndex)
  const [isOpen, setIsOpen] = React.useState(false)
  const [zoom, setZoom] = React.useState(1)

  const value = React.useMemo(
    () => ({
      items,
      currentIndex,
      setCurrentIndex,
      isOpen,
      setIsOpen,
      zoom,
      setZoom,
    }),
    [items, currentIndex, isOpen, zoom]
  )

  return (
    <LightboxContext.Provider value={value}>
      {children}
    </LightboxContext.Provider>
  )
}

interface LightboxTriggerProps extends React.HTMLAttributes<HTMLDivElement> {
  index?: number
  asChild?: boolean
}

const LightboxTrigger = React.forwardRef<HTMLDivElement, LightboxTriggerProps>(
  ({ index = 0, asChild, children, onClick, ...props }, ref) => {
    const { setCurrentIndex, setIsOpen, setZoom } = useLightbox()

    const handleClick = (e: React.MouseEvent<HTMLDivElement>) => {
      setCurrentIndex(index)
      setIsOpen(true)
      setZoom(1)
      onClick?.(e)
    }

    if (asChild) {
      const child = children as React.ReactElement<any>
      // Filter out drag events to avoid conflicts
      const { onDrag, onDragStart, onDragEnd, onDragOver, onDrop, ...filteredProps } = props
      return React.cloneElement(child, {
        ...child.props,
        ...filteredProps,
        onClick: handleClick,
      })
    }

    // Filter out drag events to avoid conflicts
    const { onDrag, onDragStart, onDragEnd, onDragOver, onDrop, ...filteredProps } = props
    return (
      <div ref={ref} onClick={handleClick} className="cursor-pointer" {...filteredProps}>
        {children}
      </div>
    )
  }
)
LightboxTrigger.displayName = "LightboxTrigger"

interface LightboxContentProps
  extends React.HTMLAttributes<HTMLDivElement>,
    VariantProps<typeof lightboxVariants> {
  showNavigation?: boolean
  showZoomControls?: boolean
  showDownload?: boolean
  showFullscreen?: boolean
  showThumbnails?: boolean
  enableKeyboardNavigation?: boolean
  enableSwipeGestures?: boolean
  animationDuration?: number
  autoPlayVideo?: boolean
  onClose?: () => void
}

const LightboxContent = React.forwardRef<HTMLDivElement, LightboxContentProps>(
  ({
    className,
    backdrop,
    showNavigation = true,
    showZoomControls = true,
    showDownload = true,
    showFullscreen = true,
    showThumbnails = false,
    enableKeyboardNavigation = true,
    enableSwipeGestures = true,
    animationDuration = 300,
    autoPlayVideo = false,
    onClose,
    ...restProps
  }, ref) => {
    // Filter out drag and animation events to avoid conflicts with Framer Motion
    const { onDrag, onDragStart, onDragEnd, onDragOver, onDrop, onAnimationStart, onAnimationEnd, onAnimationIteration, ...props } = restProps
    const { items, currentIndex, setCurrentIndex, isOpen, setIsOpen, zoom, setZoom } = useLightbox()
    const [isLoading, setIsLoading] = React.useState(true)
    const [isPlaying, setIsPlaying] = React.useState(false)
    const [isMuted, setIsMuted] = React.useState(true)
    const [isFullscreen, setIsFullscreen] = React.useState(false)
    const [position, setPosition] = React.useState({ x: 0, y: 0 })
    const [isDragging, setIsDragging] = React.useState(false)
    const containerRef = React.useRef<HTMLDivElement>(null)
    const videoRef = React.useRef<HTMLVideoElement>(null)

    const currentItem = items[currentIndex]

    // Auto-play video when item changes
    React.useEffect(() => {
      if (currentItem?.type === "video" && autoPlayVideo) {
        setIsPlaying(true)
        setIsMuted(true) // Mute for autoplay policy
      } else {
        setIsPlaying(false)
      }
    }, [currentIndex, currentItem, autoPlayVideo])

    // Keyboard navigation
    React.useEffect(() => {
      if (!enableKeyboardNavigation || !isOpen) return

      const handleKeyDown = (e: KeyboardEvent) => {
        switch (e.key) {
          case "ArrowLeft":
            handlePrevious()
            break
          case "ArrowRight":
            handleNext()
            break
          case "Escape":
            handleClose()
            break
          case "+":
          case "=":
            handleZoomIn()
            break
          case "-":
            handleZoomOut()
            break
          case " ":
            if (currentItem?.type === "video") {
              e.preventDefault()
              setIsPlaying(!isPlaying)
            }
            break
        }
      }

      window.addEventListener("keydown", handleKeyDown)
      return () => window.removeEventListener("keydown", handleKeyDown)
    }, [isOpen, currentIndex, isPlaying, enableKeyboardNavigation])

    // Handle video play/pause
    React.useEffect(() => {
      if (videoRef.current && currentItem?.type === "video") {
        if (isPlaying) {
          videoRef.current.play().catch(err => {
            console.error("Video play error:", err)
            setIsPlaying(false)
          })
        } else {
          videoRef.current.pause()
        }
      }
    }, [isPlaying, currentItem])

    const handleClose = () => {
      setIsOpen(false)
      setZoom(1)
      setPosition({ x: 0, y: 0 })
      onClose?.()
    }

    const handlePrevious = () => {
      setCurrentIndex(currentIndex > 0 ? currentIndex - 1 : items.length - 1)
      setZoom(1)
      setPosition({ x: 0, y: 0 })
      setIsLoading(true)
    }

    const handleNext = () => {
      setCurrentIndex(currentIndex < items.length - 1 ? currentIndex + 1 : 0)
      setZoom(1)
      setPosition({ x: 0, y: 0 })
      setIsLoading(true)
    }

    const handleZoomIn = () => {
      setZoom(Math.min(zoom + 0.5, 3))
    }

    const handleZoomOut = () => {
      setZoom(Math.max(zoom - 0.5, 0.5))
      if (zoom - 0.5 <= 1) {
        setPosition({ x: 0, y: 0 })
      }
    }

    const handleDownload = () => {
      if (currentItem) {
        const link = document.createElement("a")
        link.href = currentItem.src
        link.download = currentItem.alt || "download"
        link.click()
      }
    }

    const handleFullscreen = () => {
      if (!isFullscreen) {
        containerRef.current?.requestFullscreen()
      } else {
        document.exitFullscreen()
      }
      setIsFullscreen(!isFullscreen)
    }

    const handleMouseDown = (e: React.MouseEvent) => {
      if (zoom > 1) {
        setIsDragging(true)
      }
    }

    const handleMouseMove = (e: React.MouseEvent) => {
      if (isDragging && zoom > 1) {
        setPosition({
          x: position.x + e.movementX,
          y: position.y + e.movementY,
        })
      }
    }

    const handleMouseUp = () => {
      setIsDragging(false)
    }

    if (!currentItem) return null

    return (
      <DialogPrimitive.Root open={isOpen} onOpenChange={setIsOpen}>
        <AnimatePresence>
          {isOpen && (
            <DialogPrimitive.Portal forceMount>
              <DialogPrimitive.Overlay asChild>
                <motion.div
                  initial={{ opacity: 0 }}
                  animate={{ opacity: 1 }}
                  exit={{ opacity: 0 }}
                  transition={{ duration: animationDuration / 1000 }}
                  className={cn(lightboxVariants({ backdrop }), className)}
                  ref={ref}
                  onClick={(e) => {
                    if (e.target === e.currentTarget) {
                      handleClose()
                    }
                  }}
                  {...props}
                >
                  <div
                    ref={containerRef}
                    className="relative w-full h-full flex items-center justify-center pointer-events-none"
                    onMouseMove={handleMouseMove}
                    onMouseUp={handleMouseUp}
                    onMouseLeave={handleMouseUp}
                  >
                    {/* Click catcher for backdrop */}
                    <div className="absolute inset-0 pointer-events-auto" onClick={handleClose} />
                    {/* Close button */}
                    <button
                      onClick={handleClose}
                      className="absolute top-4 right-4 z-50 p-2 rounded-full bg-black/50 text-white hover:bg-black/70 transition-colors pointer-events-auto"
                    >
                      <X className="h-5 w-5" />
                    </button>

                    {/* Navigation */}
                    {showNavigation && items.length > 1 && (
                      <>
                        <button
                          onClick={handlePrevious}
                          className="absolute left-4 z-50 p-2 rounded-full bg-black/50 text-white hover:bg-black/70 transition-colors pointer-events-auto"
                        >
                          <ChevronLeft className="h-5 w-5" />
                        </button>
                        <button
                          onClick={handleNext}
                          className="absolute right-4 z-50 p-2 rounded-full bg-black/50 text-white hover:bg-black/70 transition-colors pointer-events-auto"
                        >
                          <ChevronRight className="h-5 w-5" />
                        </button>
                      </>
                    )}

                    {/* Controls */}
                    <div 
                      className="absolute bottom-4 left-1/2 -translate-x-1/2 z-50 flex items-center gap-2 pointer-events-auto">
                      {showZoomControls && currentItem.type === "image" && (
                        <>
                          <button
                            onClick={handleZoomOut}
                            className="p-2 rounded-full bg-black/50 text-white hover:bg-black/70 transition-colors"
                          >
                            <ZoomOut className="h-4 w-4" />
                          </button>
                          <span className="px-3 py-1 rounded-full bg-black/50 text-white text-sm">
                            {Math.round(zoom * 100)}%
                          </span>
                          <button
                            onClick={handleZoomIn}
                            className="p-2 rounded-full bg-black/50 text-white hover:bg-black/70 transition-colors"
                          >
                            <ZoomIn className="h-4 w-4" />
                          </button>
                        </>
                      )}

                      {currentItem.type === "video" && (
                        <>
                          <button
                            onClick={() => {
                              setIsPlaying(!isPlaying)
                              if (!isPlaying && videoRef.current) {
                                videoRef.current.play().catch(err => {
                                  console.error("Play failed:", err)
                                })
                              }
                            }}
                            className="p-2 rounded-full bg-black/50 text-white hover:bg-black/70 transition-colors"
                          >
                            {isPlaying ? <Pause className="h-4 w-4" /> : <Play className="h-4 w-4" />}
                          </button>
                          <button
                            onClick={() => {
                              setIsMuted(!isMuted)
                              if (videoRef.current) {
                                videoRef.current.muted = !isMuted
                              }
                            }}
                            className="p-2 rounded-full bg-black/50 text-white hover:bg-black/70 transition-colors"
                          >
                            {isMuted ? <VolumeX className="h-4 w-4" /> : <Volume2 className="h-4 w-4" />}
                          </button>
                        </>
                      )}

                      {showDownload && (
                        <button
                          onClick={handleDownload}
                          className="p-2 rounded-full bg-black/50 text-white hover:bg-black/70 transition-colors"
                        >
                          <Download className="h-4 w-4" />
                        </button>
                      )}

                      {showFullscreen && (
                        <button
                          onClick={handleFullscreen}
                          className="p-2 rounded-full bg-black/50 text-white hover:bg-black/70 transition-colors"
                        >
                          <Maximize2 className="h-4 w-4" />
                        </button>
                      )}
                    </div>

                    {/* Media content */}
                    <motion.div
                      initial={{ scale: 0.9, opacity: 0 }}
                      animate={{ scale: 1, opacity: 1 }}
                      exit={{ scale: 0.9, opacity: 0 }}
                      transition={{ duration: animationDuration / 1000 }}
                      className="relative flex items-center justify-center pointer-events-auto"
                      style={{
                        transform: `scale(${zoom}) translate(${position.x / zoom}px, ${position.y / zoom}px)`,
                        cursor: zoom > 1 ? (isDragging ? "grabbing" : "grab") : "auto",
                      }}
                      onMouseDown={handleMouseDown}
                    >
                      {isLoading && (
                        <div className="absolute inset-0 flex items-center justify-center">
                          <Loader2 className="h-8 w-8 animate-spin text-white" />
                        </div>
                      )}

                      {currentItem.type === "image" ? (
                        <img
                          src={currentItem.src}
                          alt={currentItem.alt}
                          className="max-w-[90vw] max-h-[90vh] w-auto h-auto object-contain select-none"
                          onLoad={() => setIsLoading(false)}
                          draggable={false}
                        />
                      ) : (
                        <video
                          ref={videoRef}
                          src={currentItem.src}
                          poster={currentItem.poster}
                          muted={isMuted}
                          controls={true}
                          autoPlay={autoPlayVideo && isPlaying}
                          playsInline
                          className="max-w-[90vw] max-h-[90vh] w-auto h-auto"
                          onLoadedData={() => {
                            setIsLoading(false)
                            if (autoPlayVideo && isPlaying && videoRef.current) {
                              videoRef.current.play().catch(err => {
                                console.error("Autoplay failed:", err)
                              })
                            }
                          }}
                          onError={(e) => {
                            console.error("Video error:", e)
                            setIsLoading(false)
                          }}
                        />
                      )}
                    </motion.div>

                    {/* Info overlay */}
                    {(currentItem.title || currentItem.description) && (
                      <motion.div
                        initial={{ opacity: 0, y: 20 }}
                        animate={{ opacity: 1, y: 0 }}
                        className="absolute top-4 left-4 max-w-md pointer-events-auto"
                      >
                        {currentItem.title && (
                          <h3 className="text-white text-xl font-semibold mb-1">{currentItem.title}</h3>
                        )}
                        {currentItem.description && (
                          <p className="text-white/80 text-sm">{currentItem.description}</p>
                        )}
                      </motion.div>
                    )}

                    {/* Thumbnails */}
                    {showThumbnails && items.length > 1 && (
                      <motion.div
                        initial={{ opacity: 0, y: 20 }}
                        animate={{ opacity: 1, y: 0 }}
                        className="absolute bottom-20 left-0 right-0 flex justify-center z-50 pointer-events-auto"
                      >
                        <div className="flex gap-2 p-2 bg-black/70 backdrop-blur-sm rounded-lg max-w-[80vw] overflow-x-auto">
                          {items.map((item, index) => (
                          <button
                            key={index}
                            onClick={() => {
                              setCurrentIndex(index)
                              setZoom(1)
                              setPosition({ x: 0, y: 0 })
                            }}
                            className={cn(
                              "w-16 h-16 rounded overflow-hidden transition-all",
                              index === currentIndex
                                ? "ring-2 ring-white scale-110"
                                : "opacity-60 hover:opacity-100"
                            )}
                          >
                            {item.type === "image" ? (
                              <img
                                src={item.thumbnail || item.src}
                                alt={item.alt}
                                className="w-full h-full object-cover"
                              />
                            ) : (
                              <div className="w-full h-full bg-black/50 flex items-center justify-center">
                                <Play className="h-4 w-4 text-white" />
                              </div>
                            )}
                          </button>
                          ))}
                        </div>
                      </motion.div>
                    )}
                  </div>
                </motion.div>
              </DialogPrimitive.Overlay>
            </DialogPrimitive.Portal>
          )}
        </AnimatePresence>
      </DialogPrimitive.Root>
    )
  }
)
LightboxContent.displayName = "LightboxContent"

// Simple lightbox for single items
interface SimpleLightboxProps extends Omit<LightboxContentProps, "items"> {
  src: string
  type?: "image" | "video"
  alt?: string
  poster?: string
  title?: string
  description?: string
  children: React.ReactNode
  autoPlayVideo?: boolean
}

function SimpleLightbox({
  src,
  type = "image",
  alt,
  poster,
  title,
  description,
  children,
  ...props
}: SimpleLightboxProps) {
  const items: MediaItem[] = [{ type, src, alt, poster, title, description }]

  return (
    <LightboxProvider items={items}>
      <LightboxTrigger>{children}</LightboxTrigger>
      <LightboxContent {...props} />
    </LightboxProvider>
  )
}

export {
  LightboxProvider,
  LightboxTrigger,
  LightboxContent,
  SimpleLightbox,
  type MediaItem,
  type LightboxContentProps,
}

// Export as MoonUI components
export {
  LightboxProvider as MoonUILightboxProviderPro,
  LightboxTrigger as MoonUILightboxTriggerPro,
  LightboxContent as MoonUILightboxContentPro,
  SimpleLightbox as MoonUILightboxPro,
}