import { React, classnames } from '@gravityforms/libraries';
import { spacerClasses } from '@gravityforms/utils';

const { forwardRef } = React;

/**
 * @module Box
 * @description Renders a simple box component for containing width or height.
 *
 * @since 1.1.15
 *
 * @param {React.ReactNode|React.ReactNode[]}          [children]          - React element children
 * @param {Record<string, any>}                        [customAttributes]  - Custom attributes for the component
 * @param {string|string[]|Record<string, boolean>}    [customClasses]     - Custom classes for the component
 * @param {string}                                     [display='block']   - The display property for the box
 * @param {boolean}                                    [setDisplay=true]   - Whether to set the display property for the box
 * @param {string|number|string[]|Record<string, any>} [spacing='']        - The spacing for the component
 * @param {string}                                     [tagName='div']     - The tagname for the box
 * @param {string}                                     [unit='px']         - The css units for the x and y props
 * @param {number}                                     [x=0]               - The width property
 * @param {string}                                     [xProp='maxWidth']  - The css property in react style syntax for the width
 * @param {number}                                     [y=0]               - The height property
 * @param {string}                                     [yProp='minHeight'] - The css property in react style syntax for the height
 * @param {React.RefObject<HTMLElement>|null}          ref                 - Ref to the component
 *
 * @return {JSX.Element} The box component
 *
 * @example
 * import Box from '@gravityforms/components/react/admin/elements/Box';
 *
 * return (
 *     <Box tagName="span">
 *         { 'children' }
 *     </Box>
 * );
 *
 */
const Box = forwardRef( ( {
	children = null,
	customAttributes = {},
	customClasses = [],
	display = 'block',
	setDisplay = true,
	spacing = '',
	tagName = 'div',
	unit = 'px',
	x = 0,
	xProp = 'maxWidth',
	y = 0,
	yProp = 'minHeight',
}, ref ) => {
	/** @type {React.CSSProperties} */
	const style = {};

	if ( setDisplay ) {
		style.display = display;
	}
	if ( x ) {
		style[ xProp ] = `${ x }${ unit }`;
	}
	if ( y ) {
		style[ yProp ] = `${ y }${ unit }`;
	}

	const mergedStyles = { ...style, ...( customAttributes.style || {} ) };

	const boxProps = {
		className: classnames( {
			'gform-box': true,
			...spacerClasses( spacing ),
		}, customClasses ),
		ref,
		...customAttributes,
		style: mergedStyles,
	};

	const Container = tagName;

	return <Container { ...boxProps }>{ children }</Container>;
} );

Box.displayName = 'Box';

export default Box;
