/**
 * Fichier  : assets/js/infinite-scroll.js
 * Auteur   : KREMER Régis
 * Version  : 2.2.0
 * Date     : 2026-02-21
 * Description : JS — Module scroll infini pour listes mobiles
 *
 * Changelog :
 *   v2.1.0 (2026-02-21) — Version initiale auditée et sécurisée
 *   v2.1.1 (2026-02-21) — Corrections sécurité, utils.js centralisé
 *   v2.2.0 (2026-02-21) — Permissions magasins, bons de commande, rapport d'écart,
 *                      import CSV, historique prix, bon de livraison multi-lignes
 */
// ================================================================
// infinite-scroll.js — Module de scroll infini pour mobile/tablette
// Remplace la pagination classique sur écrans < 1024px
// ================================================================

const InfiniteScroll = {
    // Configuration par défaut
    _instances: new Map(),
    _isMobile: false,
    _resizeTimeout: null,
    
    /**
     * Vérifie si on est en mode mobile/tablette
     */
    checkMobile() {
        this._isMobile = window.innerWidth <= 1024;
        return this._isMobile;
    },
    
    /**
     * Initialise le scroll infini pour un conteneur
     * @param {Object} config Configuration
     * @param {string} config.id - Identifiant unique de l'instance
     * @param {HTMLElement} config.container - Conteneur scrollable (ou window)
     * @param {HTMLElement} config.target - Élément où insérer le contenu
     * @param {HTMLElement} config.pagerEl - Élément pager à cacher en mobile
     * @param {Function} config.loadMore - Fonction appelée pour charger plus (reçoit page, callback)
     * @param {Function} config.renderItems - Fonction pour render les items (reçoit items, append)
     * @param {number} config.threshold - Distance du bas pour déclencher (défaut: 200px)
     * @param {number} config.pageSize - Nombre d'items par page (défaut: 12)
     */
    init(config) {
        const {
            id,
            container = null,
            target,
            pagerEl,
            loadMore,
            renderItems,
            threshold = 200,
            pageSize = 12
        } = config;
        
        if (!id || !target || !loadMore || !renderItems) {
            console.error('[InfiniteScroll] Configuration incomplète');
            return;
        }
        
        // Stocker l'instance
        const instance = {
            id,
            container: container || window,
            target,
            pagerEl,
            loadMore,
            renderItems,
            threshold,
            pageSize,
            currentPage: 1,
            isLoading: false,
            hasMore: true,
            allItems: [],
            loadedCount: 0,
            scrollHandler: null,
            loaderEl: null
        };
        
        this._instances.set(id, instance);
        
        // Créer le loader
        this._createLoader(instance);
        
        // Vérifier le mode et configurer
        this._setupInstance(instance);
        
        // Écouter les changements de taille
        this._setupResizeListener();
        
        return instance;
    },
    
    /**
     * Configure une instance selon le mode (mobile ou desktop)
     */
    _setupInstance(instance) {
        const isMobile = this.checkMobile();
        
        if (isMobile) {
            // Mode scroll infini
            this._enableInfiniteScroll(instance);
            if (instance.pagerEl) {
                instance.pagerEl.style.display = 'none';
            }
        } else {
            // Mode pagination classique
            this._disableInfiniteScroll(instance);
            if (instance.pagerEl) {
                instance.pagerEl.style.display = '';
            }
        }
    },
    
    /**
     * Active le scroll infini
     */
    _enableInfiniteScroll(instance) {
        if (instance.scrollHandler) return; // Déjà actif
        
        const scrollEl = instance.container === window 
            ? document.documentElement 
            : instance.container;
        
        instance.scrollHandler = () => {
            if (instance.isLoading || !instance.hasMore) return;
            
            let scrollTop, scrollHeight, clientHeight;
            
            if (instance.container === window) {
                scrollTop = window.scrollY || document.documentElement.scrollTop;
                scrollHeight = document.documentElement.scrollHeight;
                clientHeight = window.innerHeight;
            } else {
                scrollTop = instance.container.scrollTop;
                scrollHeight = instance.container.scrollHeight;
                clientHeight = instance.container.clientHeight;
            }
            
            // Déclencher si proche du bas
            if (scrollTop + clientHeight >= scrollHeight - instance.threshold) {
                this._loadNextPage(instance);
            }
        };
        
        instance.container.addEventListener('scroll', instance.scrollHandler, { passive: true });
        
        // Afficher le loader
        if (instance.loaderEl) {
            instance.loaderEl.style.display = '';
        }
    },
    
    /**
     * Désactive le scroll infini
     */
    _disableInfiniteScroll(instance) {
        if (instance.scrollHandler) {
            instance.container.removeEventListener('scroll', instance.scrollHandler);
            instance.scrollHandler = null;
        }
        
        // Cacher le loader
        if (instance.loaderEl) {
            instance.loaderEl.style.display = 'none';
        }
    },
    
    /**
     * Charge la page suivante
     */
    async _loadNextPage(instance) {
        if (instance.isLoading || !instance.hasMore) return;
        
        instance.isLoading = true;
        this._showLoader(instance);
        
        try {
            // Appeler la fonction loadMore fournie
            const result = await instance.loadMore(instance.currentPage + 1, instance.pageSize);
            
            if (result && result.items && result.items.length > 0) {
                instance.currentPage++;
                instance.loadedCount += result.items.length;
                instance.allItems = [...instance.allItems, ...result.items];
                
                // Rendre les nouveaux items (mode append)
                instance.renderItems(result.items, true);
                
                // Vérifier s'il y a encore des données
                if (result.items.length < instance.pageSize || result.hasMore === false) {
                    instance.hasMore = false;
                    this._showEndMessage(instance);
                }
            } else {
                instance.hasMore = false;
                this._showEndMessage(instance);
            }
        } catch (error) {
            console.error('[InfiniteScroll] Erreur chargement:', error);
            toast('Erreur lors du chargement', 'error');
        } finally {
            instance.isLoading = false;
            this._hideLoader(instance);
        }
    },
    
    /**
     * Réinitialise une instance (après filtre, recherche, etc.)
     */
    reset(id, initialItems = []) {
        const instance = this._instances.get(id);
        if (!instance) return;
        
        instance.currentPage = 1;
        instance.isLoading = false;
        instance.hasMore = true;
        instance.allItems = [...initialItems];
        instance.loadedCount = initialItems.length;
        
        // Retirer le message de fin s'il existe
        const endMsg = instance.target.querySelector('.infinite-scroll-end');
        if (endMsg) endMsg.remove();
        
        // Réafficher le loader si en mode mobile
        if (this._isMobile && instance.loaderEl) {
            instance.loaderEl.style.display = '';
        }
    },
    
    /**
     * Met à jour le nombre total d'items (pour savoir quand arrêter)
     */
    setTotal(id, total) {
        const instance = this._instances.get(id);
        if (!instance) return;
        
        instance.totalItems = total;
        if (instance.loadedCount >= total) {
            instance.hasMore = false;
        }
    },
    
    /**
     * Crée l'élément loader
     */
    _createLoader(instance) {
        const loader = document.createElement('div');
        loader.className = 'infinite-scroll-loader';
        loader.innerHTML = `
            <div class="infinite-loader-spinner"></div>
            <span>Chargement...</span>
        `;
        loader.style.display = 'none';
        
        // Insérer après le target
        instance.target.parentNode.insertBefore(loader, instance.target.nextSibling);
        instance.loaderEl = loader;
    },
    
    /**
     * Affiche le loader
     */
    _showLoader(instance) {
        if (instance.loaderEl) {
            instance.loaderEl.classList.add('visible');
        }
    },
    
    /**
     * Cache le loader
     */
    _hideLoader(instance) {
        if (instance.loaderEl) {
            instance.loaderEl.classList.remove('visible');
        }
    },
    
    /**
     * Affiche le message de fin
     */
    _showEndMessage(instance) {
        // Ne pas afficher si déjà présent
        if (instance.target.parentNode.querySelector('.infinite-scroll-end')) return;
        
        const endMsg = document.createElement('div');
        endMsg.className = 'infinite-scroll-end';
        endMsg.innerHTML = `
            <span>Tous les éléments sont affichés</span>
            <span class="infinite-end-count">${instance.loadedCount} résultat(s)</span>
        `;
        
        // Cacher le loader et afficher le message
        if (instance.loaderEl) {
            instance.loaderEl.style.display = 'none';
        }
        
        instance.target.parentNode.insertBefore(endMsg, instance.loaderEl || instance.target.nextSibling);
    },
    
    /**
     * Configure l'écouteur de redimensionnement
     */
    _setupResizeListener() {
        if (this._resizeListenerSet) return;
        this._resizeListenerSet = true;
        
        window.addEventListener('resize', () => {
            clearTimeout(this._resizeTimeout);
            this._resizeTimeout = setTimeout(() => {
                const wasMobile = this._isMobile;
                const isMobile = this.checkMobile();
                
                // Si changement de mode, reconfigurer toutes les instances
                if (wasMobile !== isMobile) {
                    this._instances.forEach(instance => {
                        this._setupInstance(instance);
                    });
                }
            }, 250);
        });
    },
    
    /**
     * Détruit une instance
     */
    destroy(id) {
        const instance = this._instances.get(id);
        if (!instance) return;
        
        this._disableInfiniteScroll(instance);
        
        if (instance.loaderEl) {
            instance.loaderEl.remove();
        }
        
        const endMsg = instance.target.parentNode.querySelector('.infinite-scroll-end');
        if (endMsg) endMsg.remove();
        
        this._instances.delete(id);
    },
    
    /**
     * Vérifie si une instance est en mode mobile
     */
    isMobileMode() {
        return this._isMobile;
    }
};

// Exposer globalement
window.InfiniteScroll = InfiniteScroll;
