/**
 * WordPress dependencies
 */
import { BlockEditProps } from '@safe-wordpress/blocks';
import { store as EDITOR } from '@safe-wordpress/editor';
import { store as BLOCK_EDITOR } from '@safe-wordpress/block-editor';
import { createHigherOrderComponent } from '@safe-wordpress/compose';
import { select } from '@safe-wordpress/data';
import { addFilter } from '@safe-wordpress/hooks';

/**
 * External dependencies
 */
import { isEmpty } from 'lodash';
import { getFormEditorSettings } from '@nelio/forms/utils';

interface WithAllowedBlocksProps extends BEP {
	name: string;
	clientId: string;
	attributes: Record< string, unknown >;
}

addFilter(
	'editor.BlockEdit',
	'nelio-forms/setAllowedBlocks',
	createHigherOrderComponent(
		( WrappedElement: BE ) => ( props: WithAllowedBlocksProps ) => {
			if (
				! isBlockEditElement( WrappedElement ) ||
				! areBlockEditProps( props )
			) {
				return <WrappedElement { ...props } />;
			} //end if

			if ( props.name !== 'core/column' ) {
				return <WrappedElement { ...props } />;
			} //end if

			if ( ! isInForm( props.clientId ) ) {
				return <WrappedElement { ...props } />;
			} //end if

			const { allowedBlocks } = getFormEditorSettings();

			return (
				<WrappedElement
					{ ...{
						...props,
						attributes: {
							...props.attributes,
							allowedBlocks,
						},
					} }
				/>
			);
		},
		'withAllowedBlocks'
	)
);

type BE = ( props: BEP ) => JSX.Element;
type BEP = BlockEditProps< Record< string, unknown > >;

const isBlockEditElement = ( el: unknown ): el is BE => !! el;
const areBlockEditProps = ( props: unknown ): props is BEP => !! props;

const isInForm = ( clientId: string ): boolean =>
	select( EDITOR ).getEditedPostAttribute( 'type' ) === 'nelio_form' ||
	! isEmpty(
		select( BLOCK_EDITOR ).getBlockParentsByBlockName(
			clientId,
			'nelio-forms/form',
			true
		)
	);
