( function ( wp ) {
	if ( ! wp || ! wp.blocks || ! wp.element || ! wp.blockEditor || ! wp.components || ! wp.i18n ) {
		return;
	}

	var BLOCK_NAME = 'skynsmfa/wishlist-menu-icon';
	var DEFAULT_ICON_SIZE = 28;
	var DEFAULT_BADGE_COLOR = '#cc1818';
	var DEFAULT_BADGE_TEXT_COLOR = '#ffffff';

	var paletteColors = [
		{ name: 'Black', color: '#000000' },
		{ name: 'White', color: '#ffffff' },
		{ name: 'Red', color: '#cc1818' },
		{ name: 'Pink', color: '#e91e63' },
		{ name: 'Gray', color: '#757575' },
	];

	function normalizeAttributes( attributes ) {
		attributes = attributes || {};
		var iconSize = parseInt( attributes.iconSize, 10 );
		if ( ! Number.isFinite( iconSize ) ) {
			iconSize = DEFAULT_ICON_SIZE;
		}
		iconSize = Math.max( 16, Math.min( 80, iconSize ) );

		return {
			countVisibility: attributes.countVisibility || 'greater_than_zero',
			iconSize: iconSize,
			iconColor: attributes.iconColor || '',
			badgeColor: attributes.badgeColor || DEFAULT_BADGE_COLOR,
			badgeTextColor: attributes.badgeTextColor || DEFAULT_BADGE_TEXT_COLOR,
			customIconUrl: attributes.customIconUrl || '',
			customIconId: parseInt( attributes.customIconId, 10 ) || 0,
		};
	}

	function badgeMetrics( iconSize ) {
		return {
			minWidth: Math.max( 14, Math.round( iconSize * 0.55 ) ),
			height: Math.max( 14, Math.round( iconSize * 0.55 ) ),
			fontSize: Math.max( 9, Math.round( iconSize * 0.38 ) ),
			top: Math.round( iconSize * -0.12 ),
			right: Math.round( iconSize * -0.2 ),
			paddingX: Math.max( 2, Math.round( iconSize * 0.1 ) ),
		};
	}

	function renderDefaultHeartIcon( createElement, iconColor ) {
		return createElement(
			'svg',
			{
				className: 'skynsmfa-wishlist-icon',
				viewBox: '0 0 24 24',
				'aria-hidden': 'true',
				focusable: 'false',
				style: {
					width: '100%',
					height: '100%',
					display: 'block',
					fill: iconColor || 'currentColor',
				},
			},
			createElement( 'path', {
				d: 'M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3 9.24 3 10.91 3.81 12 5.09 13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z',
			} )
		);
	}

	function renderMenuIconPreview( createElement, rawAttributes ) {
		var attrs = normalizeAttributes( rawAttributes );
		var badge = badgeMetrics( attrs.iconSize );
		var showBadge = attrs.countVisibility !== 'never';
		var iconColor = attrs.iconColor || undefined;

		return createElement(
			'span',
			{
				className: 'skynsmfa-menu-icon skynsmfa-menu-icon--editor-preview',
				style: {
					color: iconColor,
					'--skynsmfa-menu-icon-size': attrs.iconSize + 'px',
					'--skynsmfa-menu-icon-color': iconColor || 'currentColor',
					'--skynsmfa-badge-bg': attrs.badgeColor,
					'--skynsmfa-badge-color': attrs.badgeTextColor,
				},
			},
			createElement(
				'span',
				{
					className: 'skynsmfa-menu-icon__quantity',
					style: {
						position: 'relative',
						display: 'inline-flex',
						width: attrs.iconSize + 'px',
						height: attrs.iconSize + 'px',
					},
				},
				createElement(
					'span',
					{
						className: 'skynsmfa-menu-icon__icon',
						'aria-hidden': 'true',
						style: {
							display: 'inline-flex',
							width: attrs.iconSize + 'px',
							height: attrs.iconSize + 'px',
							color: iconColor,
						},
					},
					attrs.customIconUrl
						? createElement( 'img', {
							className: 'skynsmfa-menu-icon__custom-image',
							src: attrs.customIconUrl,
							alt: '',
							width: attrs.iconSize,
							height: attrs.iconSize,
							style: {
								width: attrs.iconSize + 'px',
								height: attrs.iconSize + 'px',
								display: 'block',
								objectFit: 'contain',
							},
						} )
						: renderDefaultHeartIcon( createElement, attrs.iconColor )
				),
				showBadge
					? createElement(
						'span',
						{
							className: 'skynsmfa-menu-icon__badge',
							style: {
								position: 'absolute',
								top: badge.top + 'px',
								right: badge.right + 'px',
								minWidth: badge.minWidth + 'px',
								height: badge.height + 'px',
								paddingLeft: badge.paddingX + 'px',
								paddingRight: badge.paddingX + 'px',
								borderRadius: '999px',
								backgroundColor: attrs.badgeColor,
								color: attrs.badgeTextColor,
								fontSize: badge.fontSize + 'px',
								fontWeight: 600,
								lineHeight: badge.height + 'px',
								textAlign: 'center',
								boxSizing: 'border-box',
								display: 'inline-flex',
								alignItems: 'center',
								justifyContent: 'center',
							},
						},
						'0'
					)
					: null
			)
		);
	}

	function renderColorControl( createElement, label, value, onChange ) {
		var ColorPalette = wp.components.ColorPalette;
		if ( ! ColorPalette ) {
			return null;
		}

		return createElement(
			wp.element.Fragment,
			null,
			createElement( 'p', { className: 'components-base-control__label' }, label ),
			createElement( ColorPalette, {
				colors: paletteColors,
				value: value || undefined,
				onChange: onChange,
				disableCustomColors: false,
			} )
		);
	}

	function MenuIconEdit( props ) {
		var blockEditor = wp.blockEditor;
		var components = wp.components;
		var i18n = wp.i18n;
		var __ = i18n.__;
		var createElement = wp.element.createElement;
		var Fragment = wp.element.Fragment;
		var useBlockProps = blockEditor.useBlockProps;
		var InspectorControls = blockEditor.InspectorControls;
		var PanelBody = components.PanelBody;
		var SelectControl = components.SelectControl;
		var RangeControl = components.RangeControl;
		var Button = components.Button;

		var attrs = normalizeAttributes( props.attributes );
		var setAttributes = props.setAttributes;
		var blockProps = useBlockProps( {
			className: 'skynsmfa-menu-icon-editor-wrap',
		} );

		var MediaUpload = blockEditor.MediaUpload;
		var MediaUploadCheck = blockEditor.MediaUploadCheck;
		var mediaControls = null;

		if ( MediaUpload && MediaUploadCheck ) {
			mediaControls = createElement(
				MediaUploadCheck,
				null,
				createElement( MediaUpload, {
					onSelect: function ( media ) {
						if ( ! media ) {
							return;
						}
						setAttributes( {
							customIconId: media.id || 0,
							customIconUrl: media.url || '',
						} );
					},
					allowedTypes: [ 'image' ],
					value: attrs.customIconId,
					render: function ( obj ) {
						return createElement(
							'div',
							{ className: 'skynsmfa-menu-icon-editor__media-actions' },
							createElement(
								Button,
								{
									onClick: obj.open,
									isSecondary: true,
								},
								attrs.customIconUrl
									? __( 'Replace custom icon', 'skynet-smart-favorites' )
									: __( 'Upload custom icon', 'skynet-smart-favorites' )
							),
							attrs.customIconUrl
								? createElement(
									Button,
									{
										onClick: function () {
											setAttributes( {
												customIconId: 0,
												customIconUrl: '',
											} );
										},
										isLink: true,
										isDestructive: true,
									},
									__( 'Use default heart', 'skynet-smart-favorites' )
								)
								: null
						);
					},
				} )
			);
		}

		return createElement(
			Fragment,
			null,
			createElement(
				InspectorControls,
				null,
				createElement(
					PanelBody,
					{ title: __( 'Icon', 'skynet-smart-favorites' ), initialOpen: true },
					RangeControl
						? createElement( RangeControl, {
							label: __( 'Icon size (px)', 'skynet-smart-favorites' ),
							value: attrs.iconSize,
							onChange: function ( value ) {
								setAttributes( { iconSize: value === undefined ? DEFAULT_ICON_SIZE : value } );
							},
							min: 16,
							max: 80,
						} )
						: null,
					renderColorControl(
						createElement,
						__( 'Icon color', 'skynet-smart-favorites' ),
						attrs.iconColor,
						function ( value ) {
							setAttributes( { iconColor: value || '' } );
						}
					),
					mediaControls,
					attrs.customIconUrl
						? createElement(
							'div',
							{ className: 'skynsmfa-menu-icon-editor__media-preview' },
							createElement( 'img', { src: attrs.customIconUrl, alt: '' } )
						)
						: null
				),
				createElement(
					PanelBody,
					{ title: __( 'Counter badge', 'skynet-smart-favorites' ), initialOpen: false },
					createElement( SelectControl, {
						label: __( 'Show count badge', 'skynet-smart-favorites' ),
						value: attrs.countVisibility,
						options: [
							{
								label: __( 'When greater than zero', 'skynet-smart-favorites' ),
								value: 'greater_than_zero',
							},
							{ label: __( 'Always', 'skynet-smart-favorites' ), value: 'always' },
							{ label: __( 'Never', 'skynet-smart-favorites' ), value: 'never' },
						],
						onChange: function ( value ) {
							setAttributes( { countVisibility: value } );
						},
					} ),
					renderColorControl(
						createElement,
						__( 'Badge background', 'skynet-smart-favorites' ),
						attrs.badgeColor,
						function ( value ) {
							setAttributes( { badgeColor: value || DEFAULT_BADGE_COLOR } );
						}
					),
					renderColorControl(
						createElement,
						__( 'Badge text color', 'skynet-smart-favorites' ),
						attrs.badgeTextColor,
						function ( value ) {
							setAttributes( { badgeTextColor: value || DEFAULT_BADGE_TEXT_COLOR } );
						}
					)
				)
			),
			createElement(
				'div',
				blockProps,
				renderMenuIconPreview( createElement, props.attributes )
			)
		);
	}

	function registerMenuIconBlock() {
		var blocks = wp.blocks;
		var i18n = wp.i18n;
		var __ = i18n.__;

		if ( ! blocks ) {
			return;
		}

		var editSettings = {
			edit: MenuIconEdit,
			save: function () {
				return null;
			},
		};

		if ( blocks.getBlockType( BLOCK_NAME ) ) {
			blocks.registerBlockType( BLOCK_NAME, editSettings );
			return;
		}

		blocks.registerBlockType( BLOCK_NAME, {
			apiVersion: 3,
			title: __( 'SkyNet Smart Favorites icon', 'skynet-smart-favorites' ),
			description: __(
				'Links to your wishlist page and shows how many items are saved.',
				'skynet-smart-favorites'
			),
			category: 'woocommerce',
			icon: 'heart',
			keywords: [
				__( 'wishlist', 'skynet-smart-favorites' ),
				__( 'favorites', 'skynet-smart-favorites' ),
				__( 'heart', 'skynet-smart-favorites' ),
				__( 'SkyNet Smart Favorites', 'skynet-smart-favorites' ),
				'skynet',
			],
			attributes: {
				countVisibility: {
					type: 'string',
					default: 'greater_than_zero',
				},
				iconSize: {
					type: 'number',
					default: DEFAULT_ICON_SIZE,
				},
				iconColor: {
					type: 'string',
					default: '',
				},
				badgeColor: {
					type: 'string',
					default: DEFAULT_BADGE_COLOR,
				},
				badgeTextColor: {
					type: 'string',
					default: DEFAULT_BADGE_TEXT_COLOR,
				},
				customIconUrl: {
					type: 'string',
					default: '',
				},
				customIconId: {
					type: 'number',
					default: 0,
				},
			},
			supports: {
				html: false,
				align: true,
				spacing: {
					margin: true,
					padding: true,
				},
			},
			edit: MenuIconEdit,
			save: function () {
				return null;
			},
		} );
	}

	registerMenuIconBlock();
} )( window.wp );
