import { useEffect, useState, useRef, useCallback } from 'react'
import { useGesture } from '@use-gesture/react'
import {
  ChevronLeft,
  ChevronRight,
  MoreHorizontal,
  X,
  Download,
  Copy,
  ZoomIn,
  ZoomOut,
  RotateCcw,
  Info,
  Film,
  Image as ImageIcon,
  HardDrive,
  Calendar,
  Clock,
  Play,
  Pause,
  Shuffle,
  PictureInPicture2,
} from 'lucide-react'
import { notificationManager } from '../lib/notificationManager'
import { MediaGalleryItem } from '../lib/api'

// Format bytes to human readable
function formatBytes(bytes: number | null | undefined): string {
  if (!bytes || bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`
}

// Format date
function formatDate(dateStr: string | null | undefined): string {
  if (!dateStr) return ''
  const date = new Date(dateStr)
  return date.toLocaleDateString('en-US', {
    year: 'numeric',
    month: 'short',
    day: 'numeric',
    hour: '2-digit',
    minute: '2-digit',
  })
}

// Format video duration
function formatDuration(seconds: number | null | undefined): string {
  if (!seconds || seconds <= 0) return ''
  const h = Math.floor(seconds / 3600)
  const m = Math.floor((seconds % 3600) / 60)
  const s = Math.floor(seconds % 60)
  if (h > 0) return `${h}:${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`
  return `${m}:${s.toString().padStart(2, '0')}`
}

// Format resolution with quality label based on shorter side
function formatResolution(width: number | undefined, height: number | undefined): string {
  if (!width || !height) return ''
  const shorter = Math.min(width, height)
  let label = ''
  if (shorter >= 2160) label = '4K'
  else if (shorter >= 1440) label = '1440p'
  else if (shorter >= 1080) label = '1080p'
  else if (shorter >= 720) label = '720p'
  else if (shorter >= 480) label = '480p'
  else if (shorter >= 360) label = '360p'
  else label = `${shorter}p`
  return `${width} x ${height} (${label})`
}

// Check if item is a video
function isVideoFile(item: MediaGalleryItem): boolean {
  if (item.media_type === 'video') return true
  const videoExts = ['mp4', 'webm', 'mkv', 'avi', 'mov', 'wmv', 'flv', 'm4v', 'ts']
  const ext = item.filename?.split('.').pop()?.toLowerCase() || ''
  return videoExts.includes(ext)
}

interface GalleryLightboxProps {
  items: MediaGalleryItem[]
  currentIndex: number
  onClose: () => void
  onNavigate: (index: number) => void
  autoPlayVideo?: boolean
  initialSlideshow?: boolean
  initialInterval?: number
  totalCount?: number
  hasMore?: boolean
  onLoadMore?: () => void
  onShuffleChange?: (enabled: boolean) => void
  isShuffled?: boolean
}

export default function GalleryLightbox({
  items,
  currentIndex,
  onClose,
  onNavigate,
  autoPlayVideo = false,
  initialSlideshow = false,
  initialInterval,
  totalCount,
  hasMore,
  onLoadMore,
  onShuffleChange,
  isShuffled,
}: GalleryLightboxProps) {
  const currentItem = items[currentIndex]
  const isCurrentVideo = currentItem ? isVideoFile(currentItem) : false

  // Mobile detection (landscape phones get desktop layout)
  const [isMobile, setIsMobile] = useState(false)
  const [isLandscape, setIsLandscape] = useState(false)
  useEffect(() => {
    const check = () => {
      const hasTouch = 'ontouchstart' in window || navigator.maxTouchPoints > 0
      const portrait = window.innerWidth < 768
      const landscapePhone = hasTouch && window.innerHeight < 500
      setIsMobile(portrait && !landscapePhone)
      setIsLandscape(landscapePhone && !portrait)
    }
    check()
    window.addEventListener('resize', check)
    return () => window.removeEventListener('resize', check)
  }, [])

  const [menuOpen, setMenuOpen] = useState(false)
  const [showMetadata, setShowMetadata] = useState(false)
  const showControls = true

  // Embedded file metadata (from ffprobe/exiftool)
  const [embeddedMetadata, setEmbeddedMetadata] = useState<{
    title?: string | null
    artist?: string | null
    description?: string | null
    comment?: string | null
    date?: string | null
    source?: string | null
  } | null>(null)
  const [embeddedMetadataLoading, setEmbeddedMetadataLoading] = useState(false)

  // Fetch embedded metadata when metadata panel is shown
  useEffect(() => {
    if (!showMetadata || !currentItem?.file_path) {
      setEmbeddedMetadata(null)
      return
    }

    const fetchEmbeddedMetadata = async () => {
      setEmbeddedMetadataLoading(true)
      try {
        const response = await fetch(
          currentItem.file_token
            ? `/api/media/embedded-metadata?t=${encodeURIComponent(currentItem.file_token)}`
            : `/api/media/embedded-metadata?file_path=${encodeURIComponent(currentItem.file_path)}`,
          { credentials: 'include' }
        )
        if (response.ok) {
          const data = await response.json()
          if (data.title || data.description || data.artist || data.comment || data.source) {
            setEmbeddedMetadata(data)
          } else {
            setEmbeddedMetadata(null)
          }
        }
      } catch {
        setEmbeddedMetadata(null)
      } finally {
        setEmbeddedMetadataLoading(false)
      }
    }

    fetchEmbeddedMetadata()
  }, [currentItem?.file_path, showMetadata])

  // Slideshow state
  const [slideshowPlaying, setSlideshowPlaying] = useState(initialSlideshow)
  const [slideshowInterval, setSlideshowInterval] = useState(initialInterval ?? 5000)
  const slideshowTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)

  // Zoom/pan state for images
  const [zoom, setZoom] = useState(1)
  const [pan, setPan] = useState({ x: 0, y: 0 })
  const [isPanning, setIsPanning] = useState(false)
  const [panStart, setPanStart] = useState({ x: 0, y: 0 })

  // Loading states
  const [imageLoading, setImageLoading] = useState(true)
  const [imageError, setImageError] = useState(false)
  const loadedUrlRef = useRef<string | null>(null)

  // Video aspect ratio for portrait video sizing
  const [videoAspectRatio, setVideoAspectRatio] = useState<number | null>(null)

  // Image dimensions for zoom calculation
  const [naturalSize, setNaturalSize] = useState<{ width: number; height: number } | null>(null)
  const [displayedSize, setDisplayedSize] = useState<{ width: number; height: number } | null>(null)

  // Auto-hide floating zoom controls
  const [zoomControlsVisible, setZoomControlsVisible] = useState(false)
  const zoomControlsTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)

  const maxZoom = naturalSize && displayedSize
    ? Math.max(5, Math.ceil((naturalSize.width / displayedSize.width) * 1.5))
    : 5

  const containerRef = useRef<HTMLDivElement>(null)
  const imageRef = useRef<HTMLImageElement>(null)
  const videoRef = useRef<HTMLVideoElement>(null)

  // Video playback: direct file serving (no HLS for media gallery)
  useEffect(() => {
    const video = videoRef.current
    if (!video || !isCurrentVideo || !currentItem) return

    video.src = getPreviewUrl(currentItem)

    return () => {
      video.pause()
    }
  }, [isCurrentVideo, currentItem?.id])

  // Pause video on close
  const handleClose = useCallback(() => {
    if (videoRef.current) {
      videoRef.current.pause()
    }
    onClose()
  }, [onClose])

  // Show zoom controls with auto-hide timer
  const showZoomControls = useCallback(() => {
    if (isCurrentVideo) return
    setZoomControlsVisible(true)
    if (zoomControlsTimerRef.current) clearTimeout(zoomControlsTimerRef.current)
    zoomControlsTimerRef.current = setTimeout(() => setZoomControlsVisible(false), 2500)
  }, [isCurrentVideo])

  // Cleanup zoom controls timer on unmount
  useEffect(() => {
    return () => { if (zoomControlsTimerRef.current) clearTimeout(zoomControlsTimerRef.current) }
  }, [])

  // Hide metadata when slideshow starts
  useEffect(() => {
    if (slideshowPlaying) {
      setShowMetadata(false)
    }
  }, [slideshowPlaying])

  // Preload next page when approaching end of loaded items
  useEffect(() => {
    if (hasMore && onLoadMore && currentIndex >= items.length - 5) {
      onLoadMore()
    }
  }, [currentIndex, items.length, hasMore, onLoadMore])

  // Slideshow: advance to next item
  const slideshowAdvance = useCallback(() => {
    if (currentIndex < items.length - 1) {
      onNavigate(currentIndex + 1)
    } else if (hasMore && onLoadMore) {
      onLoadMore()
    } else {
      setSlideshowPlaying(false)
    }
  }, [currentIndex, items.length, onNavigate, hasMore, onLoadMore])

  // Slideshow timer logic for images - wait for load, then start countdown
  useEffect(() => {
    if (slideshowTimerRef.current) {
      clearTimeout(slideshowTimerRef.current)
      slideshowTimerRef.current = null
    }

    if (slideshowPlaying && !isCurrentVideo && !imageLoading) {
      slideshowTimerRef.current = setTimeout(() => {
        slideshowAdvance()
      }, slideshowInterval)
    }

    return () => {
      if (slideshowTimerRef.current) {
        clearTimeout(slideshowTimerRef.current)
        slideshowTimerRef.current = null
      }
    }
  }, [slideshowPlaying, isCurrentVideo, imageLoading, slideshowInterval, slideshowAdvance])

  // Slideshow: handle video ended event to advance
  useEffect(() => {
    if (!slideshowPlaying || !isCurrentVideo) return

    const video = videoRef.current
    if (!video) return

    const handleEnded = () => {
      slideshowAdvance()
    }

    video.addEventListener('ended', handleEnded)
    return () => video.removeEventListener('ended', handleEnded)
  }, [slideshowPlaying, isCurrentVideo, slideshowAdvance])

  // Navigation
  const canGoPrev = currentIndex > 0
  const canGoNext = currentIndex < items.length - 1 || !!hasMore

  const navigatePrev = useCallback(() => {
    if (currentIndex > 0) {
      if (videoRef.current) videoRef.current.pause()
      onNavigate(currentIndex - 1)
    }
  }, [currentIndex, onNavigate])

  const navigateNext = useCallback(() => {
    if (currentIndex < items.length - 1) {
      if (videoRef.current) videoRef.current.pause()
      onNavigate(currentIndex + 1)
    }
  }, [currentIndex, items.length, onNavigate])

  // Keyboard shortcuts
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement) return

      switch (e.key) {
        case ' ':
          e.preventDefault()
          setSlideshowPlaying(p => !p)
          break
        case 'ArrowLeft':
          e.preventDefault()
          navigatePrev()
          break
        case 'ArrowRight':
          e.preventDefault()
          navigateNext()
          break
        case 'Escape':
          e.preventDefault()
          if (slideshowPlaying) {
            setSlideshowPlaying(false)
          } else {
            handleClose()
          }
          break
        case '+':
        case '=':
          e.preventDefault()
          if (!isCurrentVideo) { setZoom(z => Math.min(z + 0.5, maxZoom)); showZoomControls() }
          break
        case '-':
        case '_':
          e.preventDefault()
          if (!isCurrentVideo) { setZoom(z => Math.max(z - 0.5, 1)); showZoomControls() }
          break
        case '0':
          e.preventDefault()
          setZoom(1)
          setPan({ x: 0, y: 0 })
          showZoomControls()
          break
        case 'i':
        case 'I':
          e.preventDefault()
          setShowMetadata(s => !s)
          break
      }
    }

    window.addEventListener('keydown', handleKeyDown)
    return () => window.removeEventListener('keydown', handleKeyDown)
  }, [navigatePrev, navigateNext, handleClose, isCurrentVideo, maxZoom, slideshowPlaying, showZoomControls])

  // Reset zoom/pan when changing items
  useEffect(() => {
    setZoom(1)
    setPan({ x: 0, y: 0 })
    setImageError(false)
    setNaturalSize(null)
    setDisplayedSize(null)
    setMenuOpen(false)
    setVideoAspectRatio(null)
    const url = currentItem ? getPreviewUrl(currentItem) : null
    if (loadedUrlRef.current !== url) {
      setImageLoading(true)
    }
  }, [currentIndex])

  // Mouse wheel zoom
  const handleWheel = useCallback((e: WheelEvent) => {
    if (isCurrentVideo) return
    if (e.ctrlKey || e.metaKey) {
      e.preventDefault()
      const delta = e.deltaY > 0 ? -0.2 : 0.2
      setZoom(z => Math.max(1, Math.min(maxZoom, z + delta)))
      showZoomControls()
    }
  }, [maxZoom, isCurrentVideo, showZoomControls])

  useEffect(() => {
    const container = containerRef.current
    if (container) {
      container.addEventListener('wheel', handleWheel, { passive: false })
      return () => container.removeEventListener('wheel', handleWheel)
    }
  }, [handleWheel])

  // Pan handling for images
  const handleMouseDown = (e: React.MouseEvent) => {
    if (zoom > 1 && !isCurrentVideo) {
      setIsPanning(true)
      setPanStart({ x: e.clientX - pan.x, y: e.clientY - pan.y })
    }
  }

  const handleMouseMove = (e: React.MouseEvent) => {
    showZoomControls()
    if (isPanning) {
      setPan({
        x: e.clientX - panStart.x,
        y: e.clientY - panStart.y,
      })
    }
  }

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

  // Gesture refs for touch support
  const gestureZoomRef = useRef(zoom)
  const gesturePanRef = useRef(pan)

  useEffect(() => {
    gestureZoomRef.current = zoom
    gesturePanRef.current = pan
  }, [zoom, pan])

  // Track swipe state for navigation
  const swipeStartRef = useRef<{ x: number; y: number; time: number } | null>(null)

  // Touch gesture handling for images (pinch zoom, drag pan)
  useGesture(
    {
      onPinch: ({ offset: [scale], last }) => {
        if (isCurrentVideo) return
        const newZoom = Math.max(1, Math.min(maxZoom, scale))
        gestureZoomRef.current = newZoom

        if (imageRef.current) {
          const p = gesturePanRef.current
          imageRef.current.style.transform = `scale3d(${newZoom}, ${newZoom}, 1) translate3d(${p.x / newZoom}px, ${p.y / newZoom}px, 0)`
        }

        if (last) setZoom(newZoom)
      },
      onDrag: ({ offset: [x, y], pinching, last }) => {
        if (isCurrentVideo || pinching) return
        const currentZoom = gestureZoomRef.current
        if (currentZoom <= 1) return

        gesturePanRef.current = { x, y }

        if (imageRef.current) {
          imageRef.current.style.transform = `scale3d(${currentZoom}, ${currentZoom}, 1) translate3d(${x / currentZoom}px, ${y / currentZoom}px, 0)`
        }

        if (last) setPan({ x, y })
      },
    },
    {
      target: imageRef,
      eventOptions: { passive: false },
      pinch: { scaleBounds: { min: 1, max: maxZoom }, rubberband: true },
      drag: { from: () => [gesturePanRef.current.x, gesturePanRef.current.y] },
    }
  )

  // Swipe navigation for mobile (works for both images and videos)
  const handleTouchStart = useCallback((e: React.TouchEvent) => {
    showZoomControls()
    const target = e.target as HTMLElement
    if (target.closest('button, a, video, input, textarea')) {
      swipeStartRef.current = null
      return
    }

    if (e.touches.length === 1) {
      swipeStartRef.current = {
        x: e.touches[0].clientX,
        y: e.touches[0].clientY,
        time: Date.now(),
      }
    }
  }, [showZoomControls])

  const handleTouchEnd = useCallback((e: React.TouchEvent) => {
    if (!swipeStartRef.current || e.changedTouches.length !== 1) return

    const start = swipeStartRef.current
    const end = {
      x: e.changedTouches[0].clientX,
      y: e.changedTouches[0].clientY,
    }

    const deltaX = end.x - start.x
    const deltaY = end.y - start.y
    const deltaTime = Date.now() - start.time

    const minSwipeDistance = 50
    const maxVerticalDeviation = 100

    if (deltaTime < 300 && Math.abs(deltaX) > minSwipeDistance && Math.abs(deltaY) < maxVerticalDeviation) {
      if (!isCurrentVideo && zoom > 1) {
        swipeStartRef.current = null
        return
      }

      if (deltaX > 0) {
        navigatePrev()
      } else if (deltaX < 0) {
        navigateNext()
      }
    }

    swipeStartRef.current = null
  }, [navigatePrev, navigateNext, isCurrentVideo, zoom])

  // URL helpers
  const getPreviewUrl = (item: MediaGalleryItem) =>
    item.file_token
      ? `/api/media/preview?t=${encodeURIComponent(item.file_token)}`
      : `/api/media/preview?file_path=${encodeURIComponent(item.file_path)}`

  const getThumbnailUrl = (item: MediaGalleryItem) => {
    const mediaType = isVideoFile(item) ? 'video' : 'image'
    return item.file_token
      ? `/api/media/thumbnail?t=${encodeURIComponent(item.file_token)}&media_type=${mediaType}`
      : `/api/media/thumbnail?file_path=${encodeURIComponent(item.file_path)}&media_type=${mediaType}`
  }

  // Actions
  const handleDownload = async () => {
    try {
      const url = getPreviewUrl(currentItem)
      const filename = currentItem.filename || `file_${currentItem.id}`
      const response = await fetch(url)
      const blob = await response.blob()
      const downloadUrl = window.URL.createObjectURL(blob)
      const a = document.createElement('a')
      a.href = downloadUrl
      a.download = filename
      document.body.appendChild(a)
      a.click()
      document.body.removeChild(a)
      window.URL.revokeObjectURL(downloadUrl)
      notificationManager.success('Downloaded', filename)
      setMenuOpen(false)
    } catch {
      notificationManager.error('Download Failed', 'Could not download file')
    }
  }

  const handleCopyPath = () => {
    navigator.clipboard.writeText(currentItem.file_path || '')
    notificationManager.success('Copied', 'Path copied to clipboard')
    setMenuOpen(false)
  }

  const handlePiP = async () => {
    const video = videoRef.current
    if (!video) return
    setMenuOpen(false)
    try {
      if (document.pictureInPictureEnabled && video.requestPictureInPicture) {
        await video.requestPictureInPicture()
        return
      }
      if ((video as any).webkitSupportsPresentationMode?.('picture-in-picture')) {
        ;(video as any).webkitSetPresentationMode('picture-in-picture')
        return
      }
      notificationManager.error('PiP unavailable', 'Picture-in-Picture is not supported on this device')
    } catch {
      notificationManager.error('PiP failed', 'Could not enter Picture-in-Picture mode')
    }
  }

  return (
    <div
      ref={containerRef}
      className="fixed inset-0 z-[60] bg-black flex"
      style={isLandscape ? { height: '100dvh', width: '100vw' } : undefined}
      onMouseMove={handleMouseMove}
      onMouseUp={handleMouseUp}
      onMouseLeave={handleMouseUp}
      onTouchStart={handleTouchStart}
      onTouchEnd={handleTouchEnd}
    >
      {/* ===== MAIN CONTENT AREA ===== */}
      <div className="flex-1 flex flex-col relative" style={isLandscape ? { height: '100dvh' } : undefined}>
        {/* Top Left: Slideshow Controls */}
        <div
          className={`absolute z-20 flex items-center gap-2 transition-opacity duration-200 ${
            isMobile ? 'top-0 left-4' : isLandscape ? 'top-2 left-3' : 'top-10 left-[7.5rem]'
          }`}
          style={isMobile ? { paddingTop: 'env(safe-area-inset-top, 0px)' } : undefined}
        >
          {(totalCount || items.length) > 1 && (
            <button
              onClick={() => setSlideshowPlaying(p => !p)}
              className="p-2 bg-black/50 hover:bg-black/70 rounded-lg text-white transition-colors"
              title={slideshowPlaying ? 'Pause Slideshow (Space)' : 'Play Slideshow (Space)'}
            >
              {slideshowPlaying ? (
                <Pause className="w-5 h-5" />
              ) : (
                <Play className="w-5 h-5" />
              )}
            </button>
          )}
          {slideshowPlaying && (totalCount || items.length) > 1 && onShuffleChange && (
            <button
              onClick={() => onShuffleChange(!isShuffled)}
              className={`p-2 bg-black/50 hover:bg-black/70 rounded-lg transition-colors ${
                isShuffled ? 'text-cyan-400' : 'text-white'
              }`}
              title={isShuffled ? 'Disable Shuffle' : 'Enable Shuffle'}
            >
              <Shuffle className="w-5 h-5" />
            </button>
          )}
          {slideshowPlaying && (totalCount || items.length) > 1 && (
            <div className="flex items-center gap-1 bg-black/50 rounded-lg p-1">
              {[3000, 5000, 8000, 10000].map(ms => (
                <button
                  key={ms}
                  onClick={() => setSlideshowInterval(ms)}
                  className={`px-2 py-1 rounded text-xs transition-colors ${
                    slideshowInterval === ms
                      ? 'bg-white/30 text-white font-medium'
                      : 'text-white/60 hover:text-white hover:bg-white/10'
                  }`}
                >
                  {ms / 1000}s
                </button>
              ))}
            </div>
          )}
          {/* Position indicator on desktop */}
          {!isMobile && items.length > 1 && (
            <span className="text-white/60 text-sm ml-1">
              {currentIndex + 1} / {totalCount || items.length}
              {isShuffled && ' (shuffled)'}
              {!totalCount && hasMore && '+'}
            </span>
          )}
        </div>

        {/* Top Right: Info, Menu and Close */}
        <div
          className={`absolute z-20 flex items-center gap-2 transition-opacity duration-200 ${
            isMobile ? 'top-0 right-4 safe-area-inset-top' : isLandscape ? 'top-2 right-3' : 'top-10 right-6'
          } ${isMobile && !showControls ? 'opacity-0 pointer-events-none' : 'opacity-100'}`}
          style={isMobile ? { paddingTop: 'env(safe-area-inset-top, 0px)' } : undefined}
        >
          {/* Info toggle button */}
          <button
            onClick={() => setShowMetadata(!showMetadata)}
            className={`p-2 md:p-2 hover:bg-white/10 rounded-lg transition-colors drop-shadow-[0_2px_4px_rgba(0,0,0,0.8)] ${
              showMetadata ? 'text-cyan-400' : isMobile || isLandscape ? 'text-white/70' : 'text-transparent hover:text-white'
            }`}
            title="Toggle Details (I)"
          >
            <Info className="w-7 h-7 md:w-7 md:h-7 drop-shadow-[0_1px_2px_rgba(0,0,0,0.9)]" />
          </button>
          <div className="relative">
            <button
              onClick={() => setMenuOpen(!menuOpen)}
              className="p-2 hover:bg-white/10 rounded-lg text-white transition-colors drop-shadow-[0_2px_4px_rgba(0,0,0,0.8)]"
            >
              <MoreHorizontal className="w-7 h-7 drop-shadow-[0_1px_2px_rgba(0,0,0,0.9)]" />
            </button>
            {menuOpen && (
              <div className="absolute top-full right-0 mt-1 w-44 bg-zinc-900 border border-white/10 rounded-lg shadow-xl overflow-hidden">
                <button
                  onClick={handleDownload}
                  className="w-full px-4 py-2.5 text-left text-white text-sm hover:bg-white/10 flex items-center gap-3"
                >
                  <Download className="w-4 h-4" />
                  Download
                </button>
                <button
                  onClick={handleCopyPath}
                  className="w-full px-4 py-2.5 text-left text-white text-sm hover:bg-white/10 flex items-center gap-3"
                >
                  <Copy className="w-4 h-4" />
                  Copy path
                </button>
                {isCurrentVideo && (
                  <>
                    <div className="border-t border-white/10" />
                    <button
                      onClick={handlePiP}
                      className="w-full px-4 py-2.5 text-left text-white text-sm hover:bg-white/10 flex items-center gap-3"
                    >
                      <PictureInPicture2 className="w-4 h-4" />
                      Picture-in-Picture
                    </button>
                  </>
                )}
              </div>
            )}
          </div>
          {/* Close button */}
          <button
            onClick={handleClose}
            className={`p-2 hover:bg-white/10 rounded-lg transition-colors drop-shadow-[0_2px_4px_rgba(0,0,0,0.8)] ${
              isMobile || isLandscape ? 'text-white/70' : 'text-transparent hover:text-white'
            }`}
          >
            <X className="w-7 h-7 drop-shadow-[0_1px_2px_rgba(0,0,0,0.9)]" />
          </button>
        </div>

        {/* Mobile position indicator */}
        {isMobile && items.length > 1 && (
          <div
            className={`absolute top-12 left-1/2 -translate-x-1/2 z-10 px-3 py-1 bg-black/50 rounded-full text-white text-sm transition-opacity duration-200 ${
              showControls ? 'opacity-100' : 'opacity-0'
            }`}
            style={{ paddingTop: 'env(safe-area-inset-top, 0px)' }}
          >
            {currentIndex + 1} / {totalCount || items.length}{isShuffled && ' (shuffled)'}{!totalCount && hasMore && '+'}
          </div>
        )}

        {/* Navigation Arrow - Previous */}
        {canGoPrev && (
          <button
            onClick={navigatePrev}
            className={`absolute top-1/2 -translate-y-1/2 z-20 transition-colors drop-shadow-[0_2px_4px_rgba(0,0,0,0.8)] ${
              isMobile
                ? 'left-2 p-3 bg-black/40 rounded-full text-white/80 active:bg-white/20'
                : isLandscape
                  ? 'left-1 p-3 bg-black/40 rounded-full text-white/80 active:bg-white/20'
                  : 'left-0 px-6 py-16 hover:bg-white/5 rounded-r-2xl text-transparent hover:text-white'
            }`}
          >
            <ChevronLeft className={`${isMobile ? 'w-8 h-8' : isLandscape ? 'w-7 h-7' : 'w-6 h-6'} drop-shadow-[0_1px_2px_rgba(0,0,0,0.9)]`} />
          </button>
        )}

        {/* Navigation Arrow - Next */}
        {canGoNext && (
          <button
            onClick={navigateNext}
            className={`absolute top-1/2 -translate-y-1/2 z-20 transition-colors drop-shadow-[0_2px_4px_rgba(0,0,0,0.8)] ${
              isMobile
                ? 'right-2 p-3 bg-black/40 rounded-full text-white/80 active:bg-white/20'
                : isLandscape
                  ? 'right-1 p-3 bg-black/40 rounded-full text-white/80 active:bg-white/20'
                  : 'right-0 px-6 py-16 hover:bg-white/5 rounded-l-2xl text-transparent hover:text-white'
            }`}
          >
            <ChevronRight className={`${isMobile ? 'w-8 h-8' : isLandscape ? 'w-7 h-7' : 'w-6 h-6'} drop-shadow-[0_1px_2px_rgba(0,0,0,0.9)]`} />
          </button>
        )}

        {/* Floating Zoom Controls Pill */}
        {!isCurrentVideo && (
          <div
            className={`absolute ${isMobile ? 'bottom-24' : 'bottom-8'} left-1/2 -translate-x-1/2 z-30
              flex items-center gap-1 px-2 py-1.5 bg-black/70 backdrop-blur-sm rounded-full
              transition-opacity duration-300
              ${zoomControlsVisible ? 'opacity-100' : 'opacity-0 pointer-events-none'}`}
            onMouseEnter={() => {
              if (zoomControlsTimerRef.current) clearTimeout(zoomControlsTimerRef.current)
              setZoomControlsVisible(true)
            }}
            onMouseLeave={() => {
              zoomControlsTimerRef.current = setTimeout(() => setZoomControlsVisible(false), 2500)
            }}
          >
            <button onClick={() => { setZoom(z => Math.max(1, z - 0.5)); showZoomControls() }}
              disabled={zoom <= 1}
              className="p-1.5 text-white/80 hover:text-white disabled:text-white/30" title="Zoom out (-)">
              <ZoomOut className="w-4 h-4" />
            </button>
            <span className="text-white/90 text-xs font-mono min-w-[3rem] text-center select-none">
              {naturalSize && displayedSize
                ? `${Math.round((displayedSize.width / naturalSize.width) * zoom * 100)}%`
                : `${Math.round(zoom * 100)}%`}
            </span>
            <button onClick={() => { setZoom(z => Math.min(maxZoom, z + 0.5)); showZoomControls() }}
              disabled={zoom >= maxZoom}
              className="p-1.5 text-white/80 hover:text-white disabled:text-white/30" title="Zoom in (+)">
              <ZoomIn className="w-4 h-4" />
            </button>
            {naturalSize && displayedSize && (
              <button
                onClick={() => { setZoom(naturalSize.width / displayedSize.width); showZoomControls() }}
                disabled={Math.abs(zoom - naturalSize.width / displayedSize.width) < 0.01}
                className="px-1.5 py-0.5 text-white/80 hover:text-white disabled:text-white/30 text-xs font-medium"
                title="Actual size (1)">
                100%
              </button>
            )}
            <button onClick={() => { setZoom(1); setPan({ x: 0, y: 0 }); showZoomControls() }}
              disabled={zoom === 1 && pan.x === 0 && pan.y === 0}
              className="p-1.5 text-white/80 hover:text-white disabled:text-white/30" title="Reset view (0)">
              <RotateCcw className="w-4 h-4" />
            </button>
          </div>
        )}

        {/* Media Display Area */}
        <div
          className={`flex-1 flex items-center justify-center ${isCurrentVideo ? '' : isMobile ? 'px-2 pb-4 pt-2' : isLandscape ? 'px-2 pb-2 pt-1' : 'px-16 pb-8 pt-4'}`}
          onClick={() => menuOpen && setMenuOpen(false)}
        >
          {isCurrentVideo ? (
            /* ===== FULLSCREEN VIDEO PLAYER ===== */
            <div className={`fixed z-10 inset-0 flex ${isMobile ? 'items-center' : videoAspectRatio && videoAspectRatio > 1 ? 'items-center pt-[30px]' : 'items-start'} justify-center bg-black`}>
              {/* Blurred background for portrait videos */}
              <div
                className="absolute inset-0 scale-150"
                style={{
                  backgroundImage: `url(${getThumbnailUrl(currentItem)})`,
                  backgroundSize: 'cover',
                  backgroundPosition: 'center',
                  filter: 'blur(30px) brightness(0.75)',
                }}
              />
              <video
                ref={videoRef}
                key={currentItem.id}
                poster={getThumbnailUrl(currentItem)}
                className={`object-contain relative z-10 ${
                  isMobile ? 'w-full' :
                  isLandscape ? 'max-w-full max-h-full' :
                  videoAspectRatio && videoAspectRatio <= 1 ? 'h-full' :
                  'w-full max-h-full'
                }`}
                style={isMobile && videoAspectRatio
                  ? { aspectRatio: videoAspectRatio }
                  : isLandscape && videoAspectRatio
                    ? { aspectRatio: videoAspectRatio, height: '100%' }
                    : videoAspectRatio && videoAspectRatio <= 1
                      ? { aspectRatio: videoAspectRatio }
                      : undefined
                }
                // @ts-ignore - Safari attributes
                x-webkit-airplay="allow"
                airplay="allow"
                controls
                autoPlay={isMobile || slideshowPlaying || autoPlayVideo}
                muted={isMobile}
                playsInline
                preload="auto"
                disablePictureInPicture={false}
                onLoadStart={() => setImageLoading(true)}
                onLoadedData={(e) => {
                  setImageLoading(false)
                  const video = e.currentTarget
                  if ((isMobile || slideshowPlaying || autoPlayVideo) && video.paused) {
                    video.play().then(() => {
                      if (isMobile && video.muted) {
                        video.muted = false
                      }
                    }).catch(() => {})
                  } else if (isMobile && !video.paused && video.muted) {
                    video.muted = false
                  }
                  if (video.videoWidth && video.videoHeight) {
                    setVideoAspectRatio(video.videoWidth / video.videoHeight)
                  }
                }}
                onCanPlay={() => setImageLoading(false)}
              />
            </div>
          ) : (
            /* ===== FULLSCREEN IMAGE DISPLAY ===== */
            <div
              className="fixed inset-0 flex items-center justify-center bg-black z-10"
              onMouseDown={handleMouseDown}
              style={{
                cursor: zoom > 1 ? 'grab' : 'default',
              }}
            >
              {imageLoading && (
                <div className="absolute inset-0 flex items-center justify-center">
                  <div className="w-10 h-10 border-4 border-white/20 border-t-white rounded-full animate-spin" />
                </div>
              )}
              {imageError ? (
                <div className="text-white text-center p-8">
                  <p className="mb-4">Failed to load image</p>
                  <button
                    onClick={() => { setImageError(false); loadedUrlRef.current = null; setImageLoading(true) }}
                    className="px-4 py-2 bg-white/20 hover:bg-white/30 rounded-lg transition-colors"
                  >
                    Retry
                  </button>
                </div>
              ) : (
                <img
                  ref={imageRef}
                  key={getPreviewUrl(currentItem)}
                  src={getPreviewUrl(currentItem)}
                  alt={currentItem.filename || ''}
                  className="w-full h-full object-contain select-none"
                  style={{
                    transform: `scale3d(${zoom}, ${zoom}, 1) translate3d(${pan.x / zoom}px, ${pan.y / zoom}px, 0)`,
                    transformOrigin: 'center',
                    opacity: imageLoading ? 0 : 1,
                    transition: 'opacity 0.2s',
                    touchAction: 'none',
                  }}
                  onLoad={(e) => {
                    loadedUrlRef.current = getPreviewUrl(currentItem)
                    setImageLoading(false)
                    const img = e.target as HTMLImageElement
                    setNaturalSize({ width: img.naturalWidth, height: img.naturalHeight })
                    const containerAspect = img.clientWidth / img.clientHeight
                    const imageAspect = img.naturalWidth / img.naturalHeight
                    if (imageAspect > containerAspect) {
                      setDisplayedSize({ width: img.clientWidth, height: img.clientWidth / imageAspect })
                    } else {
                      setDisplayedSize({ width: img.clientHeight * imageAspect, height: img.clientHeight })
                    }
                  }}
                  onError={() => { setImageLoading(false); setImageError(true) }}
                  draggable={false}
                />
              )}
            </div>
          )}
        </div>

        {/* ===== METADATA PANEL ===== */}
        <div
          className={`absolute transition-all duration-300 ease-in-out z-30 ${
            isMobile
              ? `inset-x-0 bottom-0 top-[62px] ${showMetadata ? 'opacity-100' : 'opacity-0 pointer-events-none'}`
              : `right-6 bottom-8 w-80 ${showMetadata ? 'translate-x-0 opacity-100' : 'translate-x-[110%] opacity-0 pointer-events-none'}`
          }`}
          style={isMobile ? { paddingTop: 'env(safe-area-inset-top, 0px)' } : { top: '5.5rem' }}
          onClick={(e) => e.stopPropagation()}
        >
          <div className={`h-full bg-gradient-to-br from-gray-900/95 to-black/95 backdrop-blur-xl overflow-hidden ${
            isMobile ? 'rounded-t-2xl' : 'rounded-2xl border border-white/30 shadow-[0_20px_60px_rgba(0,0,0,0.8)]'
          }`}>
            <div className="p-6 h-full overflow-y-auto">
              <div className="flex items-center justify-between mb-6 pb-4 border-b border-white/20">
                <h3 className="text-white font-semibold text-lg">Details</h3>
                {isMobile && (
                  <button
                    onClick={() => setShowMetadata(false)}
                    className="p-2 hover:bg-white/10 rounded-lg text-white/70"
                  >
                    <X className="w-5 h-5" />
                  </button>
                )}
              </div>

              <div className="space-y-3 text-sm">
                {/* Embedded Metadata */}
                {embeddedMetadataLoading && (
                  <div className="text-white/40 text-xs italic">Loading metadata...</div>
                )}

                {embeddedMetadata?.title && (
                  <div>
                    <div className="text-white/60 mb-1 flex items-center gap-2">
                      <Film className="w-4 h-4" />
                      Title
                    </div>
                    <div className="text-white">{embeddedMetadata.title}</div>
                  </div>
                )}

                {embeddedMetadata?.description && (
                  <div>
                    <div className="text-white/60 mb-1">Description</div>
                    <div className="text-white text-xs max-h-24 overflow-y-auto whitespace-pre-wrap">
                      {embeddedMetadata.description}
                    </div>
                  </div>
                )}

                {embeddedMetadata?.artist && (
                  <div>
                    <div className="text-white/60 mb-1">Artist</div>
                    <div className="text-white">{embeddedMetadata.artist}</div>
                  </div>
                )}

                {embeddedMetadata?.source && (
                  <div>
                    <div className="text-white/60 mb-1">Source URL</div>
                    <div className="text-white text-xs break-all">{embeddedMetadata.source}</div>
                  </div>
                )}

                {(embeddedMetadata?.title || embeddedMetadata?.description || embeddedMetadata?.artist) && (
                  <div className="border-t border-white/10 pt-3 mt-3" />
                )}

                {/* Filename */}
                <div>
                  <div className="text-white/60 mb-1 flex items-center gap-2">
                    <ImageIcon className="w-4 h-4" />
                    Filename
                  </div>
                  <div className="text-white break-all">
                    {currentItem.filename || `File ${currentItem.id}`}
                  </div>
                </div>

                {/* Resolution */}
                {((currentItem.width && currentItem.height) || naturalSize) && (
                  <div>
                    <div className="text-white/60 mb-1 flex items-center gap-2">
                      <ImageIcon className="w-4 h-4" />
                      Resolution
                    </div>
                    <div className="text-white">
                      {currentItem.width && currentItem.height
                        ? formatResolution(currentItem.width, currentItem.height)
                        : naturalSize
                          ? formatResolution(naturalSize.width, naturalSize.height)
                          : 'Loading...'}
                    </div>
                  </div>
                )}

                {/* File Size */}
                {currentItem.file_size > 0 && (
                  <div>
                    <div className="text-white/60 mb-1 flex items-center gap-2">
                      <HardDrive className="w-4 h-4" />
                      Size
                    </div>
                    <div className="text-white">{formatBytes(currentItem.file_size)}</div>
                  </div>
                )}

                {/* Duration (for videos) */}
                {isCurrentVideo && currentItem.duration && currentItem.duration > 0 && (
                  <div>
                    <div className="text-white/60 mb-1 flex items-center gap-2">
                      <Clock className="w-4 h-4" />
                      Duration
                    </div>
                    <div className="text-white">{formatDuration(currentItem.duration)}</div>
                  </div>
                )}

                {/* Date */}
                {(currentItem.post_date || currentItem.download_date) && (
                  <div>
                    <div className="text-white/60 mb-1 flex items-center gap-2">
                      <Calendar className="w-4 h-4" />
                      {currentItem.post_date ? 'Post Date' : 'Download Date'}
                    </div>
                    <div className="text-white">
                      {formatDate(currentItem.post_date || currentItem.download_date)}
                    </div>
                  </div>
                )}

                {/* File Path */}
                {currentItem.file_path && (
                  <div>
                    <div className="text-white/60 mb-1">Path</div>
                    <div className="text-white text-xs break-all font-mono">
                      {currentItem.file_path}
                    </div>
                  </div>
                )}

                {/* Platform + Source */}
                {(currentItem.platform || currentItem.source) && (
                  <div>
                    <div className="text-white/60 mb-1">Platform / Source</div>
                    <div className="text-white capitalize">
                      {[currentItem.platform, currentItem.source].filter(Boolean).join(' / ')}
                    </div>
                  </div>
                )}
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  )
}
