/**
 * External dependencies
 */
import { RichText, useBlockProps } from '@wordpress/block-editor';
import { memo, useCallback, useMemo } from '@wordpress/element';
import { select } from '@wordpress/data';
import { __ } from '@wordpress/i18n';

/**
 * Internal dependencies
 */
import { spectraClassNames } from '@spectra-helpers';
import { useSpectraStyles } from '@spectra-hooks';
import RenderSVG from '@spectra-helpers/render-svg';

/**
 * The Editor Block render.
 *
 * @param {Object} props The element props.
 * @since x.x.x
 * @return {Element} The rendered block.
 */
const Render = ( props ) => {
	const {
		isSelected,
		setAttributes,
		context: {
			'spectra-pro/loop-builder-pagination/textColor': parentTextColor,
			'spectra-pro/loop-builder-pagination/textColorHover': parentTextColorHover,
			'spectra-pro/loop-builder-pagination/backgroundColor': parentBackgroundColor,
			'spectra-pro/loop-builder-pagination/backgroundColorHover': parentBackgroundColorHover,
			'spectra-pro/loop-builder-pagination/backgroundGradient': parentBackgroundGradient,
			'spectra-pro/loop-builder-pagination/backgroundGradientHover': parentBackgroundGradientHover,
		},
		attributes,
	} = props;

	const {
		text,
		showText,
		icon,
		iconPosition,
		textColor = parentTextColor,
		textColorHover = parentTextColorHover,
		iconColor = parentTextColor,
		iconColorHover = parentTextColorHover,
		backgroundColor = parentBackgroundColor,
		backgroundColorHover = parentBackgroundColorHover,
		backgroundGradient = parentBackgroundGradient,
		backgroundGradientHover = parentBackgroundGradientHover,
		size,
		rotation,
		flipForRTL
	} = attributes;

	/**
	 * Dynamically retrieve all registered RichText format types from the
	 * WordPress rich-text store and exclude the 'core/link' format.
	 *
	 * This ensures that all other formatting options (like bold, italic, etc.)
	 * remain available in the RichText toolbar, while preventing users from
	 * inserting or editing links.
	 */
	const allowedFormats = useMemo( () => {
		const allFormats = select( 'core/rich-text' ).getFormatTypes() || [];
	
		return allFormats
			.map( ( format ) => format.name )
			.filter( ( name ) => name !== 'core/link' && name !== 'core/footnote' );
	}, [] );

	// Configuration for the useSpectraStyles hook.
	const config = [
		{ key: 'textColor', value: textColor },
		{ key: 'textColorHover', value: textColorHover },
		{ key: 'iconColor', value: iconColor },
		{ key: 'iconColorHover', value: iconColorHover },
		{ key: 'backgroundColor', value: backgroundColor },
		{ key: 'backgroundColorHover', value: backgroundColorHover },
		{ key: 'backgroundGradient', value: backgroundGradient },
		{ key: 'backgroundGradientHover', value: backgroundGradientHover },
		{ key: 'gap' },
	];

	// Additional classes.
	const additionalClasses = [ 'wp-block-button', 'wp-block-button__link', isSelected && 'current' ];

	// Generate styles and class names.
	const { style, classNames } = useSpectraStyles( attributes, config, additionalClasses );

	// Use the block props, with the added CSS variables and their related classes.
	const blockProps = useBlockProps( {
		className: spectraClassNames( classNames ),
		style,
	} );

	const iconHtml = useCallback(
		( position ) => {
			const finalIconPosition = iconPosition || 'after';

			if ( ! icon || position !== finalIconPosition ) {
				return null;
			}

			return (
				<RenderSVG
					className={ spectraClassNames( [
						'spectra-button__icon',
						`spectra-button__icon-position-${ finalIconPosition }`,
						iconColor && 'spectra-icon-color',
						iconColorHover && 'spectra-icon-color-hover',
					] ) }
					svg={ icon }
					needsRTL={ flipForRTL }
					extraProps={ {
						width: size,
						height: size,
						style: { 
							width: size,
							height: size,
							transform: rotation ? `rotate(${ rotation }deg)` : '',
						},
					} }
				/>
			);
		},
		[ icon, iconPosition, size, iconColor, iconColorHover, rotation, flipForRTL ]
	);

	const btnText = useCallback( () => {
		if ( ! showText ) {
			return '';
		}

		return (
			<RichText
				placeholder={ __( 'Next', 'spectra-pro' ) }
				value={ text }
				tagName="div"
				onChange={ ( value ) => setAttributes( { text: value } ) }
				className="spectra-button__link"
				allowedFormats={ allowedFormats }
			/>
		);
	}, [ showText, text, setAttributes ] );

	return (
		<div { ...blockProps }>
			{ iconHtml( 'before' ) }
			{ btnText() }
			{ iconHtml( 'after' ) }
		</div>
	);
};

export default memo( Render );
