/**
 * EventEmitter - Système d'événements simple pour la communication entre composants
 * 
 * Permet aux composants de s'abonner à des événements et d'être notifiés des changements
 */

class EventEmitter {
    constructor() {
        this.events = {};
    }
    
    /**
     * S'abonne à un événement
     * @param {string} event - Nom de l'événement
     * @param {Function} callback - Fonction à appeler quand l'événement est émis
     * @returns {Function} Fonction pour se désabonner
     */
    on(event, callback) {
        if (!this.events[event]) {
            this.events[event] = [];
        }
        
        this.events[event].push(callback);
        
        // Retourner une fonction pour se désabonner
        return () => this.off(event, callback);
    }
    
    /**
     * Se désabonne d'un événement
     * @param {string} event - Nom de l'événement
     * @param {Function} callback - Fonction à retirer
     */
    off(event, callback) {
        if (!this.events[event]) {
            return;
        }
        
        this.events[event] = this.events[event].filter(cb => cb !== callback);
    }
    
    /**
     * Émet un événement
     * @param {string} event - Nom de l'événement
     * @param {*} data - Données à passer aux callbacks
     */
    emit(event, data) {
        if (!this.events[event]) {
            return;
        }
        
        this.events[event].forEach(callback => {
            try {
                callback(data);
            } catch (error) {
                console.error(`Error in event handler for "${event}":`, error);
            }
        });
    }
    
    /**
     * S'abonne à un événement une seule fois
     * @param {string} event - Nom de l'événement
     * @param {Function} callback - Fonction à appeler
     */
    once(event, callback) {
        const onceCallback = (data) => {
            callback(data);
            this.off(event, onceCallback);
        };
        
        this.on(event, onceCallback);
    }
    
    /**
     * Supprime tous les listeners d'un événement ou tous les événements
     * @param {string} [event] - Nom de l'événement (optionnel)
     */
    removeAllListeners(event) {
        if (event) {
            delete this.events[event];
        } else {
            this.events = {};
        }
    }
    
    /**
     * Retourne le nombre de listeners pour un événement
     * @param {string} event - Nom de l'événement
     * @returns {number} Nombre de listeners
     */
    listenerCount(event) {
        return this.events[event] ? this.events[event].length : 0;
    }
}

// Export pour utilisation dans d'autres modules
if (typeof module !== 'undefined' && module.exports) {
    module.exports = EventEmitter;
}
