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

const { forwardRef } = React;

const presetIconMap = {
	'metric-info': 'mail',
	'metric-success': 'check-circle',
	'metric-warn': 'clock',
	'metric-error': 'x-circle',
	'status-default': 'question-mark-simple',
	'status-locked': 'lock',
	'status-info': 'information-simple',
	'status-incorrect': 'x-simple',
	'status-correct': 'checkmark-simple',
	'status-error': 'exclamation-simple',
};

/**
 * @module Icon
 * @description Renders a simple icon component.
 *
 * @since 1.1.15
 *
 * @param {object}                     props                  Component props.
 * @param {JSX.Element}                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}                     props.icon             The name for the icon to use from the icon library specified in iconPrefix.
 * @param {string}                     props.iconPrefix       The prefix for the icon library to be used.
 * @param {string}                     props.preset           The preset for the icon.
 * @param {string|number|Array|object} props.spacing          The spacing for the component, as a string, number, array, or object.
 * @param {object|null}                ref                    Ref to the component.
 *
 * @return {JSX.Element} The icon component.
 *
 * @example
 * import Icon from '@gravityforms/components/react/admin/elements/Icon';
 *
 * return <Icon icon="exclamation" iconPrefix="gform-common-icon" />;
 *
 */
const Icon = forwardRef( ( {
	children = null,
	customAttributes = {},
	customClasses = [],
	icon = '',
	iconPrefix = 'gravity-component-icon',
	preset = '',
	spacing = '',
}, ref ) => {
	if ( ! icon.length && presetIconMap[ preset ] ) {
		icon = presetIconMap[ preset ];
	}

	const componentProps = {
		className: classnames( {
			[ `${ iconPrefix }` ]: true,
			[ `${ iconPrefix }--${ icon }` ]: icon.length > 0,
			[ `gform-icon--preset-active` ]: preset.length > 0,
			[ `gform-icon-preset--${ preset }` ]: preset.length > 0,
			...spacerClasses( spacing ),
		}, customClasses ),
		ref,
		...customAttributes,
	};
	return <span { ...componentProps }>{ children }</span>;
} );

Icon.propTypes = {
	children: PropTypes.oneOfType( [
		PropTypes.arrayOf( PropTypes.node ),
		PropTypes.node,
	] ),
	customAttributes: PropTypes.object,
	customClasses: PropTypes.oneOfType( [
		PropTypes.string,
		PropTypes.array,
		PropTypes.object,
	] ),
	icon: PropTypes.string,
	iconPrefix: PropTypes.string,
	spacing: PropTypes.oneOfType( [
		PropTypes.string,
		PropTypes.number,
		PropTypes.array,
		PropTypes.object,
	] ),
};

Icon.displayName = 'Icon';

export default Icon;
