/**
 * External dependencies.
 */
import { useEffect, memo } from '@wordpress/element';
import { useBlockProps, useInnerBlocksProps } from '@wordpress/block-editor';
import { useDispatch, useSelect } from '@wordpress/data';
import { createBlocksFromInnerBlocksTemplate } from '@wordpress/blocks';

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

/**
 * The Editor Block render for Form Input Wrapper.
 *
 * @param {Object} props The element props.
 * @since 2.0.0
 * @return {Element} The rendered block.
 */
const Render = ( props ) => {
	// Destructure the required props.
	const {
		clientId,
		attributes: {
			fieldPlaceholder,
			isRequired
		},
		context
	} = props;

	// Get context values from parent form
	const {
		'spectra-pro/form/demoFieldErrorMessage': demoFieldErrorMessage,
		'spectra-pro/form/messageEmailMissingError': messageEmailMissingError,
		'spectra-pro/form/messageEmailAlreadyUsedError': messageEmailAlreadyUsedError
	} = context;


	const { replaceInnerBlocks, updateBlockAttributes } = useDispatch( 'core/block-editor' );

	// Get block children to check if template already exists
	const { hasChildBlocks } = useSelect( ( select ) => {
		const { getBlocks } = select( 'core/block-editor' );
		const currentBlockChildren = getBlocks( clientId );
		return {
			hasChildBlocks: currentBlockChildren.length > 0
		};
	} );

	// Function to update existing inner blocks when wrapper attributes change
	const updateExistingBlocks = () => {
		const { getBlocks } = wp.data.select( 'core/block-editor' );
		const childBlocks = getBlocks( clientId );

		childBlocks.forEach( block => {
			if ( block.name === 'spectra-pro/form-input-label' ) {
				// Update the label's required state
				updateBlockAttributes( block.clientId, {
					isRequired
				} );
			} else if ( block.name === 'spectra-pro/form-field-wrapper' ) {
				// Check inner blocks of the field wrapper
				block.innerBlocks.forEach( innerBlock => {
					if ( innerBlock.name === 'spectra-pro/form-input-field' ) {
						updateBlockAttributes( innerBlock.clientId, {
							placeholder: fieldPlaceholder,
							isRequired
						} );
					}
				} );
			}
		} );
	};

	// Create/update template when settings change
	useEffect( () => {
		// If children exist, update their attributes instead of recreating
		if ( hasChildBlocks ) {
			updateExistingBlocks();
			return;
		}
		const template = [];

		// Always add label - it will hide itself via context when showLabels is false
		template.push( [
			'spectra-pro/form-input-label',
			{
				labelText: 'Email Address',
				isRequired
			}
		] );

		// Create input group container with icon and field
		const inputGroupChildren = [];

		// Always add icon - it will hide itself via context when showIcons is false
		// Don't set icon attribute - form-icon will use fieldType to determine default
		// This preserves custom SVG icons and sizes
		inputGroupChildren.push( [
			'spectra-pro/form-icon',
			{
				fieldType: 'email'
			}
		] );
		
		// Always add the input field
		inputGroupChildren.push( [
			'spectra-pro/form-input-field',
			{
				inputType: 'email',
				placeholder: fieldPlaceholder || 'Enter your email address',
				isRequired
			}
		] );

		// Add input group field wrapper
		template.push( [
			'spectra-pro/form-field-wrapper',
			{
				className: 'spectra-pro-form-input-group'
			},
			inputGroupChildren
		] );

		// Replace inner blocks with the new template only on initial creation
		replaceInnerBlocks( clientId, createBlocksFromInnerBlocksTemplate( template ) );
	}, [ fieldPlaceholder, isRequired, clientId, hasChildBlocks ] );



	// Create combined attributes with context values for color handling
	const combinedAttributes = {
		...props.attributes,
		labelColor: props.attributes.labelColor || context['spectra-pro/form/labelColor'],
		labelColorHover: props.attributes.labelColorHover || context['spectra-pro/form/labelColorHover'],
		inputTextColor: props.attributes.inputTextColor || context['spectra-pro/form/inputTextColor'],
		inputTextColorHover: props.attributes.inputTextColorHover || context['spectra-pro/form/inputTextColorHover'],
		inputBgColor: props.attributes.inputBgColor || context['spectra-pro/form/inputBgColor'],
		inputBgColorHover: props.attributes.inputBgColorHover || context['spectra-pro/form/inputBgColorHover'],
		iconColor: props.attributes.iconColor || context['spectra-pro/form/iconColor'],
	};

	// Configuration for useSpectraStyles hook
	const config = [
		{ key: 'labelColor', cssVar: '--spectra-label-color', className: 'spectra-label-color' },
		{ key: 'labelColorHover', cssVar: '--spectra-label-color-hover', className: 'spectra-label-color-hover' },
		{ key: 'inputTextColor', cssVar: '--spectra-input-text-color', className: 'spectra-input-text-color' },
		{ key: 'inputTextColorHover', cssVar: '--spectra-input-text-color-hover', className: 'spectra-input-text-color-hover' },
		{ key: 'inputBgColor', cssVar: '--spectra-input-bg-color', className: 'spectra-input-bg-color' },
		{ key: 'inputBgColorHover', cssVar: '--spectra-input-bg-color-hover', className: 'spectra-input-bg-color-hover' },
		{ key: 'iconColor', cssVar: '--spectra-icon-color', className: 'spectra-icon-color' },
	];

	// Generate styles and class names using useSpectraStyles hook
	const { style: generatedStyle, classNames: generatedClassNames } = useSpectraStyles( combinedAttributes, config );

	// Custom class names
	const customClassNames = [
		'spectra-pro-register-email',
		'spectra-pro-form-input-wrapper--email',
		// Add error class when demo field error is enabled
		...( demoFieldErrorMessage ? ['spectra-pro-register-form__input-error'] : [] )
	];

	// Get block props
	const blockProps = useBlockProps( {
		className: spectraClassNames( [...customClassNames, ...generatedClassNames] ),
		style: generatedStyle
	} );

	// Get inner blocks props
	const innerBlocksProps = useInnerBlocksProps( blockProps, {
		allowedBlocks: [ 'spectra-pro/form-input-label', 'spectra-pro/form-field-wrapper', 'spectra-pro/form-input-field', 'spectra-pro/form-icon' ],
		templateLock: 'all',
		renderAppender: false
	} );

	return (
		<div { ...innerBlocksProps }>
			{ innerBlocksProps.children }
			{ demoFieldErrorMessage && (
				<span className="spectra-pro-register-form__field-error-message">
					{ messageEmailMissingError || messageEmailAlreadyUsedError || 'Please enter a valid email address.' }
				</span>
			) }
		</div>
	);
};

export default memo( Render );