import { useEffect, useRef, useState } from "react";

/**
 * LazyImage — Netflix-style image loading.
 *
 * Features:
 *   1. IntersectionObserver: only loads when in/near viewport.
 *   2. Blur-up: shows a tinted placeholder that fades to the real image.
 *   3. Disk cache friendly: browser caches with long cache headers.
 *   4. Error fallback: gracefully hides broken images.
 *   5. Minimal DOM: single <img> tag when loaded, pure CSS transition.
 */

interface LazyImageProps {
  src?: string;
  alt?: string;
  className?: string;
  placeholderColor?: string;
  /** How far from viewport to start loading (px). Default 200. */
  rootMargin?: number;
  onError?: () => void;
}

const LazyImage = ({
  src,
  alt = "",
  className = "",
  placeholderColor = "rgba(255,215,0,0.08)",
  rootMargin = 200,
  onError,
}: LazyImageProps) => {
  const imgRef = useRef<HTMLImageElement>(null);
  const [loaded, setLoaded] = useState(false);
  const [visible, setVisible] = useState(false);
  const [errored, setErrored] = useState(false);

  useEffect(() => {
    const el = imgRef.current;
    if (!el || !src) return;

    // Reset state on src change
    setLoaded(false);
    setErrored(false);
    setVisible(false);

    const observer = new IntersectionObserver(
      ([entry]) => {
        if (entry.isIntersecting) {
          setVisible(true);
          observer.disconnect();
        }
      },
      { rootMargin: `${rootMargin}px` }
    );

    observer.observe(el);
    return () => observer.disconnect();
  }, [src, rootMargin]);

  if (!src || errored) {
    // No image or errored — return empty placeholder
    return (
      <div
        className={className}
        style={{ backgroundColor: placeholderColor }}
      />
    );
  }

  return (
    <img
      ref={imgRef}
      src={visible ? src : undefined}
      alt={alt}
      decoding="async"
      className={className}
      style={{
        backgroundColor: placeholderColor,
        opacity: loaded ? 1 : 0,
        transition: "opacity 0.25s ease-in",
        objectFit: "cover",
        width: "100%",
        height: "100%",
      }}
      onLoad={() => setLoaded(true)}
      onError={() => {
        setErrored(true);
        onError?.();
      }}
    />
  );
};

export default LazyImage;
