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

/**
 * A simplified utility for conditionally joining class names together.
 * Similar to clsx/classnames that accepts arrays and objects for convenience.
 *
 * @param args - Class names, arrays, objects, or conditional expressions
 * @returns Filtered and joined class names
 *
 * @example
 * // Basic usage with array
 * cx(['foo', 'bar']); // => 'foo bar'
 *
 * @example
 * // Multiple arguments
 * cx('foo', 'bar'); // => 'foo bar'
 *
 * @example
 * // Filtering out falsy values
 * cx(['foo', null, 'bar', undefined, '', false, 0]); // => 'foo bar'
 *
 * @example
 * // With conditional expressions
 * cx(['base', isActive && 'active', hasError && 'error']); // => returns 'base active' or 'base error' depending on conditions
 *
 * @example
 * // Object syntax
 * cx({ foo: true, bar: false, baz: isCondition }); // => 'foo baz' if isCondition is true, otherwise just 'foo'
 *
 * @example
 * // Mixed arguments
 * cx('base', { active: isActive, disabled: isDisabled }, ['extra', condition && 'conditional']); // => combines all formats
 */
export function cx( ...args ) {
	return args
		.flatMap( arg => {
			if ( !arg ) {
				return [];
			}

			if ( typeof arg === 'string' ) {
				return arg;
			}

			if ( Array.isArray( arg ) ) {
				return cx( ...arg );
			}

			if ( typeof arg === 'object' ) {
				return Object
					.entries( arg )
					.filter( ( [ , value ] ) => Boolean( value ) )
					.map( ( [ key ] ) => key );
			}

			return [];
		} )
		.filter( Boolean )
		.join( ' ' )
		.trim();
}
