'use client'

import { memo, useEffect, useCallback, useState, useMemo } from 'react'
import { createPortal } from 'react-dom'
import { cn } from '@djangocfg/ui-core/lib'
import { useAppT } from '@djangocfg/i18n'
import { X, ChevronLeft, ChevronRight, Download, Share2, ZoomIn, ZoomOut } from 'lucide-react'
import { useSwipe } from '../../hooks/useSwipe'
import { usePreloadImages } from '../../hooks/usePreloadImages'
import { useZoom } from '../../hooks/useZoom'
import { GalleryMedia } from '../media'
import { GalleryThumbnails } from '../thumbnails'
import type { GalleryLightboxProps } from '../../types'

/**
 * GalleryLightbox - Fullscreen image viewer with zoom and navigation
 *
 * Features:
 * - Preloads adjacent images for smooth navigation
 * - Loading skeleton while image loads
 * - Zoom with pan/drag support
 * - Keyboard and swipe navigation
 */
export const GalleryLightbox = memo(function GalleryLightbox({
  open,
  onClose,
  images,
  currentIndex,
  onIndexChange,
  showThumbnails = true,
  enableZoom = true,
  enableDownload = true,
  enableShare = true,
  title,
}: GalleryLightboxProps) {
  const t = useAppT()
  const [mounted, setMounted] = useState(false)

  // Translations
  const labels = useMemo(() => ({
    lightbox: t('tools.gallery.lightbox'),
    previous: t('tools.gallery.previous'),
    next: t('tools.gallery.next'),
    close: t('tools.gallery.close'),
    download: t('tools.gallery.download'),
    share: t('tools.gallery.share'),
    zoomIn: t('tools.image.zoomIn'),
    zoomOut: t('tools.image.zoomOut'),
  }), [t])

  // Unified zoom (handles both desktop click/drag and mobile pinch/tap)
  const zoom = useZoom({
    minScale: 1,
    maxScale: 3,
    desktopScale: 2,
  })

  // Prepare data
  const currentImage = useMemo(() => images[currentIndex], [images, currentIndex])
  const hasMultiple = useMemo(() => images.length > 1, [images.length])
  const { isZoomed, isDragging } = zoom

  // Preload adjacent images when lightbox is open
  usePreloadImages(open ? images : [], currentIndex, 2)

  // Handle client-side mounting for portal
  useEffect(() => {
    setMounted(true)
  }, [])

  // Reset zoom when image changes
  useEffect(() => {
    zoom.reset()
  }, [currentIndex])

  // Prevent body scroll when open
  useEffect(() => {
    if (open) {
      const originalStyle = window.getComputedStyle(document.body).overflow
      document.body.style.overflow = 'hidden'
      return () => {
        document.body.style.overflow = originalStyle
      }
    }
  }, [open])

  // Navigation handlers
  const goToPrev = useCallback(() => {
    if (hasMultiple) {
      onIndexChange((currentIndex - 1 + images.length) % images.length)
    }
  }, [hasMultiple, currentIndex, images.length, onIndexChange])

  const goToNext = useCallback(() => {
    if (hasMultiple) {
      onIndexChange((currentIndex + 1) % images.length)
    }
  }, [hasMultiple, currentIndex, images.length, onIndexChange])

  // Keyboard navigation
  useEffect(() => {
    if (!open) return

    const handleKeyDown = (e: KeyboardEvent) => {
      switch (e.key) {
        case 'Escape':
          if (isZoomed) {
            zoom.reset()
          } else {
            onClose()
          }
          break
        case 'ArrowLeft':
          if (!isZoomed) goToPrev()
          break
        case 'ArrowRight':
          if (!isZoomed) goToNext()
          break
      }
    }

    window.addEventListener('keydown', handleKeyDown)
    return () => window.removeEventListener('keydown', handleKeyDown)
  }, [open, isZoomed, goToPrev, goToNext, onClose, zoom])

  // Swipe handlers (disabled when zoomed)
  const swipeHandlers = useSwipe({
    onSwipeLeft: isZoomed ? undefined : goToNext,
    onSwipeRight: isZoomed ? undefined : goToPrev,
  })

  // Action handlers
  const handleDownload = useCallback(() => {
    if (!currentImage) return
    const link = document.createElement('a')
    link.href = currentImage.src
    link.download = currentImage.alt || `image-${currentIndex + 1}.jpg`
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
  }, [currentImage, currentIndex])

  const handleShare = useCallback(async () => {
    if (!currentImage) return
    if (navigator.share) {
      try {
        await navigator.share({
          title: title || 'Image',
          url: currentImage.src,
        })
      } catch {
        // User cancelled or error
      }
    } else {
      await navigator.clipboard.writeText(currentImage.src)
    }
  }, [currentImage, title])

  const handleToggleZoom = useCallback(() => {
    zoom.toggleZoom()
  }, [zoom])

  const handleContentClick = useCallback((e: React.MouseEvent) => {
    e.stopPropagation()
  }, [])

  if (!open || !mounted) return null

  const lightbox = (
    <div
      className={cn(
        'fixed inset-0 z-50',
        'backdrop-blur-sm',
        'animate-in fade-in-0 duration-200'
      )}
      style={{ backgroundColor: 'rgba(0, 0, 0, 0.85)' }}
      onClick={onClose}
      role="dialog"
      aria-modal="true"
      aria-label={labels.lightbox}
    >
      {/* Content */}
      <div
        className="relative w-full h-full flex flex-col"
        onClick={handleContentClick}
        {...swipeHandlers}
      >
        {/* Header */}
        <div className="absolute top-0 left-0 right-0 z-10 flex items-center justify-between p-4">
          {/* Title & Counter */}
          <div className="text-white">
            {title && <div className="font-medium">{title}</div>}
            {hasMultiple && (
              <div className="text-sm text-white/70">
                {currentIndex + 1} / {images.length}
              </div>
            )}
          </div>

          {/* Actions */}
          <div className="flex items-center gap-2">
            {enableZoom && (
              <button
                type="button"
                className="p-2 rounded-full bg-white/10 hover:bg-white/20 text-white transition-colors"
                onClick={handleToggleZoom}
                aria-label={isZoomed ? labels.zoomOut : labels.zoomIn}
              >
                {isZoomed ? (
                  <ZoomOut className="w-5 h-5" />
                ) : (
                  <ZoomIn className="w-5 h-5" />
                )}
              </button>
            )}

            {enableDownload && (
              <button
                type="button"
                className="p-2 rounded-full bg-white/10 hover:bg-white/20 text-white transition-colors"
                onClick={handleDownload}
                aria-label={labels.download}
              >
                <Download className="w-5 h-5" />
              </button>
            )}

            {enableShare && (
              <button
                type="button"
                className="p-2 rounded-full bg-white/10 hover:bg-white/20 text-white transition-colors"
                onClick={handleShare}
                aria-label={labels.share}
              >
                <Share2 className="w-5 h-5" />
              </button>
            )}

            <button
              type="button"
              className="p-2 rounded-full bg-white/10 hover:bg-white/20 text-white transition-colors"
              onClick={onClose}
              aria-label={labels.close}
            >
              <X className="w-5 h-5" />
            </button>
          </div>
        </div>

        {/* Main Image */}
        <div className="flex-1 flex items-center justify-center p-4 pt-16 pb-24 overflow-hidden">
          {currentImage && (
            <div
              className={cn(
                'relative w-full h-full select-none',
                isZoomed ? 'cursor-grab' : enableZoom ? 'cursor-zoom-in' : 'cursor-default',
                isDragging && 'cursor-grabbing'
              )}
              {...(enableZoom ? zoom.handlers : {})}
              style={{
                transform: isZoomed
                  ? `scale(${zoom.state.scale}) translate(${zoom.state.x}px, ${zoom.state.y}px)`
                  : 'scale(1)',
                transition: isDragging ? 'none' : 'transform 0.3s ease-out',
                touchAction: 'none',
              }}
            >
              <GalleryMedia
                media={currentImage}
                className="w-full h-full pointer-events-none"
                objectFit="contain"
                showLoading
                priority
                autoPlay
              />
            </div>
          )}
        </div>

        {/* Navigation Arrows */}
        {hasMultiple && !isZoomed && (
          <>
            <button
              type="button"
              className={cn(
                'absolute left-4 top-1/2 -translate-y-1/2 z-10',
                'w-12 h-12 rounded-full',
                'bg-white/10 hover:bg-white/20 text-white',
                'flex items-center justify-center transition-colors',
                'focus:outline-none focus-visible:ring-2 focus-visible:ring-white'
              )}
              onClick={goToPrev}
              aria-label={labels.previous}
            >
              <ChevronLeft className="w-6 h-6" />
            </button>

            <button
              type="button"
              className={cn(
                'absolute right-4 top-1/2 -translate-y-1/2 z-10',
                'w-12 h-12 rounded-full',
                'bg-white/10 hover:bg-white/20 text-white',
                'flex items-center justify-center transition-colors',
                'focus:outline-none focus-visible:ring-2 focus-visible:ring-white'
              )}
              onClick={goToNext}
              aria-label={labels.next}
            >
              <ChevronRight className="w-6 h-6" />
            </button>
          </>
        )}

        {/* Thumbnails */}
        {showThumbnails && hasMultiple && !isZoomed && (
          <div className="absolute bottom-0 left-0 right-0 p-4 bg-gradient-to-t from-black/50 to-transparent">
            <GalleryThumbnails
              images={images}
              currentIndex={currentIndex}
              onSelect={onIndexChange}
              size="sm"
              className="justify-center"
            />
          </div>
        )}
      </div>
    </div>
  )

  return createPortal(lightbox, document.body)
})
