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

/**
 * Creates a mutation observer to detect content changes in the specified element.
 *
 * @param config - Configuration object
 * @param config.element - The element to observe for changes
 * @param config.callback - The function to call when mutations occur
 * @param [config.attributeFilter] - Specific attributes to watch (optional)
 * @param [config.options] - MutationObserver options (defaults to observing all changes)
 * @returns A function that disconnects the observer when called
 */
export function createMutationObserver( { element, callback, attributeFilter, options = {} } ) {
	// Create default options if none provided
	const observerOptions = {
		childList: options.childList ?? true,
		characterData: options.characterData ?? true,
		subtree: options.subtree ?? true,
		attributes: options.attributes ?? true,
		attributeFilter
	};

	// Create a new mutation observer
	const mutationObserver = new MutationObserver( mutations => {
		// Check if any mutations affected the content
		const contentChanged = mutations.some( mutation =>
			mutation.type === 'characterData' ||
			mutation.type === 'childList' ||
				( mutation.type === 'attributes' &&
				( !attributeFilter || attributeFilter.includes( mutation.attributeName ) ) )
		);

		// If content changed, call the callback with mutation information
		if ( contentChanged ) {
			callback( mutations );
		}
	} );

	// Start observing the element
	mutationObserver.observe( element, observerOptions );

	// Return a function to disconnect the observer
	return () => {
		mutationObserver.disconnect();
	};
}
