"use client"

import * as React from "react"
import { cva, type VariantProps } from "class-variance-authority"
import { motion, AnimatePresence } from "framer-motion"
import { Grid3x3, LayoutGrid, Square, Columns, Filter, SortAsc, Image as ImageIcon, Video, X, Loader2 } from "lucide-react"

import { cn } from "../../lib/utils"
import { 
  MoonUILightboxProviderPro, 
  MoonUILightboxTriggerPro, 
  MoonUILightboxContentPro,
  type MediaItem 
} from "./lightbox"

/**
 * Premium Media Gallery Component
 * 
 * Advanced gallery component for displaying images and videos in responsive layouts
 * with filtering, sorting, lightbox integration, and smooth animations.
 * Perfect for portfolios, product galleries, and media showcases.
 */

const galleryVariants = cva(
  "w-full",
  {
    variants: {
      layout: {
        grid: "grid gap-4",
        masonry: "",
        horizontal: "flex overflow-x-auto gap-4 pb-4 snap-x snap-mandatory [&>*]:snap-center",
        justified: "flex flex-wrap gap-2",
      },
      columns: {
        1: "grid-cols-1",
        2: "grid-cols-1 sm:grid-cols-2",
        3: "grid-cols-1 sm:grid-cols-2 md:grid-cols-3",
        4: "grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4",
        5: "grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5",
        6: "grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6",
      },
    },
    defaultVariants: {
      layout: "grid",
      columns: 3,
    },
  }
)

const galleryItemVariants = cva(
  "relative overflow-hidden cursor-pointer group",
  {
    variants: {
      variant: {
        default: "rounded-lg",
        card: "rounded-lg shadow-sm border border-border bg-card",
        ghost: "rounded-lg hover:bg-accent/50",
        outline: "rounded-lg border-2 border-transparent hover:border-primary",
        glass: "rounded-lg backdrop-blur-md bg-white/10 border border-white/20",
      },
      aspectRatio: {
        square: "aspect-square",
        video: "aspect-video",
        portrait: "aspect-[3/4]",
        auto: "",
      },
      hover: {
        none: "",
        zoom: "transition-transform duration-300 hover:scale-105",
        lift: "transition-all duration-300 hover:-translate-y-1 hover:shadow-lg",
        glow: "transition-all duration-300 hover:shadow-lg hover:shadow-primary/20",
      },
    },
    defaultVariants: {
      variant: "default",
      aspectRatio: "square",
      hover: "zoom",
    },
  }
)

interface GalleryCategory {
  id: string
  label: string
  icon?: React.ReactNode
}

interface GallerySortOption {
  id: string
  label: string
  compareFn: (a: MediaItem, b: MediaItem) => number
}

interface MoonUIMediaGalleryProProps
  extends React.HTMLAttributes<HTMLDivElement>,
    VariantProps<typeof galleryVariants> {
  items: MediaItem[]
  variant?: VariantProps<typeof galleryItemVariants>["variant"]
  aspectRatio?: VariantProps<typeof galleryItemVariants>["aspectRatio"]
  hover?: VariantProps<typeof galleryItemVariants>["hover"]
  enableLightbox?: boolean
  enableFiltering?: boolean
  enableSorting?: boolean
  categories?: GalleryCategory[]
  sortOptions?: GallerySortOption[]
  defaultCategory?: string
  defaultSort?: string
  showItemType?: boolean
  showOverlay?: boolean
  overlayContent?: (item: MediaItem, index: number) => React.ReactNode
  loadingState?: boolean
  skeletonCount?: number
  emptyState?: React.ReactNode
  onItemClick?: (item: MediaItem, index: number) => void
  lazyLoad?: boolean
  infiniteScroll?: boolean
  onLoadMore?: () => void
  hasMore?: boolean
  lightboxProps?: Partial<React.ComponentProps<typeof MoonUILightboxContentPro>>
}

const MoonUIMediaGalleryPro = React.forwardRef<
  HTMLDivElement,
  MoonUIMediaGalleryProProps
>(({
  className,
  items,
  layout,
  columns,
  variant,
  aspectRatio,
  hover,
  enableLightbox = true,
  enableFiltering = false,
  enableSorting = false,
  categories = [],
  sortOptions = [],
  defaultCategory = "all",
  defaultSort = "default",
  showItemType = true,
  showOverlay = true,
  overlayContent,
  loadingState = false,
  skeletonCount = 6,
  emptyState,
  onItemClick,
  lazyLoad = true,
  infiniteScroll = false,
  onLoadMore,
  hasMore = false,
  lightboxProps,
  ...props
}, ref) => {
  const [activeCategory, setActiveCategory] = React.useState(defaultCategory)
  const [activeSort, setActiveSort] = React.useState(defaultSort)
  const [showFilters, setShowFilters] = React.useState(false)
  const [loadedImages, setLoadedImages] = React.useState<Set<number>>(new Set())
  const observerRef = React.useRef<IntersectionObserver | null>(null)
  const loadMoreRef = React.useRef<HTMLDivElement>(null)

  // Filter items by category
  const filteredItems = React.useMemo(() => {
    if (!enableFiltering || activeCategory === "all") return items

    return items.filter(item => {
      // Check if item has category property
      if ('category' in item && typeof item.category === 'string') {
        return item.category === activeCategory
      }
      // Fallback to type-based filtering
      if (activeCategory === "image") return item.type === "image"
      if (activeCategory === "video") return item.type === "video"
      return true
    })
  }, [items, activeCategory, enableFiltering])

  // Sort items
  const sortedItems = React.useMemo(() => {
    if (!enableSorting || activeSort === "default") return filteredItems

    const sortOption = sortOptions.find(opt => opt.id === activeSort)
    if (!sortOption) return filteredItems

    return [...filteredItems].sort(sortOption.compareFn)
  }, [filteredItems, activeSort, enableSorting, sortOptions])

  // Default categories if none provided
  const defaultCategories: GalleryCategory[] = [
    { id: "all", label: "All" },
    { id: "image", label: "Images", icon: <ImageIcon className="h-4 w-4" /> },
    { id: "video", label: "Videos", icon: <Video className="h-4 w-4" /> },
  ]

  const finalCategories = categories.length > 0 ? categories : defaultCategories

  // Lazy loading
  React.useEffect(() => {
    if (!lazyLoad) return

    observerRef.current = new IntersectionObserver(
      (entries) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
            const index = parseInt(entry.target.getAttribute("data-index") || "0")
            setLoadedImages(prev => new Set(prev).add(index))
          }
        })
      },
      { rootMargin: "50px" }
    )

    return () => {
      observerRef.current?.disconnect()
    }
  }, [lazyLoad])

  // Infinite scroll
  React.useEffect(() => {
    if (!infiniteScroll || !onLoadMore || !hasMore) return

    const observer = new IntersectionObserver(
      (entries) => {
        if (entries[0].isIntersecting) {
          onLoadMore()
        }
      },
      { rootMargin: "100px" }
    )

    if (loadMoreRef.current) {
      observer.observe(loadMoreRef.current)
    }

    return () => observer.disconnect()
  }, [infiniteScroll, onLoadMore, hasMore])

  const handleItemClick = (item: MediaItem, index: number) => {
    if (onItemClick) {
      onItemClick(item, index)
    }
  }

  const renderGalleryItem = (item: MediaItem, index: number) => {
    const isLoaded = !lazyLoad || loadedImages.has(index)

    const itemContent = (
      <motion.div
        key={index}
        className={cn(
          galleryItemVariants({ 
            variant, 
            aspectRatio: layout === "masonry" || layout === "justified" ? "auto" : aspectRatio, 
            hover 
          }),
          layout === "masonry" && "break-inside-avoid mb-4 inline-block w-full",
          layout === "justified" && "flex-grow"
        )}
        style={layout === "justified" ? { flexBasis: "200px", maxWidth: "400px" } : undefined}
        initial={{ opacity: 0, scale: 0.9 }}
        animate={{ opacity: 1, scale: 1 }}
        transition={{ duration: 0.3, delay: index * 0.05 }}
        data-index={index}
        ref={(el) => {
          if (el && observerRef.current && !loadedImages.has(index)) {
            observerRef.current.observe(el)
          }
        }}
        onClick={() => handleItemClick(item, index)}
      >
        {item.type === "image" ? (
          <div className={cn(
            "relative w-full",
            layout === "masonry" || layout === "justified" ? "" : "h-full"
          )}>
            <img
              src={item.thumbnail || item.src}
              alt={item.alt || `Gallery item ${index + 1}`}
              className={cn(
                "w-full object-cover",
                layout === "masonry" ? "h-auto" : "h-full",
                isLoaded ? "opacity-100" : "opacity-0",
                "transition-opacity duration-300"
              )}
              loading={lazyLoad ? "lazy" : undefined}
              onLoad={() => setLoadedImages(prev => new Set(prev).add(index))}
            />
            {!isLoaded && (
              <div className={cn(
                "absolute inset-0 w-full bg-muted animate-pulse",
                layout === "masonry" ? "h-64" : "h-full",
                layout === "masonry" && "aspect-[3/4]"
              )} />
            )}
          </div>
        ) : (
          <div className={cn(
            "relative w-full bg-black",
            layout === "masonry" ? "" : "h-full"
          )}>
            {isLoaded && (item.thumbnail || item.poster) && (
              <img
                src={item.thumbnail || item.poster}
                alt={item.alt || `Video thumbnail ${index + 1}`}
                className={cn(
                  "w-full object-cover",
                  layout === "masonry" ? "h-auto" : "h-full"
                )}
                loading={lazyLoad ? "lazy" : undefined}
              />
            )}
            <div className="absolute inset-0 flex items-center justify-center">
              <div className="w-12 h-12 bg-black/70 rounded-full flex items-center justify-center">
                <Video className="h-6 w-6 text-white" />
              </div>
            </div>
          </div>
        )}

        {/* Overlay */}
        {showOverlay && (
          <div className="absolute inset-0 bg-gradient-to-t from-black/70 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300">
            {overlayContent ? (
              overlayContent(item, index)
            ) : (
              <div className="absolute bottom-0 left-0 right-0 p-4 text-white">
                {item.title && (
                  <h3 className="text-sm font-semibold mb-1">{item.title}</h3>
                )}
                {item.description && (
                  <p className="text-xs opacity-90 line-clamp-2">{item.description}</p>
                )}
              </div>
            )}

            {showItemType && (
              <div className="absolute top-2 right-2">
                <div className="w-8 h-8 bg-white/20 backdrop-blur-sm rounded-full flex items-center justify-center">
                  {item.type === "image" ? (
                    <ImageIcon className="h-4 w-4 text-white" />
                  ) : (
                    <Video className="h-4 w-4 text-white" />
                  )}
                </div>
              </div>
            )}
          </div>
        )}
      </motion.div>
    )

    // If lightbox is enabled and we're in the main gallery content, wrap with trigger
    if (enableLightbox) {
      return (
        <MoonUILightboxTriggerPro key={index} index={index}>
          {itemContent}
        </MoonUILightboxTriggerPro>
      )
    }

    return itemContent
  }

  const renderSkeleton = () => (
    <div className={cn(galleryItemVariants({ variant, aspectRatio }))}>
      <div className="w-full h-full bg-muted animate-pulse" />
    </div>
  )

  const galleryContent = (
    <>
      {/* Filters and Sorting */}
      {(enableFiltering || enableSorting) && (
        <div className="mb-6">
          <div className="flex items-center justify-between mb-4">
            <div className="flex items-center gap-4">
              {enableFiltering && (
                <button
                  onClick={() => setShowFilters(!showFilters)}
                  className={cn(
                    "flex items-center gap-2 px-4 py-2 rounded-lg border transition-colors",
                    showFilters
                      ? "bg-primary text-primary-foreground border-primary"
                      : "bg-background border-border hover:bg-accent"
                  )}
                >
                  <Filter className="h-4 w-4" />
                  Filters
                </button>
              )}
              {enableSorting && sortOptions.length > 0 && (
                <select
                  value={activeSort}
                  onChange={(e) => setActiveSort(e.target.value)}
                  className="px-4 py-2 rounded-lg border bg-background"
                >
                  <option value="default">Default order</option>
                  {sortOptions.map(option => (
                    <option key={option.id} value={option.id}>
                      {option.label}
                    </option>
                  ))}
                </select>
              )}
            </div>
            <div className="text-sm text-muted-foreground">
              {sortedItems.length} items
            </div>
          </div>

          {/* Category filters */}
          <AnimatePresence>
            {showFilters && enableFiltering && (
              <motion.div
                initial={{ height: 0, opacity: 0 }}
                animate={{ height: "auto", opacity: 1 }}
                exit={{ height: 0, opacity: 0 }}
                transition={{ duration: 0.2 }}
                className="overflow-hidden"
              >
                <div className="flex flex-wrap gap-2 pb-4">
                  {finalCategories.map(category => (
                    <button
                      key={category.id}
                      onClick={() => setActiveCategory(category.id)}
                      className={cn(
                        "flex items-center gap-2 px-3 py-1.5 rounded-full text-sm transition-colors",
                        activeCategory === category.id
                          ? "bg-primary text-primary-foreground"
                          : "bg-muted hover:bg-accent"
                      )}
                    >
                      {category.icon}
                      {category.label}
                    </button>
                  ))}
                </div>
              </motion.div>
            )}
          </AnimatePresence>
        </div>
      )}

      {/* Gallery */}
      <div
        ref={ref}
        className={cn(
          layout === "masonry" 
            ? "columns-1 sm:columns-2 md:columns-3 lg:columns-4 gap-4" 
            : galleryVariants({ layout, columns }),
          className
        )}
        style={layout === "masonry" ? { columnGap: "1rem" } : undefined}
        {...props}
      >
        {loadingState ? (
          <>
            {Array.from({ length: skeletonCount }).map((_, i) => (
              <React.Fragment key={i}>{renderSkeleton()}</React.Fragment>
            ))}
          </>
        ) : sortedItems.length > 0 ? (
          sortedItems.map((item, index) => renderGalleryItem(item, index))
        ) : (
          emptyState || (
            <div className="col-span-full flex flex-col items-center justify-center py-12 text-center">
              <ImageIcon className="h-12 w-12 text-muted-foreground mb-4" />
              <p className="text-muted-foreground">No media items found</p>
            </div>
          )
        )}
      </div>

      {/* Load more trigger */}
      {infiniteScroll && hasMore && (
        <div ref={loadMoreRef} className="flex justify-center py-8">
          <Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
        </div>
      )}
    </>
  )

  if (enableLightbox) {
    return (
      <MoonUILightboxProviderPro items={sortedItems}>
        {galleryContent}
        <MoonUILightboxContentPro showThumbnails showNavigation backdrop="blur" {...lightboxProps} />
      </MoonUILightboxProviderPro>
    )
  }

  return galleryContent
})
MoonUIMediaGalleryPro.displayName = "MoonUIMediaGalleryPro"

// Gallery item component for custom layouts
interface MoonUIGalleryItemProProps
  extends React.HTMLAttributes<HTMLDivElement>,
    VariantProps<typeof galleryItemVariants> {
  item: MediaItem
  index?: number
  showType?: boolean
  showOverlay?: boolean
  overlayContent?: React.ReactNode
  onLoad?: () => void
}

const MoonUIGalleryItemPro = React.forwardRef<
  HTMLDivElement,
  MoonUIGalleryItemProProps
>(({
  className,
  item,
  index = 0,
  variant,
  aspectRatio,
  hover,
  showType = true,
  showOverlay = true,
  overlayContent,
  onLoad,
  ...props
}, ref) => {
  const [isLoaded, setIsLoaded] = React.useState(false)

  const handleLoad = () => {
    setIsLoaded(true)
    onLoad?.()
  }

  return (
    <div
      ref={ref}
      className={cn(galleryItemVariants({ variant, aspectRatio, hover }), className)}
      {...props}
    >
      {item.type === "image" ? (
        <img
          src={item.src}
          alt={item.alt || `Gallery item ${index + 1}`}
          className={cn(
            "w-full h-full object-cover transition-opacity duration-300",
            isLoaded ? "opacity-100" : "opacity-0"
          )}
          onLoad={handleLoad}
        />
      ) : (
        <div className="relative w-full h-full bg-black">
          {item.poster && (
            <img
              src={item.poster}
              alt={item.alt || `Video thumbnail ${index + 1}`}
              className="w-full h-full object-cover"
              onLoad={handleLoad}
            />
          )}
          <div className="absolute inset-0 flex items-center justify-center">
            <div className="w-12 h-12 bg-black/70 rounded-full flex items-center justify-center">
              <Video className="h-6 w-6 text-white" />
            </div>
          </div>
        </div>
      )}

      {!isLoaded && (
        <div className="absolute inset-0 bg-muted animate-pulse" />
      )}

      {showOverlay && isLoaded && (
        <div className="absolute inset-0 bg-gradient-to-t from-black/70 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300">
          {overlayContent || (
            <div className="absolute bottom-0 left-0 right-0 p-4 text-white">
              {item.title && (
                <h3 className="text-sm font-semibold mb-1">{item.title}</h3>
              )}
              {item.description && (
                <p className="text-xs opacity-90 line-clamp-2">{item.description}</p>
              )}
            </div>
          )}

          {showType && (
            <div className="absolute top-2 right-2">
              <div className="w-8 h-8 bg-white/20 backdrop-blur-sm rounded-full flex items-center justify-center">
                {item.type === "image" ? (
                  <ImageIcon className="h-4 w-4 text-white" />
                ) : (
                  <Video className="h-4 w-4 text-white" />
                )}
              </div>
            </div>
          )}
        </div>
      )}
    </div>
  )
})
MoonUIGalleryItemPro.displayName = "MoonUIGalleryItemPro"

export {
  MoonUIMediaGalleryPro,
  MoonUIGalleryItemPro,
  galleryVariants,
  galleryItemVariants,
  type GalleryCategory,
  type GallerySortOption,
}

// Clean exports
export {
  MoonUIMediaGalleryPro as MediaGallery,
  MoonUIGalleryItemPro as GalleryItem,
}