import { useEffect, useState, useRef } from 'react'
import { PhotoSearchResult, photosApi } from '../api/photos'
import { apiClient } from '../api/client'

interface PhotoViewerProps {
  photos: PhotoSearchResult[]
  initialIndex: number
  onClose: () => void
}

const ZOOM_MIN = 0.5
const ZOOM_MAX = 5
const ZOOM_STEP = 0.25
const SLIDESHOW_INTERVALS = [
  { value: 1, label: '1s' },
  { value: 2, label: '2s' },
  { value: 3, label: '3s' },
  { value: 5, label: '5s' },
  { value: 10, label: '10s' },
]

export default function PhotoViewer({ photos, initialIndex, onClose }: PhotoViewerProps) {
  const [currentIndex, setCurrentIndex] = useState(initialIndex)
  const [imageLoading, setImageLoading] = useState(true)
  const [imageError, setImageError] = useState(false)
  const preloadedImages = useRef<Set<number>>(new Set())
  
  // Zoom state
  const [zoom, setZoom] = useState(1)
  const [panX, setPanX] = useState(0)
  const [panY, setPanY] = useState(0)
  const [isDragging, setIsDragging] = useState(false)
  const [dragStart, setDragStart] = useState({ x: 0, y: 0 })
  const imageContainerRef = useRef<HTMLDivElement>(null)
  
  // Slideshow state
  const [isPlaying, setIsPlaying] = useState(false)
  const [slideshowInterval, setSlideshowInterval] = useState(3) // seconds
  const slideshowTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
  
  // Favorite state
  const [isFavorite, setIsFavorite] = useState(false)
  const [loadingFavorite, setLoadingFavorite] = useState(false)

  const currentPhoto = photos[currentIndex]
  const canGoPrev = currentIndex > 0
  const canGoNext = currentIndex < photos.length - 1

  // Get photo URL
  const getPhotoUrl = (photoId: number) => {
    return `${apiClient.defaults.baseURL}/api/v1/photos/${photoId}/image`
  }

  // Preload adjacent images
  const preloadAdjacent = (index: number) => {
    // Preload next photo
    if (index + 1 < photos.length) {
      const nextPhotoId = photos[index + 1].id
      if (!preloadedImages.current.has(nextPhotoId)) {
        const img = new Image()
        img.src = getPhotoUrl(nextPhotoId)
        preloadedImages.current.add(nextPhotoId)
      }
    }
    // Preload previous photo
    if (index - 1 >= 0) {
      const prevPhotoId = photos[index - 1].id
      if (!preloadedImages.current.has(prevPhotoId)) {
        const img = new Image()
        img.src = getPhotoUrl(prevPhotoId)
        preloadedImages.current.add(prevPhotoId)
      }
    }
  }

  // Handle navigation
  const goPrev = () => {
    if (currentIndex > 0) {
      setCurrentIndex(currentIndex - 1)
      // Reset zoom when navigating
      setZoom(1)
      setPanX(0)
      setPanY(0)
    }
  }

  const goNext = () => {
    if (currentIndex < photos.length - 1) {
      setCurrentIndex(currentIndex + 1)
      // Reset zoom when navigating
      setZoom(1)
      setPanX(0)
      setPanY(0)
    }
  }

  // Zoom functions
  const zoomIn = () => {
    setZoom(prev => Math.min(prev + ZOOM_STEP, ZOOM_MAX))
  }

  const zoomOut = () => {
    setZoom(prev => Math.max(prev - ZOOM_STEP, ZOOM_MIN))
  }

  const resetZoom = () => {
    setZoom(1)
    setPanX(0)
    setPanY(0)
  }

  const handleWheel = (e: React.WheelEvent) => {
    if (e.ctrlKey || e.metaKey) {
      // Zoom with Ctrl/Cmd + wheel
      e.preventDefault()
      const delta = e.deltaY > 0 ? -ZOOM_STEP : ZOOM_STEP
      setZoom(prev => Math.max(ZOOM_MIN, Math.min(ZOOM_MAX, prev + delta)))
    }
  }

  // Pan (drag) functionality
  const handleMouseDown = (e: React.MouseEvent) => {
    if (zoom > 1) {
      setIsDragging(true)
      setDragStart({ x: e.clientX - panX, y: e.clientY - panY })
    }
  }

  const handleMouseMove = (e: React.MouseEvent) => {
    if (isDragging && zoom > 1) {
      setPanX(e.clientX - dragStart.x)
      setPanY(e.clientY - dragStart.y)
    }
  }

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

  // Slideshow functions
  const toggleSlideshow = () => {
    setIsPlaying(prev => !prev)
  }

  useEffect(() => {
    if (isPlaying) {
      slideshowTimerRef.current = setInterval(() => {
        setCurrentIndex(prev => {
          if (prev < photos.length - 1) {
            return prev + 1
          } else {
            // Loop back to start or stop
            setIsPlaying(false)
            return prev
          }
        })
        // Reset zoom when slideshow advances
        setZoom(1)
        setPanX(0)
        setPanY(0)
      }, slideshowInterval * 1000)
    } else {
      if (slideshowTimerRef.current) {
        clearInterval(slideshowTimerRef.current)
        slideshowTimerRef.current = null
      }
    }

    return () => {
      if (slideshowTimerRef.current) {
        clearInterval(slideshowTimerRef.current)
      }
    }
  }, [isPlaying, slideshowInterval, photos.length])

  // Handle image load
  useEffect(() => {
    if (!currentPhoto) return

    setImageLoading(true)
    setImageError(false)
    // Reset zoom when photo changes
    setZoom(1)
    setPanX(0)
    setPanY(0)

    // Load favorite status when photo changes
    photosApi.checkFavorite(currentPhoto.id)
      .then(result => setIsFavorite(result.is_favorite))
      .catch(err => {
        console.error('Error checking favorite:', err)
        setIsFavorite(false)
      })

    // Preload adjacent images when current photo changes
    preloadAdjacent(currentIndex)
  }, [currentIndex, currentPhoto, photos.length])

  // Toggle favorite
  const toggleFavorite = async () => {
    if (loadingFavorite || !currentPhoto) return
    
    setLoadingFavorite(true)
    try {
      const result = await photosApi.toggleFavorite(currentPhoto.id)
      setIsFavorite(result.is_favorite)
    } catch (error) {
      console.error('Error toggling favorite:', error)
      alert('Error updating favorite status')
    } finally {
      setLoadingFavorite(false)
    }
  }

  // Keyboard navigation
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.key === 'Escape') {
        onClose()
      } else if (e.key === 'ArrowLeft' && !isPlaying) {
        e.preventDefault()
        if (currentIndex > 0) {
          setCurrentIndex(currentIndex - 1)
          setZoom(1)
          setPanX(0)
          setPanY(0)
        }
      } else if (e.key === 'ArrowRight' && !isPlaying) {
        e.preventDefault()
        if (currentIndex < photos.length - 1) {
          setCurrentIndex(currentIndex + 1)
          setZoom(1)
          setPanX(0)
          setPanY(0)
        }
      } else if (e.key === '+' || e.key === '=') {
        e.preventDefault()
        setZoom(prev => Math.min(prev + ZOOM_STEP, ZOOM_MAX))
      } else if (e.key === '-' || e.key === '_') {
        e.preventDefault()
        setZoom(prev => Math.max(prev - ZOOM_STEP, ZOOM_MIN))
      } else if (e.key === '0') {
        e.preventDefault()
        setZoom(1)
        setPanX(0)
        setPanY(0)
      } else if (e.key === ' ') {
        e.preventDefault()
        setIsPlaying(prev => !prev)
      }
    }

    window.addEventListener('keydown', handleKeyDown)
    return () => window.removeEventListener('keydown', handleKeyDown)
  }, [currentIndex, photos.length, onClose, isPlaying])

  if (!currentPhoto) {
    return null
  }

  const photoUrl = getPhotoUrl(currentPhoto.id)

  return (
    <div className="fixed inset-0 bg-black z-[100] flex flex-col">
      {/* Top Left Info Corner */}
      <div className="absolute top-0 left-0 z-10 bg-black bg-opacity-70 text-white p-2 rounded-br-lg">
        <div className="flex items-center gap-3">
          <button
            onClick={onClose}
            className="px-2 py-1 bg-gray-700 hover:bg-gray-600 rounded text-xs"
            title="Close (Esc)"
          >
            ✕
          </button>
          <div className="text-xs">
            {currentIndex + 1} / {photos.length}
          </div>
          {currentPhoto.filename && (
            <div className="text-xs text-gray-300 truncate max-w-xs">
              {currentPhoto.filename}
            </div>
          )}
        </div>
      </div>

      {/* Top Right Controls */}
      <div className="absolute top-0 right-0 z-10 bg-black bg-opacity-70 text-white p-2 rounded-bl-lg">
        <div className="flex items-center gap-2">
          {/* Favorite button */}
          <button
            onClick={toggleFavorite}
            disabled={loadingFavorite}
            className={`px-3 py-1 rounded text-xs ${
              isFavorite
                ? 'bg-yellow-600 hover:bg-yellow-700'
                : 'bg-gray-700 hover:bg-gray-600'
            } disabled:opacity-50`}
            title={isFavorite ? 'Remove from favorites' : 'Add to favorites'}
          >
            {isFavorite ? '⭐' : '☆'}
          </button>
          
          {/* Slideshow controls */}
          {isPlaying && (
            <select
              value={slideshowInterval}
              onChange={(e) => setSlideshowInterval(Number(e.target.value))}
              onClick={(e) => e.stopPropagation()}
              className="px-2 py-1 bg-gray-700 rounded text-xs"
              title="Slideshow speed"
            >
              {SLIDESHOW_INTERVALS.map(interval => (
                <option key={interval.value} value={interval.value}>
                  {interval.label}
                </option>
              ))}
            </select>
          )}
          <button
            onClick={toggleSlideshow}
            className={`px-3 py-1 rounded text-xs ${
              isPlaying
                ? 'bg-red-600 hover:bg-red-700'
                : 'bg-green-600 hover:bg-green-700'
            }`}
            title={isPlaying ? 'Pause slideshow (Space)' : 'Start slideshow (Space)'}
          >
            {isPlaying ? '⏸' : '▶'}
          </button>
        </div>
      </div>

      {/* Main Image Area */}
      <div
        ref={imageContainerRef}
        className="flex-1 flex items-center justify-center relative overflow-hidden"
        onWheel={handleWheel}
        onMouseDown={handleMouseDown}
        onMouseMove={handleMouseMove}
        onMouseUp={handleMouseUp}
        onMouseLeave={handleMouseUp}
        style={{ cursor: zoom > 1 ? (isDragging ? 'grabbing' : 'grab') : 'default' }}
      >
        {imageLoading && (
          <div className="absolute inset-0 flex items-center justify-center bg-black z-20">
            <div className="text-white text-lg">Loading...</div>
          </div>
        )}
        {imageError ? (
          <div className="text-white text-center">
            <div className="text-lg mb-2">Failed to load image</div>
            <div className="text-sm text-gray-400">{currentPhoto.path}</div>
          </div>
        ) : (
          <div
            style={{
              transform: `translate(${panX}px, ${panY}px) scale(${zoom})`,
              transition: isDragging ? 'none' : 'transform 0.2s ease-out',
            }}
          >
            <img
              src={photoUrl}
              alt={currentPhoto.filename || `Photo ${currentIndex + 1}`}
              className="max-w-full max-h-full object-contain"
              style={{ userSelect: 'none', pointerEvents: 'none' }}
              onLoad={() => setImageLoading(false)}
              onError={() => {
                setImageLoading(false)
                setImageError(true)
              }}
              draggable={false}
            />
          </div>
        )}

        {/* Zoom Controls */}
        <div className="absolute top-12 right-4 z-30 flex flex-col gap-2">
          <button
            onClick={zoomIn}
            disabled={zoom >= ZOOM_MAX}
            className="px-3 py-2 bg-black bg-opacity-70 hover:bg-opacity-90 text-white rounded disabled:opacity-30 disabled:cursor-not-allowed"
            title="Zoom in (Ctrl/Cmd + Wheel)"
          >
            +
          </button>
          <div className="px-3 py-1 bg-black bg-opacity-70 text-white rounded text-center text-xs">
            {Math.round(zoom * 100)}%
          </div>
          <button
            onClick={zoomOut}
            disabled={zoom <= ZOOM_MIN}
            className="px-3 py-2 bg-black bg-opacity-70 hover:bg-opacity-90 text-white rounded disabled:opacity-30 disabled:cursor-not-allowed"
            title="Zoom out (Ctrl/Cmd + Wheel)"
          >
            −
          </button>
          {zoom !== 1 && (
            <button
              onClick={resetZoom}
              className="px-3 py-1 bg-black bg-opacity-70 hover:bg-opacity-90 text-white rounded text-xs"
              title="Reset zoom"
            >
              Reset
            </button>
          )}
        </div>

        {/* Navigation Buttons */}
        <button
          onClick={goPrev}
          disabled={!canGoPrev || isPlaying}
          className="absolute left-4 top-1/2 -translate-y-1/2 px-4 py-2 bg-black bg-opacity-70 hover:bg-opacity-90 text-white rounded disabled:opacity-30 disabled:cursor-not-allowed z-30"
          title="Previous (←)"
        >
          ← Prev
        </button>
        <button
          onClick={goNext}
          disabled={!canGoNext || isPlaying}
          className="absolute right-4 top-1/2 -translate-y-1/2 px-4 py-2 bg-black bg-opacity-70 hover:bg-opacity-90 text-white rounded disabled:opacity-30 disabled:cursor-not-allowed z-30"
          title="Next (→)"
        >
          Next →
        </button>
      </div>

    </div>
  )
}

