import { consoleInfo, getNode, objectToAttributes, trigger, spacerClasses } from '@gravityforms/utils';
/**
 * @function helpTextTemplate
 * @description The help text template function, can be used when not needing events or a help text instance.
 *
 * @since 2.2.0
 *
 * @param {object}              options                  The options for the select component.
 * @param {string}              options.content          Helper text.
 * @param {object}              options.customAttributes Any custom attributes.
 * @param {Array}               options.customClasses    Any custom classes.
 * @param {string}              options.id               Id for the helper text.
 * @param {string}              options.size             The font size for the helper text.
 * @param {string|number|Array} options.spacing          The spacing for the component, string or array.
 * @param {string}              options.weight           The font weight for the label.
 *
 * @return {string} The html for the help text component.
 */
export const helpTextTemplate = ( {
	content = '',
	customAttributes = {},
	customClasses = [],
	id = '',
	size = 'text-xs',
	spacing = '',
	weight = 'regular',
} ) => {
	if ( ! content ) {
		return '';
	}

	const helpTextAttrs = objectToAttributes( {
		...customAttributes,
		class: [
			'gform-input-help-text',
			`gform-typography--size-${ size }`,
			`gform-typography--weight-${ weight }`,
			...Object.keys( spacerClasses( spacing ) ),
			...customClasses,
		],
		id,
	} );

	return `
		<span ${ helpTextAttrs }>${ content }</span>
	`;
};

/**
 * @class HelpText
 * @description A help text component for use in various form inputs mainly.
 *
 * @since 2.2.0
 *
 * @param {string}              options.content          Helper text.
 * @param {object}              options.customAttributes Any custom attributes.
 * @param {Array}               options.customClasses    Any custom classes.
 * @param {string}              options.id               Id for the helper text.
 * @param {string}              options.size             The font size for the helper text.
 * @param {string|number|Array} options.spacing          The spacing for the component, string or array.
 * @param {string}              options.weight           The font weight for the label.
 *
 * @return {Class} The HelpText instance.
 */
export default class HelpText {
	/**
	 * @description The class constructor.
	 *
	 * @param {object} options The options object. Check defaults for descriptions.
	 */
	constructor( options = {} ) {
		this.options = {};
		Object.assign(
			this.options,
			{
				content: '',
				customAttributes: {},
				customClasses: [],
				id: '',
				rendered: false, // is this button already rendered in the dom, eg by php?
				renderOnInit: true, // render this button on init?
				size: 'text-xs',
				spacing: '',
				target: '', // the target to render to. Any valid css selector string.
				targetPosition: 'afterbegin', // the insert position for the target.
				weight: 'regular',
			},
			options
		);

		trigger( { event: 'gform/help_text/pre_init', native: false, data: { instance: this } } );

		this.elements = {};

		if ( this.options.renderOnInit ) {
			this.init();
		}
	}

	/**
	 * @function render
	 * @description Renders the box into the dom.
	 *
	 * @since 2.2.0
	 *
	 * @return {void}
	 */
	render() {
		const { rendered, target, targetPosition } = this.options;

		if ( ! rendered ) {
			const renderTarget = getNode( target, document, true );

			renderTarget.insertAdjacentHTML(
				targetPosition,
				helpTextTemplate( this.options )
			);
		}

		this.elements.helpText = getNode( `#${ this.options.id }`, document, true );
	}

	/**
	 * @function init
	 * @description Initialize the help text.
	 *
	 * @since 2.2.0
	 *
	 * @return {void}
	 */
	init() {
		this.render();

		trigger( { event: 'gform/help_text/post_render', native: false, data: { instance: this } } );

		consoleInfo( `Gravity Forms Admin: Initialized help text component on ${ this.options.target }.` );
	}
}
