/**
 * External Dependencies
 */
// import clsx from 'clsx';
import { assign, merge } from 'lodash';

/**
 * WordPress Dependencies
 */
import { __ } from '@wordpress/i18n';
import { addFilter } from '@wordpress/hooks';
import { createHigherOrderComponent } from '@wordpress/compose';
import { useEffect, useState } from '@wordpress/element';
import { useSelect } from '@wordpress/data';
// import { useEntityProp } from '@wordpress/core-data';
// import { registerPlugin } from '@wordpress/plugins';
// import { PluginMoreMenuItem, store as editorStore } from '@wordpress/editor';
// import { check } from '@wordpress/icons';

import {
	InspectorControls,	
	//useSettings,
	//useBlockEditContext 
} from '@wordpress/block-editor';

import {
	hasBlockSupport,
	store as blocksStore
} from '@wordpress/blocks';

// import {
// 	TabPanel,
// 	PanelBody,
// 	__experimentalUseCustomUnits as useCustomUnits,
// } from '@wordpress/components';

import SelectDevice from './inc/select-device';
import ColumnOrder from './inc/column-order';

import './editor.scss';
import './style.scss';

const featureIsSupported = block => {
	const name = block.name || block;
	if (window.uclaResponsiveSupport.responsiveUnsupportedBlocks.includes(name)) {
		return false;
	}
	return hasBlockSupport(block, 'responsiveControls', true);
}

/**
 * Add custom attributes for responsive settings.
 *
 * @param {Object} settings Settings for the block.
 *
 * @return {Object} settings Modified settings.
 */
function addResponsiveAttributes( settings ) {
	// check if object exists for old Gutenberg version compatibility
	if (typeof settings.attributes !== 'undefined' && featureIsSupported(settings)) {
		return assign( {}, settings, {
			attributes: merge(settings.attributes, {
				responsiveControls: {
					type: 'object',
					default: {}
				}
			})
		});
	}
	return settings;
}

const minHeightUnitIsSupported = block => {
	const name = block.name || block;
	const blockType = useSelect( ( select ) => {
		return select(blocksStore).getBlockType(name);
	}, [] );
	return !!(blockType?.attributes && Object.prototype.hasOwnProperty.call(blockType.attributes, 'minHeightUnit'));
}

/**
 * Add responsive controls on Block Panel.
 *
 * @param {function} BlockEdit Block edit component.
 *
 * @return {function} BlockEdit Modified block edit component.
 */
const withResponsiveControls = createHigherOrderComponent((BlockEdit)=> {
  return (props) => {

		if (featureIsSupported(props.name)) {
			const {
				attributes,
				setAttributes
			} = props;

			const {
				responsiveControls,
				style,
				borderColor,
				minHeight,
				minHeightUnit
			} = attributes;

			// TODO: Restructure responsiveControls object to match attributes object.

			const deviceType = useSelect( ( select ) => {
				return select( 'core/editor' ).getDeviceType();
			}, [] );

			const blockType = useSelect( ( select ) => {
					return select(blocksStore).getBlockType(props.name);
				}, [] );

			const supportsMinHeightUnit = !!(
					blockType?.attributes &&
					Object.prototype.hasOwnProperty.call(blockType.attributes, 'minHeightUnit')
				);

			useEffect(()=> {
				const {tablet, mobile, ...pruneStyles} = responsiveControls;
				
				switch (deviceType) {
					case 'Mobile':
						const mobileBorderColor = mobile?.borderColor ?? null;
						if (mobileBorderColor) {
							delete mobile['borderColor'];
						}
						setAttributes({
							style: mobile ? mobile : undefined,
							...(mobileBorderColor&& {borderColor: mobileBorderColor}),
							...(mobile?.minHeight && {minHeight: mobile.minHeight}),
							...(supportsMinHeightUnit && (mobile?.minHeightUnit ? {minHeightUnit: mobile.minHeightUnit} : {minHeightUnit: 'px'}))
						})
						break;
					case 'Tablet':
						const tabletBorderColor = tablet?.borderColor ?? null;
						if (tabletBorderColor) {
							delete tablet['borderColor'];
						}
						setAttributes({
							style: tablet ? tablet : undefined,
							...(tabletBorderColor && {borderColor: tabletBorderColor}),
							...(tablet?.minHeight && {minHeight: tablet.minHeight}),
							...(supportsMinHeightUnit && (tablet?.minHeightUnit ? {minHeightUnit: tablet.minHeightUnit} : {minHeightUnit: 'px'}))
						})
						break;
					case 'Desktop':
						const desktopBorderColor = pruneStyles?.borderColor ?? null;
						if (desktopBorderColor) {
							delete pruneStyles['borderColor'];
						}
						setAttributes({
							style: pruneStyles ? pruneStyles : undefined,
							...(desktopBorderColor && {borderColor: desktopBorderColor}),
							...(pruneStyles?.minHeight && {minHeight: pruneStyles.minHeight}),
							...(supportsMinHeightUnit && (pruneStyles?.minHeightUnit ? {minHeightUnit: pruneStyles.minHeightUnit} : {minHeightUnit: 'px'}))
						})
						break;
					default:
						console.log('Unknown Device Type: ', deviceType);
				}
			}, [deviceType])

			useEffect(()=> {
				// console.log('action', attributes)
				switch (deviceType) {
					case 'Mobile':
						let mobileStyles = responsiveControls;
						if (!style && !minHeight && !minHeightUnit) {
							delete mobileStyles['mobile'];
						} else {
							mobileStyles = {
								...mobileStyles,
								'mobile': {
									...style,
									...(borderColor && {'borderColor': borderColor}),
									...(minHeight && {'minHeight': minHeight}),
									...(minHeightUnit && {'minHeightUnit': minHeightUnit})
								}
							}
						}
						setAttributes({
							responsiveControls: mobileStyles
						})
						break;
					case 'Tablet':
						let tabletStyles = responsiveControls;
						if (!style && !minHeight && !minHeightUnit) {
							delete tabletStyles['tablet'];
						} else {
							tabletStyles = {
								...tabletStyles,
								'tablet': {
									...style,
									...(borderColor && {'borderColor': borderColor}),
									...(minHeight && {'minHeight': minHeight}),
									...(minHeightUnit && {'minHeightUnit': minHeightUnit})
								}
							}
						}
						setAttributes({
							responsiveControls: tabletStyles
						})
						break;
					case 'Desktop':
						// console.log('desktop action', style)
						setAttributes({
							responsiveControls: {
								...(responsiveControls.tablet && {'tablet': responsiveControls.tablet}),
								...(responsiveControls.mobile && {'mobile': responsiveControls.mobile}),
								...style,
								...(borderColor && {'borderColor': borderColor}),
								...(minHeight && {'minHeight': minHeight}),
								...(minHeightUnit && {'minHeightUnit': minHeightUnit})
							}
						});
						break;
					default:
						console.log('Unknown Device Type: ', deviceType);
				}
				
			}, [style, borderColor, minHeight, minHeightUnit])

			useEffect(()=>{
				// console.log('init attr', attributes)
				// console.log('init rc', responsiveControls)
				
				if (responsiveControls) {
					const {tablet, mobile, ...pruneStyles} = responsiveControls;
					setAttributes({
						style: pruneStyles ? pruneStyles : undefined
					})
				}
			}, [])
			
			return (
				<>
					<BlockEdit {...props} />
						<InspectorControls group="styles">
							{ featureIsSupported(props.name) && <SelectDevice isBlock={true}/> }
						</InspectorControls>
						<InspectorControls group="advanced">
							{(props.__unstableParentLayout?.type === 'flex' || props.__unstableParentLayout?.default?.type === 'flex' || props.__unstableParentLayout.type === 'grid') &&  <ColumnOrder {...props} deviceType={deviceType} />}
						</InspectorControls>
					
				</>
			)
		}
		return <BlockEdit {...props} />;
  }
}, 'withResponsiveControls');

/**
 * Add responsive styling to the block in the editor
 */
const addResponsiveStylingEditor = createHigherOrderComponent( (BlockListBlock) => {
  return (props) => {

		//const orderStyles = {style: {order: attributes?.style?.order}}
		// console.log(props)
    return (
			<BlockListBlock	{ ...props } 
				// wrapperProps={attributes?.style?.order && {style:{order: attributes?.style?.order}}}
			/>
		);
  }
}, 'addResponsiveStylingEditor' );

// Add responsive attribute
addFilter(
	'blocks.registerBlockType',
	'ucla-wordpress-plugin/responsive-attributes',
	addResponsiveAttributes
);

// Add responsive controls
addFilter(
	'editor.BlockEdit',
	'ucla-wordpress-plugin/responsive-controls',
	withResponsiveControls
);

// Add responsive styles (backend)
addFilter(
  'editor.BlockListBlock',
  'ucla-wordpress-plugin/responsive-styling-editor',
  addResponsiveStylingEditor
);