// performance.js - Optimisations de performance pour l'application

/**
 * Lazy Loading pour les graphiques Chart.js
 * Charge les graphiques seulement quand ils sont visibles
 */
class ChartLazyLoader {
    constructor() {
        this.observer = null;
        this.loadedCharts = new Set();
        this.init();
    }

    init() {
        if ('IntersectionObserver' in window) {
            this.observer = new IntersectionObserver(
                (entries) => this.handleIntersection(entries),
                {
                    root: null,
                    rootMargin: '50px',
                    threshold: 0.1
                }
            );
        }
    }

    handleIntersection(entries) {
        entries.forEach(entry => {
            if (entry.isIntersecting && !this.loadedCharts.has(entry.target.id)) {
                this.loadChart(entry.target.id);
                this.loadedCharts.add(entry.target.id);
                this.observer.unobserve(entry.target);
            }
        });
    }

    loadChart(chartId) {
        try {
            switch(chartId) {
                case 'evolutionChart':
                    if (typeof loadEvolutionChart === 'function') {
                        loadEvolutionChart();
                    }
                    break;
                case 'productsChart':
                    if (typeof loadProductsChart === 'function') {
                        loadProductsChart();
                    }
                    break;
                case 'topClientsChart':
                    if (typeof loadTopClientsChart === 'function') {
                        loadTopClientsChart();
                    }
                    break;
                case 'sitesChart':
                    if (typeof loadSitesChart === 'function') {
                        loadSitesChart();
                    }
                    break;
                default:
                    console.log(`Chart loader not found for: ${chartId}`);
            }
        } catch (error) {
            console.error(`Error loading chart ${chartId}:`, error);
        }
    }

    observe(element) {
        if (this.observer && element) {
            this.observer.observe(element);
        }
    }

    observeAll(selector = '.chart-container canvas') {
        const charts = document.querySelectorAll(selector);
        charts.forEach(chart => this.observe(chart));
    }
}

/**
 * Debounce utility pour limiter les appels de fonctions
 */
function debounce(func, wait, immediate) {
    let timeout;
    return function executedFunction(...args) {
        const later = () => {
            timeout = null;
            if (!immediate) func(...args);
        };
        const callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func(...args);
    };
}

/**
 * Throttle utility pour limiter la fréquence d'exécution
 */
function throttle(func, limit) {
    let inThrottle;
    return function(...args) {
        if (!inThrottle) {
            func.apply(this, args);
            inThrottle = true;
            setTimeout(() => inThrottle = false, limit);
        }
    };
}

/**
 * Cache simple en mémoire pour les données API
 */
class SimpleCache {
    constructor(maxSize = 50, defaultTTL = 5 * 60 * 1000) { // 5 minutes par défaut
        this.cache = new Map();
        this.maxSize = maxSize;
        this.defaultTTL = defaultTTL;
    }

    set(key, value, ttl = this.defaultTTL) {
        // Supprimer l'ancienne entrée si elle existe
        if (this.cache.has(key)) {
            this.cache.delete(key);
        }

        // Si le cache est plein, supprimer la plus ancienne entrée
        if (this.cache.size >= this.maxSize) {
            const firstKey = this.cache.keys().next().value;
            this.cache.delete(firstKey);
        }

        const expiryTime = Date.now() + ttl;
        this.cache.set(key, { value, expiryTime });
    }

    get(key) {
        const item = this.cache.get(key);
        if (!item) return null;

        if (Date.now() > item.expiryTime) {
            this.cache.delete(key);
            return null;
        }

        return item.value;
    }

    has(key) {
        return this.get(key) !== null;
    }

    clear() {
        this.cache.clear();
    }

    size() {
        return this.cache.size;
    }
}

/**
 * Image lazy loading avec placeholder
 */
function setupImageLazyLoading() {
    const imageObserver = new IntersectionObserver((entries) => {
        entries.forEach(entry => {
            if (entry.isIntersecting) {
                const img = entry.target;
                img.src = img.dataset.src;
                img.classList.remove('lazy');
                imageObserver.unobserve(img);
            }
        });
    });

    document.querySelectorAll('img[data-src]').forEach(img => {
        imageObserver.observe(img);
    });
}

/**
 * Optimisation des animations pendant le scroll
 */
function optimizeScrollAnimations() {
    let ticking = false;

    function updateAnimations() {
        // Logique d'animation ici
        ticking = false;
    }

    function requestTick() {
        if (!ticking) {
            requestAnimationFrame(updateAnimations);
            ticking = true;
        }
    }

    window.addEventListener('scroll', requestTick, { passive: true });
}

/**
 * Preload des ressources critiques
 */
function preloadCriticalResources() {
    const criticalResources = [
        './styles.css',
        './responsive.css'
    ];

    criticalResources.forEach(resource => {
        const link = document.createElement('link');
        link.rel = 'preload';
        link.href = resource;
        link.as = 'style';
        document.head.appendChild(link);
    });
}

/**
 * Service Worker registration pour le cache
 */
function registerServiceWorker() {
    if ('serviceWorker' in navigator) {
        window.addEventListener('load', () => {
            navigator.serviceWorker.register('./sw.js')
                .then(registration => {
                    console.log('✅ Service Worker enregistré:', registration);
                })
                .catch(error => {
                    console.log('❌ Échec d\'enregistrement du Service Worker:', error);
                });
        });
    }
}

/**
 * Initialisation des optimisations de performance
 */
function initPerformanceOptimizations() {
    // Lazy loading des charts
    const chartLoader = new ChartLazyLoader();
    
    // Attendre que le DOM soit chargé
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', () => {
            chartLoader.observeAll();
            setupImageLazyLoading();
        });
    } else {
        chartLoader.observeAll();
        setupImageLazyLoading();
    }

    // Optimisations scroll
    optimizeScrollAnimations();
    
    // Preload des ressources
    preloadCriticalResources();
    
    // Service Worker
    registerServiceWorker();

    return { chartLoader };
}

// Instance globale du cache
window.appCache = new SimpleCache();

// Export pour utilisation
if (typeof module !== 'undefined' && module.exports) {
    module.exports = {
        ChartLazyLoader,
        SimpleCache,
        debounce,
        throttle,
        initPerformanceOptimizations
    };
}

// Auto-initialisation
document.addEventListener('DOMContentLoaded', () => {
    window.performanceUtils = initPerformanceOptimizations();
});