/**
 * Optimized Lazy Loading for Images
 * Improves page load time by deferring offscreen images
 * Uses Intersection Observer API for efficient monitoring
 */

(function () {
  "use strict";

  // Configuration
  const CONFIG = {
    rootMargin: "50px", // Start loading 50px before entering viewport
    threshold: 0.01,
    loadingClass: "lazy-loading",
    loadedClass: "lazy-loaded",
    errorClass: "lazy-error",
  };

  // Image cache to prevent duplicate loads
  const imageCache = new Set();

  /**
   * Preload image and return promise
   */
  function preloadImage(src) {
    if (imageCache.has(src)) {
      return Promise.resolve();
    }

    return new Promise((resolve, reject) => {
      const img = new Image();
      img.onload = () => {
        imageCache.add(src);
        resolve();
      };
      img.onerror = reject;
      img.src = src;
    });
  }

  /**
   * Load image with fade-in effect
   */
  async function loadImage(img) {
    const src = img.dataset.src;
    const srcset = img.dataset.srcset;

    if (!src) return;

    img.classList.add(CONFIG.loadingClass);

    try {
      // Preload the image
      await preloadImage(src);

      // Set the actual src
      img.src = src;
      if (srcset) {
        img.srcset = srcset;
      }

      // Remove data attributes to free memory
      delete img.dataset.src;
      delete img.dataset.srcset;

      // Add loaded class for fade-in animation
      img.classList.remove(CONFIG.loadingClass);
      img.classList.add(CONFIG.loadedClass);
    } catch (error) {
      console.error("Failed to load image:", src, error);
      img.classList.remove(CONFIG.loadingClass);
      img.classList.add(CONFIG.errorClass);

      // Set fallback/placeholder if available
      if (img.dataset.fallback) {
        img.src = img.dataset.fallback;
      }
    }
  }

  /**
   * Initialize lazy loading with Intersection Observer
   */
  function initLazyLoad() {
    // Check for browser support
    if (!("IntersectionObserver" in window)) {
      // Fallback: load all images immediately
      console.warn("IntersectionObserver not supported, loading all images");
      const images = document.querySelectorAll("img[data-src]");
      images.forEach(loadImage);
      return;
    }

    // Create observer
    const observer = new IntersectionObserver(
      (entries) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
            const img = entry.target;
            loadImage(img);
            observer.unobserve(img); // Stop observing once loaded
          }
        });
      },
      {
        rootMargin: CONFIG.rootMargin,
        threshold: CONFIG.threshold,
      }
    );

    // Observe all lazy images
    const lazyImages = document.querySelectorAll("img[data-src]");
    lazyImages.forEach((img) => observer.observe(img));

    // Also observe images added dynamically
    const mutationObserver = new MutationObserver((mutations) => {
      mutations.forEach((mutation) => {
        mutation.addedNodes.forEach((node) => {
          if (node.nodeName === "IMG" && node.dataset && node.dataset.src) {
            observer.observe(node);
          }
          // Check child images
          if (node.querySelectorAll) {
            const childImages = node.querySelectorAll("img[data-src]");
            childImages.forEach((img) => observer.observe(img));
          }
        });
      });
    });

    mutationObserver.observe(document.body, {
      childList: true,
      subtree: true,
    });

    // Store observers globally for cleanup
    window._lazyLoadObservers = { observer, mutationObserver };
  }

  /**
   * Cleanup observers (call on page unload if needed)
   */
  function cleanup() {
    if (window._lazyLoadObservers) {
      const { observer, mutationObserver } = window._lazyLoadObservers;
      observer.disconnect();
      mutationObserver.disconnect();
    }
  }

  // Add CSS for loading states
  function injectStyles() {
    if (document.getElementById("lazy-load-styles")) return;

    const style = document.createElement("style");
    style.id = "lazy-load-styles";
    style.textContent = `
      img[data-src] {
        opacity: 0;
        transition: opacity 0.3s ease-in-out;
      }
      
      img.lazy-loading {
        opacity: 0.5;
        background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
        background-size: 200% 100%;
        animation: loading 1.5s infinite;
      }
      
      img.lazy-loaded {
        opacity: 1;
      }
      
      img.lazy-error {
        opacity: 0.3;
        border: 2px dashed #ccc;
      }
      
      @keyframes loading {
        0% { background-position: 200% 0; }
        100% { background-position: -200% 0; }
      }
      
      /* Prevent layout shift */
      img[data-src] {
        min-height: 200px;
        background-color: #f5f5f5;
      }
    `;
    document.head.appendChild(style);
  }

  // Initialize on DOM ready
  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", () => {
      injectStyles();
      initLazyLoad();
    });
  } else {
    injectStyles();
    initLazyLoad();
  }

  // Export for manual usage
  window.LazyLoad = {
    init: initLazyLoad,
    load: loadImage,
    cleanup: cleanup,
  };
})();
