import { useState, useEffect, useRef, memo } from 'react'

interface ThrottledImageProps {
  src: string
  alt: string
  className: string
  showErrorPlaceholder?: boolean
  priority?: boolean // Load immediately without waiting for intersection
}

// Shared IntersectionObserver for all images (performance optimization)
let sharedObserver: IntersectionObserver | null = null
const observerCallbacks = new Map<Element, () => void>()

function getSharedObserver(): IntersectionObserver {
  if (!sharedObserver) {
    sharedObserver = new IntersectionObserver(
      (entries) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
            const callback = observerCallbacks.get(entry.target)
            if (callback) {
              callback()
              sharedObserver?.unobserve(entry.target)
              observerCallbacks.delete(entry.target)
            }
          }
        })
      },
      {
        rootMargin: '400px', // Start loading 400px before visible (increased from 50px)
        threshold: 0
      }
    )
  }
  return sharedObserver
}

/**
 * ThrottledImage component - optimized lazy loading for thumbnail grids
 *
 * Optimizations:
 * - Shared IntersectionObserver for all images (less memory/CPU)
 * - 400px rootMargin for aggressive preloading
 * - No artificial delays - immediate load when in range
 * - Memoized to prevent unnecessary re-renders
 * - Priority prop for above-the-fold images
 */
function ThrottledImageComponent({ src, alt, className, showErrorPlaceholder = false, priority = false }: ThrottledImageProps) {
  const [loaded, setLoaded] = useState(false)
  const [error, setError] = useState(false)
  const [shouldLoad, setShouldLoad] = useState(priority)
  const containerRef = useRef<HTMLDivElement>(null)

  useEffect(() => {
    if (priority || shouldLoad) return

    const element = containerRef.current
    if (!element) return

    const observer = getSharedObserver()
    observerCallbacks.set(element, () => setShouldLoad(true))
    observer.observe(element)

    return () => {
      observer.unobserve(element)
      observerCallbacks.delete(element)
    }
  }, [priority, shouldLoad])

  return (
    <div ref={containerRef} className={className}>
      {shouldLoad ? (
        showErrorPlaceholder && error ? (
          <div className="w-full h-full bg-slate-300 dark:bg-slate-600 flex items-center justify-center">
            <svg className="w-8 h-8 text-slate-400 dark:text-slate-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
            </svg>
          </div>
        ) : (
          <img
            src={src}
            alt={alt}
            className={`w-full h-full object-cover transition-opacity duration-200 ${
              loaded ? 'opacity-100' : 'opacity-0'
            }`}
            onLoad={() => setLoaded(true)}
            onError={() => setError(true)}
            loading="lazy"
            decoding="async"
            fetchPriority={priority ? 'high' : 'low'}
          />
        )
      ) : (
        <div className="w-full h-full bg-slate-200 dark:bg-slate-700 animate-pulse" />
      )}
    </div>
  )
}

// Memoize to prevent unnecessary re-renders when parent re-renders
const ThrottledImage = memo(ThrottledImageComponent)
export default ThrottledImage

/**
 * Prefetch images for better perceived performance.
 * Call this with URLs of images that will likely be needed soon.
 */
export function prefetchImages(urls: string[]): void {
  urls.forEach(url => {
    const link = document.createElement('link')
    link.rel = 'prefetch'
    link.as = 'image'
    link.href = url
    document.head.appendChild(link)
  })
}
