/**
 * @license Copyright (c) 2017-2025, CKSource Holding sp. z o.o. All rights reserved.
 * For licensing, see LICENSE.md.
 */

/**
 * Creates a cleanup registry that manages a collection of cleanup callbacks.
 *
 * @returns An object with methods to register and destroy callbacks
 */
export function createCleanupRegistry() {
	const callbacks = [];

	return {
		/**
		 * Registers a cleanup callback and returns it.
		 *
		 * @param callback - The cleanup callback to register
		 * @returns The registered callback
		 */
		register( callback ) {
			if ( typeof callback === 'function' ) {
				callbacks.push( callback );
			}

			return callback;
		},

		/**
		 * Executes all registered callbacks and clears the registry.
		 */
		destroy() {
			while ( callbacks.length ) {
				const callback = callbacks.pop();
				if ( typeof callback === 'function' ) {
					callback();
				}
			}
		},

		/**
		 * Attaches an event listener to an element and registers its cleanup.
		 *
		 * @param element - DOM element to attach the event to
		 * @param type - Event type (e.g., 'click', 'focus')
		 * @param handler - Event handler function
		 * @param [options] - Optional addEventListener options
		 * @returns The handler function for reference
		 */
		addEventListener( element, type, handler, options ) {
			if ( !element || !type || typeof handler !== 'function' ) {
				console.warn( 'Invalid parameters provided to addEventListener' );
				return handler;
			}

			element.addEventListener( type, handler, options );

			this.register( () => {
				element.removeEventListener( type, handler, options );
			} );

			return handler;
		},

		/**
		 * Attaches multiple event listeners to an element and registers their cleanup.
		 *
		 * @param element - DOM element to attach the events to
		 * @param events - Map of event types to handler functions
		 * @param [options] - Optional addEventListener options
		 * @returns The provided element for chaining
		 */
		addEventListeners( element, events, options ) {
			if ( !element || !events ) {
				console.warn( 'Invalid parameters provided to addEventListeners' );
				return element;
			}

			for ( const [ type, handler ] of Object.entries( events ) ) {
				if ( typeof handler === 'function' ) {
					this.addEventListener( element, type, handler, options );
				}
			}

			return element;
		}
	};
}
