/**
 * External dependencies.
 */
import { createHigherOrderComponent } from '@wordpress/compose';
import { useSelect } from '@wordpress/data';

/**
 * Internal dependencies.
 */
import DynamicContentEnhancer from '@spectra-pro-extensions/dynamic-content/enhancers/DynamicContentEnhancer';
import { BLOCK_CONTENT_CONFIG, DYNAMIC_CONTENT_ATTR } from '@spectra-pro-extensions/dynamic-content/utils/constants';
import { isAllowedBlock } from '@spectra-pro-extensions/dynamic-content/utils/helpers';

/**
 * Higher Order Component to enhance blocks with dynamic content capability
 *
 * @since x.x.x
 *
 * @param {Function} BlockEdit - Original BlockEdit component
 * @return {Function} Enhanced component
 */
const withDynamicContent = createHigherOrderComponent( ( BlockEdit ) => {
	return ( props ) => {
		// Early return if not allowed block.
		if ( ! isAllowedBlock( props ) ) return <BlockEdit { ...props } />;

		const { clientId, name: blockName, attributes } = props;

		const config = BLOCK_CONTENT_CONFIG?.[ blockName ];

		// Early return if no config present.
		if ( ! config ) return <BlockEdit { ...props } />;

		const contentAttr = config.contentAttr;
		const contentValue = attributes?.[ contentAttr ]; // Saved value.

		// Fetch live block content from the editor state.
		const currentValue = useSelect(
			( select ) => {
				const block = select( 'core/block-editor' ).getBlock( clientId );
				return block?.attributes[ contentAttr ] || contentValue;
			},
			[ clientId, contentAttr ]
		);

		// Early return if no content or no dynamic content attribute present.
		if ( ! currentValue || ! currentValue.includes( DYNAMIC_CONTENT_ATTR ) ) return <BlockEdit { ...props } />;

		return (
			<DynamicContentEnhancer
				clientId={ clientId }
				attributes={ attributes }
				contentAttr={ contentAttr }
				currentValue={ currentValue }
				props={ props }
				BlockEdit={ BlockEdit }
			/>
		);
	};
}, 'withDynamicContent' );

export default withDynamicContent;
