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

const { forwardRef } = React;

/**
 * @module Card
 * @description A card component.
 *
 * @since 1.1.15
 *
 * @param {object}                     props                  Component props.
 * @param {JSX.Element|null}           props.afterCard        React elements for after the card.
 * @param {boolean}                    props.baseClass        Whether to include the base class.
 * @param {JSX.Element|null}           props.beforeCard       React elements for before the card.
 * @param {JSX.Element|null}           props.children         React element children.
 * @param {object}                     props.customAttributes Custom attributes for the component.
 * @param {string|Array|object}        props.customClasses    Custom classes for the component.
 * @param {string|number|Array|object} props.spacing          The spacing for the component, as a string, number, array, or object.
 * @param {string}                     props.style            The style of the card.
 * @param {object|null}                ref                    Ref to the component.
 *
 * @return {JSX.Element} The Card component.
 *
 */
const Card = forwardRef( ( {
	afterCard = null,
	baseClass = true,
	beforeCard = null,
	children = null,
	customAttributes = {},
	customClasses = [],
	spacing = 0,
	style = '',
}, ref ) => {
	const attributes = {
		className: classnames( {
			'gform-card': baseClass,
			[ `gform-card--${ style }` ]: style,
			...spacerClasses( spacing ),
		}, customClasses ),
		...customAttributes,
	};

	return (
		<article { ...attributes } ref={ ref }>
			{ beforeCard }
			{ children }
			{ afterCard }
		</article>
	);
} );

Card.propTypes = {
	afterCard: PropTypes.node,
	beforeCard: PropTypes.node,
	children: PropTypes.oneOfType( [
		PropTypes.arrayOf( PropTypes.node ),
		PropTypes.node,
	] ),
	customAttributes: PropTypes.object,
	customClasses: PropTypes.oneOfType( [
		PropTypes.string,
		PropTypes.array,
		PropTypes.object,
	] ),
	spacing: PropTypes.oneOfType( [
		PropTypes.string,
		PropTypes.number,
		PropTypes.array,
		PropTypes.object,
	] ),
	style: PropTypes.string,
};

Card.displayName = 'Card';

export default Card;
