import { useState, useEffect, useCallback, useRef } from 'react';

/**
 * Custom Hook für intelligentes Image Preloading in der Slideshow
 * 
 * Lädt die nächsten N Bilder im Hintergrund vor, um nahtlose Übergänge zu garantieren.
 * Verhindert das "Doppelte Bild"-Problem durch proaktives Laden.
 * 
 * @param {Array} allGroups - Array aller Slideshow-Gruppen
 * @param {number} currentGroupIndex - Index der aktuellen Gruppe
 * @param {number} currentImageIndex - Index des aktuellen Bildes
 * @param {Function} getImageSrc - Funktion zum Generieren der Image-URL
 * @param {number} preloadCount - Anzahl der vorzuladenden Bilder (default: 2)
 * 
 * @returns {Object} { isPreloaded, preloadProgress }
 */
function useImagePreloader(
  allGroups,
  currentGroupIndex,
  currentImageIndex,
  getImageSrc,
  preloadCount = 2
) {
  // Cache für erfolgreich geladene Bilder (URL → Image Object)
  const preloadCache = useRef(new Map());
  
  // Set der aktuell vorgeladenen URLs
  const [preloadedUrls, setPreloadedUrls] = useState(new Set());
  
  // Preload-Status für Debugging
  const [preloadProgress, setPreloadProgress] = useState({
    total: 0,
    loaded: 0,
    failed: 0
  });

  /**
   * Berechnet die URLs der nächsten N Bilder in der Slideshow-Sequenz
   * Berücksichtigt Gruppenübergänge und Loop-Back
   */
  const calculateNextImageUrls = useCallback(() => {
    if (!allGroups || allGroups.length === 0) return [];

    const urls = [];
    let groupIdx = currentGroupIndex;
    let imgIdx = currentImageIndex;
    let iterations = 0;
    const maxIterations = allGroups.reduce((sum, g) => sum + (g.images?.length || 0), 0);

    while (urls.length < preloadCount && iterations < maxIterations) {
      iterations++;
      
      const currentGroup = allGroups[groupIdx];
      if (!currentGroup || !currentGroup.images) break;

      // Nächstes Bild
      imgIdx++;
      
      if (imgIdx >= currentGroup.images.length) {
        // Zur nächsten Gruppe wechseln (sequenziell, nicht zufällig)
        groupIdx = (groupIdx + 1) % allGroups.length;
        imgIdx = 0;
        
        // Verhindere Endlosschleife beim Loop-Back
        if (groupIdx === currentGroupIndex && imgIdx === currentImageIndex) {
          break;
        }
      }

      const nextGroup = allGroups[groupIdx];
      const nextImage = nextGroup?.images?.[imgIdx];
      
      if (nextImage) {
        const url = getImageSrc(nextImage, false); // false = full resolution
        urls.push(url);
      }
    }

    return urls;
  }, [allGroups, currentGroupIndex, currentImageIndex, getImageSrc, preloadCount]);

  /**
   * Lädt ein einzelnes Bild vor
   * Nutzt Image() API für garantiertes Laden
   */
  const preloadImage = useCallback((url) => {
    return new Promise((resolve, reject) => {
      // Bereits im Cache? Sofort resolven
      if (preloadCache.current.has(url)) {
        resolve(url);
        return;
      }

      // Neues Image Object erstellen
      const img = new Image();
      
      // Timeout für langsame Verbindungen (max 3 Sekunden)
      const timeout = setTimeout(() => {
        img.src = ''; // Cancel loading
        reject(new Error(`Timeout loading ${url}`));
      }, 3000);

      img.onload = () => {
        clearTimeout(timeout);
        preloadCache.current.set(url, img);
        resolve(url);
      };

      img.onerror = () => {
        clearTimeout(timeout);
        reject(new Error(`Failed to load ${url}`));
      };

      // Start loading
      img.src = url;
    });
  }, []);

  /**
   * Hauptlogik: Lädt die nächsten Bilder im Hintergrund
   */
  useEffect(() => {
    if (!allGroups || allGroups.length === 0) return;

    const urls = calculateNextImageUrls();
    if (urls.length === 0) return;

    let isMounted = true;

    // Reset Progress
    setPreloadProgress({
      total: urls.length,
      loaded: 0,
      failed: 0
    });

    // Preload alle URLs parallel
    const preloadPromises = urls.map(url => 
      preloadImage(url)
        .then(loadedUrl => {
          if (isMounted) {
            setPreloadedUrls(prev => new Set([...prev, loadedUrl]));
            setPreloadProgress(prev => ({
              ...prev,
              loaded: prev.loaded + 1
            }));
          }
          return loadedUrl;
        })
        .catch(error => {
          console.warn(`[Preloader] Failed to preload image: ${error.message}`);
          if (isMounted) {
            setPreloadProgress(prev => ({
              ...prev,
              failed: prev.failed + 1
            }));
          }
          return null;
        })
    );

    Promise.allSettled(preloadPromises);

    return () => {
      isMounted = false;
    };
  }, [allGroups, currentGroupIndex, currentImageIndex, calculateNextImageUrls, preloadImage]);

  /**
   * Cleanup: Entferne alte Bilder aus dem Cache (LRU-Strategy)
   * Maximal 10 Bilder im Cache halten
   */
  useEffect(() => {
    const MAX_CACHE_SIZE = 10;
    
    if (preloadCache.current.size > MAX_CACHE_SIZE) {
      const entries = Array.from(preloadCache.current.entries());
      const toDelete = entries.slice(0, entries.length - MAX_CACHE_SIZE);
      
      toDelete.forEach(([url]) => {
        preloadCache.current.delete(url);
      });
    }
  }, [preloadedUrls]);

  /**
   * Prüft, ob eine bestimmte URL bereits vorgeladen ist
   */
  const isPreloaded = useCallback((url) => {
    return preloadedUrls.has(url) || preloadCache.current.has(url);
  }, [preloadedUrls]);

  return {
    isPreloaded,
    preloadProgress,
    cacheSize: preloadCache.current.size
  };
}

export default useImagePreloader;
