import { React } from '@gravityforms/libraries';

const breakpoints = {
	md: 768,
	lg: 1280,
};

/**
 * @function getCss
 * @description Gets a string of CSS for the selector provided by applying the provided styles.
 * Optional breakpoint can be applied to create a media query.
 *
 * @since 1.1.18
 *
 * @param {string} selector   The CSS selector.
 * @param {object} styles     The styles to be applied, as key-value pairs.
 * @param {string} breakpoint The media query breakpoint to apply.
 *
 * @return {string} The CSS style.
 */
export const getCss = ( selector = '', styles = {}, breakpoint = '' ) => {
	if ( ! selector ) {
		return '';
	}

	const stylesArray = Object.keys( styles ).reduce( ( carry, styleKey ) => [
		...carry,
		`${ styleKey }: ${ styles[ styleKey ] };`,
	], [] );

	const bpOpen = breakpoint ? `@media only screen and (min-width: ${ breakpoints[ breakpoint ] }px) {` : '';
	const bpClose = breakpoint ? '}' : '';

	return `
	${ bpOpen }
	${ selector } {
		${ stylesArray.join( '' ) }
	}
	${ bpClose }
	`;
};

/**
 * @function getAllCss
 * @description Gets a string of all the CSS based on the array of styles provided.
 *
 * @since 1.1.18
 *
 * @param {Array} array Array of objects with selector, styles, and breakpoint.
 *
 * @return {string} The CSS styles.
 */
export const getAllCss = ( array = [] ) => {
	if ( ! Array.isArray( array ) ) {
		throw new Error( 'First argument should be an array.' );
	}

	return array.reduce( function( carry, prop ) {
		const { selector, styles, breakpoint } = prop;
		return `${ carry }${ getCss( selector, styles, breakpoint ) }`;
	}, '' );
};

/**
 * @function cssStyle
 * @description Gets the style element with CSS styles from the provided array of styles.
 *
 * @since 1.1.18
 *
 * @param {Array} styles Array of objects with selector, styles, and breakpoint.
 *
 * @return {JSX.Element} The style element with CSS styles.
 */
export default function cssStyle( styles = [] ) {
	return (
		<style>
			{ getAllCss( styles ) }
		</style>
	);
}
