import {
	BlockControls,
	RichText,
} from '@wordpress/block-editor';
import { ToolbarGroup, DropdownMenu, Icon } from '@wordpress/components';
import { __, sprintf } from '@wordpress/i18n';
import { useEffect, useState, useRef } from '@wordpress/element';
import {
	headingLevel1,
	headingLevel2,
	headingLevel3,
	headingLevel4,
	headingLevel5,
	headingLevel6,
	paragraph,
} from '@wordpress/icons';

// This control use to create richtext area in editor
export const RichTextControl = (props) =>{
	
	const { _props, propsName, value, tagName : TagName } = props;
	const { setAttributes, attributes } = _props;
	const [headingLevel, setHeadingLevel] = useState(null);
	const richRef = useRef(null);
		
	var newProps = { ...props };
	
	var renderVal = pagelayerTrim(value);
	if(renderVal == `{{${propsName}}}`){
		renderVal = '';
	}
	
	delete newProps._props;
	delete newProps.propsName;
	delete newProps.value;
	delete newProps['pagelayer-editable'];
	
	const tagNames = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6']; 

	// Make child editable if child is single and wrapped by block tag
	var children = jQuery(`<div>${value}</div>`)[0].childNodes;
	var childTag = null;
	
	if(
		children.length == 1 &&
		children[0].nodeType != 3 &&
		tagNames.indexOf(children[0].localName) != -1
	){
		childTag = children[0].localName;
		delete newProps.tagName;
	}
	
	// Save the rich text data with tag
	const HeadingFormatting = (value) => {
		
		if(headingLevel == null) return;
		
		var newTag = tagNames[headingLevel];
		var newVal = `<${newTag}>${value}</${newTag}>`;
		
		if(children[0].attributes.length > 0){
			newVal = `<${newTag} ${children[0].attributes}>${value}</${newTag}>`;
		}
		
		setAttributes({ [propsName]: newVal });
	}
	
	useEffect( () => {
		//HeadingFormatting
		if (richRef.current) {
		  richRef.current.dispatchEvent(new Event('input', { bubbles: true }));
		}
	}, [headingLevel]);

	useEffect(() => {
		if(children.length < 1){
			return;
		}
		setHeadingLevel( tagNames.indexOf(children[0].localName) );
	}, []);
		
	return (
		<>
			{ childTag ? (
				<>
					<BlockControls group="block">
						<HeadingLevelDropdown
							options={ [ 1, 2, 3, 4, 5, 6, 0 ] }
							value={ headingLevel }
							onChange={ ( newLevel ) =>
								setHeadingLevel(newLevel)
							}
						/>
					</BlockControls>
					<TagName {...newProps}>
						<RichText
							ref={richRef}
							key="editable"
							tagName={childTag}
							keepPlaceholderOnFocus
							placeholder={'Add Content...'}
							onChange={ (value) => HeadingFormatting(value) }
							value={ children[0].innerHTML}
							{...children[0].attributes}
						/>
					</TagName>
				</>
			) : (
				<RichText
					key="editable"
					keepPlaceholderOnFocus
					placeholder={'Add Content...'}
					onChange={(value) => setAttributes({ [propsName]: value })}
					value={ pagelayer_empty(attributes[propsName]) ? renderVal : attributes[propsName]}
					{...newProps}
				/>
			)}
		</>
	);	
}

// HeadingLevelDropdown props.
const HEADING_LEVELS = [ 1, 2, 3, 4, 5, 6 ];
export function HeadingLevelDropdown( {
	options = HEADING_LEVELS,
	value,
	onChange,
} ) {
	const createLevelControl = (
		targetLevel,
		currentLevel,
		onChangeCallback
	) => {
		const isActive = targetLevel === currentLevel;
		return {
			icon: (
				<HeadingLevelIcon
					level={ targetLevel }
					isPressed={ isActive }
				/>
			),
			// translators: %s: heading level e.g: "1", "2", "3"
			// title: sprintf( __( 'Heading %d' ), targetLevel ),
			isActive,
			onClick: () => onChangeCallback( targetLevel ),
		};
	};

	return (
		<DropdownMenu
			icon={ <HeadingLevelIcon level={ value } /> }
			controls={ options.map( ( index ) =>
				createLevelControl( index, value, onChange )
			) }
			label={ __( 'Change level' ) }
		/>
	);
}

// HeadingLevelIcon props.

const LEVEL_TO_PATH = {
	0: paragraph,
	1: headingLevel1,
	2: headingLevel2,
	3: headingLevel3,
	4: headingLevel4,
	5: headingLevel5,
	6: headingLevel6,
};

export function HeadingLevelIcon( { level } ) {
	if ( LEVEL_TO_PATH[ level ] ) {
		return <Icon icon={ LEVEL_TO_PATH[ level ] } />;
	}

	return null;
}
