import { React, PropTypes, classnames } from '@gravityforms/libraries';
import { ConditionalWrapper } from '@gravityforms/react-utils';

/**
 * @module Loader
 * @description A loader component with variations, optional mask and text display.
 *
 * @since 1.1.15
 *
 * @param {object}              props                      Component props.
 * @param {JSX.Element}         props.children             React element children.
 * @param {boolean}             props.displayText          Whether or not to display the passed text.
 * @param {JSX.Element}         props.loader               The loader element.
 * @param {boolean}             props.mask                 Whether to place the loader on a mask that covers an area using position absolute.
 * @param {object}              props.maskCustomAttributes Custom attributes for the mask.
 * @param {string|Array|object} props.maskCustomClasses    Custom classes for the mask.
 * @param {string}              props.maskTheme            Them for the mask, controls background color, one of `light` or `dark`.
 * @param                       props.alignment
 * @param {string}              props.text                 Optional text, either hidden or visible. Pass nothing to not render element.
 * @param {string}              props.textColor            The color for the text as css property value.
 * @param {object}              props.textCustomAttributes Custom attributes for the text.
 * @param {string|Array|object} props.textCustomClasses    Custom classes for the text.
 *
 * @return {JSX.Element} The Loader component.
 *
 */
const Loader = ( {
	children = null,
	displayText = true,
	loader = null,
	mask = false,
	maskCustomAttributes = {},
	maskCustomClasses = [],
	maskTheme = 'light',
	text = '',
	textColor = '#000',
	textCustomAttributes = {},
	textCustomClasses = [],
} ) => {
	const maskProps = mask ? {
		className: classnames( {
			'gform-loader__mask': true,
			[ `gform-loader__mask--theme-${ maskTheme }` ]: true,
		}, maskCustomClasses ),
		...maskCustomAttributes,
	} : {};

	const textProps = text ? {
		className: classnames( {
			'gform-loader__text': displayText,
			'gform-visually-hidden': ! displayText,
		}, textCustomClasses ),
		style: {
			color: textColor,
		},
		...textCustomAttributes,
	} : {};

	return (
		<>
			<ConditionalWrapper
				condition={ mask }
				wrapper={ ( ch ) => <div { ...maskProps }>{ ch }</div> }
			>
				<ConditionalWrapper
					condition={ ! mask && text && displayText }
					wrapper={ ( ch ) => <span className="gform-loader__inner">{ ch }</span> }
				>
					{ loader }
					{ text && <span { ...textProps }>{ text }</span> }
					{ children }
				</ConditionalWrapper>
			</ConditionalWrapper>
		</>
	);
};

Loader.propTypes = {
	children: PropTypes.oneOfType( [
		PropTypes.arrayOf( PropTypes.node ),
		PropTypes.node,
	] ),
	displayText: PropTypes.bool,
	loader: PropTypes.node,
	mask: PropTypes.bool,
	maskCustomAttributes: PropTypes.object,
	maskCustomClasses: PropTypes.oneOfType( [
		PropTypes.string,
		PropTypes.array,
		PropTypes.object,
	] ),
	maskTheme: PropTypes.string,
	text: PropTypes.string,
	textColor: PropTypes.string,
	textCustomAttributes: PropTypes.object,
	textCustomClasses: PropTypes.oneOfType( [
		PropTypes.string,
		PropTypes.array,
		PropTypes.object,
	] ),
};

Loader.displayName = 'Loader';

export default Loader;
