import allowedBlocks from '../../common/component/compatibility/allowedBlocks';
import NonTextComments from './nonTextComments';
import { openCommentBoardSidebar, positionFloatingElement, floatWholeBlockNonTextBoard, createFloatingIcons } from '../../common/utils';

const { __ } = wp.i18n;
const { BlockControls } = wp.blockEditor;  
const { createHigherOrderComponent, compose } = wp.compose;  // eslint-disable-line
const { displayShortcut, isKeyboardEvent } = wp.keycodes;
const { Fragment, useState, useMemo, useEffect } = wp.element;     // eslint-disable-line
const { ToolbarGroup, ToolbarButton } = wp.components;  // eslint-disable-line
const { useSelect } = wp.data;

const NonTextComment = new NonTextComments();
let isRichClassExist = document.activeElement.classList.contains('rich-text');

const nonTextBlock = createHigherOrderComponent(BlockEdit => {

	return (props) => {
		
		const {
			name,
			attributes,
			isSelected,
		} = props;

		const iframe = cfGetIframe();
		const iframeDocument = iframe ? iframe.contentWindow.document : null;

		var prefixAcf = 'acf/';
        if ( props.name.startsWith(prefixAcf) ) {

        	var selection = window.getSelection();
        	if(selection){
	        	var anchorOffset = selection.anchorOffset;
	        	var datatextValue = selection.anchorNode;

	        	if( ( null !== datatextValue && anchorOffset == 0 ) || props.attributes.datatext ){
	    			const [isActive, setIsActive] = useState(true);
	    		 	wp.data.dispatch('mdstore').setIsActive(true);
	        	}else{
	        		const [isActive, setIsActive] = useState(false);
	        		wp.data.dispatch('mdstore').setIsActive(false);
	        	}
	        }else{
	        	const [isActive, setIsActive] = useState(false);
	        	wp.data.dispatch('mdstore').setIsActive(false);
	        }
        	
        }else{
        	const [isActive, setIsActive] = (props.attributes.datatext) ? useState(true) : useState(false);
        	if (props.attributes.datatext) { wp.data.dispatch('mdstore').setIsActive(true) } else { wp.data.dispatch('mdstore').setIsActive(false) };
        }

		const isTemplate = wp.data.select('core/editor').getCurrentPostType();
      	const isEditingTemplate = isTemplate === 'wp_template';

		const blockAttributes = useSelect(select => select('core/block-editor').getSelectedBlock()?.attributes, [isSelected]);
		const selectors = useMemo(() => cfgetCustomAttribute(), []);
		
        useEffect(() => {
			
			const handleEvent = (event) => {
				const skipSelectors = [
					'mdspan',
					'ins.mdadded',
					'ins.mdmodified',
					'ins.mdremoved',
					'del.mdremoved',
				];

				const selectors = [
					'.commentIcon',
					'.non-core-block',
					'.cf-icon-wholeblock__comment',
					'.cf-icon__addBlocks',
					'.cf-icon__removeBlocks',
					'[align_sg_id]:not(.commentIcon)',
					'[textAlign_sg_id]:not(.commentIcon)',
					'[lock_sg_id]:not(.commentIcon)',
					'[url_sg_id]:not(.commentIcon)',
					'[link_sg_id]:not(.commentIcon)',
					'[width_sg_id]:not(.commentIcon)',
					'[style_sg_id]:not(.commentIcon)',
					'[tracks_sg_id]:not(.commentIcon)',
					'[contentposition_sg_id]:not(.commentIcon)',
					'[minheight_sg_id]:not(.commentIcon)',
				];

				// First check skipSelectors - if typing on these, always skip
				const shouldSkip = skipSelectors.some(
					sel => event.target.matches(sel) || event.target.closest(sel)
				);

				// Check if user is typing text or using delete keys (keydown event)
				const isTypingText = event.type === 'keydown' && 
					(event.key === 'Backspace' || 
					 event.key === 'Delete' ||
					 (event.key && event.key.length === 1 && 
					  !event.ctrlKey && 
					  !event.altKey && 
					  !event.metaKey));

				// If typing on skipSelectors OR typing text, immediately return
				if (shouldSkip || isTypingText) {
					return; // Exit early, no further processing
				}
	
				const matchResult = selectors.reduce((result, selector) => {
					if (result.isMatch) return result; // If already matched, skip further checks
					const isMatch = event.target.matches(selector) || event.target.closest(selector);
					return isMatch ? { isMatch: true, matchedSelector: selector } : result;
				}, { isMatch: false, matchedSelector: null });
	
				// Destructure the result
				const { isMatch, matchedSelector } = matchResult;
				if (isMatch) {
					openCommentBoardSidebar();
					
					// Call your function with the matched selector
					floatWholeBlockNonTextBoard(event, matchedSelector);

					let mdspanElements;
					let suggestionElements;
					if(iframeDocument){
						mdspanElements = iframeDocument.getElementsByTagName("mdspan");
						suggestionElements = iframeDocument.querySelectorAll('ins.mdadded, ins.mdmodified, ins.mdremoved, del.mdremoved');
					}else{
						mdspanElements = document.getElementsByTagName("mdspan");
						suggestionElements = document.querySelectorAll('ins.mdadded, ins.mdmodified, ins.mdremoved, del.mdremoved');
					}
					for (let i = 0; i < mdspanElements.length; i++) {
						mdspanElements[i].removeAttribute("data-rich-text-format-boundary");
					}
					if(suggestionElements){
						suggestionElements.forEach(element => {
							element.removeAttribute("data-rich-text-format-boundary");
						});
					}
				}
			};

			if (iframeDocument) {
				iframeDocument.addEventListener('click', handleEvent);
				iframeDocument.addEventListener('keydown', handleEvent);
			}else{
				// Attach the event listener to the document
				document.addEventListener('click', handleEvent);
				document.addEventListener('keydown', handleEvent);
			}
	
			// Cleanup event listener on unmount
			return () => {
				if (iframeDocument) {
					iframeDocument.removeEventListener('click', handleEvent);
					iframeDocument.removeEventListener('keydown', handleEvent);
				}else{
					document.removeEventListener('click', handleEvent);
					document.removeEventListener('keydown', handleEvent);
				}
			};
        }, [isSelected]);

		if ((allowedBlocks.text).includes(props.name)  || isRichClassExist) {
			return (

				<BlockEdit  {...props} />

			);
		}
		
		let focusedElement;
		if(iframeDocument){
			focusedElement = iframeDocument?.activeElement?.localName;
		} else{
			focusedElement = document.activeElement.localName;
		}
		if ('core/gallery' === name) {
			var isGalleryImageExist = props.attributes.images.length;
		}

		const handleKeyDown = (event) => {
            	
				var block = wp.data.select("core/block-editor").getSelectedBlock();
				let focusedElement;
				if(iframeDocument){
					focusedElement = iframeDocument?.activeElement?.localName;
				} else{
					focusedElement = document.activeElement.localName;
				}
                if (
					isSelected && 
					!(
					  allowedBlocks.text.includes(block?.name) ||
					  "figcaption" === focusedElement
					)
				  ) {
					if (isKeyboardEvent.primaryAlt(event, "m")) {
						event.preventDefault();
					  	NonTextComment.onToggleNonTextBlock();
					}
				  }
            
        };
        useEffect(() => {
            // Add the event listener for keydown
            window.addEventListener('keydown', handleKeyDown);

            // Cleanup on unmount
            return () => {
                window.removeEventListener('keydown', handleKeyDown);
            };
        }, [isSelected]);

		return (

			<Fragment>

				<BlockEdit {...props} />
				{isSelected && (!(allowedBlocks.text).includes(props.name) && ('figcaption' !== focusedElement) && 'yoast-seo/breadcrumbs' !== props.name && 
				!(allowedBlocks.excluded).includes(props.name)) && !isEditingTemplate && !isRichClassExist
					&&
					<BlockControls>
						<ToolbarGroup>
							<ToolbarButton
								icon="admin-comments"
								isActive={wp.data.select('mdstore').getIsActive()}
								label={__('Comment', 'commenting-feature')}
								onClick={NonTextComment.onToggleNonTextBlock}
								shortcut={displayShortcut.primaryAlt('m')}
								className={`toolbar-button-with-nontext toolbar-button__${props.name}`}
								onChange={e => props.setAttributes({ datatext: currentTime })}
							/>
						</ToolbarGroup>
					</BlockControls>
				}
			</Fragment>
		);
	};
}, 'nonTextBlock');

export default compose()(nonTextBlock);