/**
 * Gallery Masonry Display Block Settings
 * Adds masonry layout option to core/gallery block
 *
 * @package Brandy\BlockSettings\GalleryMasonryDisplay
 */

(function () {
	const { addFilter } = wp.hooks;
	const { createHigherOrderComponent } = wp.compose;
	const { Fragment, useEffect } = wp.element;
	const { InspectorControls } = wp.blockEditor;
	const { ToggleControl, PanelBody } = wp.components;
	const { __ } = wp.i18n;

	/**
	 * Check if block is a gallery block
	 */
	function isGalleryBlock(name) {
		return name === "core/gallery";
	}

	/**
	 * Add custom attributes to gallery block
	 */
	function addGalleryMasonryAttributes(settings) {
		if (!settings.attributes || !isGalleryBlock(settings.name)) {
			return settings;
		}

		settings.attributes = Object.assign(settings.attributes, {
			masonryDisplay: {
				type: "boolean",
				default: false,
			},
		});

		return settings;
	}

	addFilter(
		"blocks.registerBlockType",
		"brandy-blocks/gallery-masonry-attribute",
		addGalleryMasonryAttributes
	);

	/**
	 * Add inspector controls for masonry display setting
	 */
	const GalleryMasonryControls = createHigherOrderComponent((BlockEdit) => {
		return (props) => {
			const { isSelected, attributes, setAttributes, name, clientId } = props;

			if (!isGalleryBlock(name)) {
				return React.createElement(BlockEdit, props);
			}

			// Update masonry columns in editor when attribute changes
			useEffect(() => {
				if (!attributes?.masonryDisplay) return;

				const columns = attributes.columns || 3;

				// Find and update gallery in editor iframe
				const updateMasonryColumns = () => {
					const editorFrame =
						document.querySelector('iframe[name="editor-canvas"]') ||
						document.querySelector("iframe.editor-canvas__iframe") ||
						document.querySelector('iframe[title="Editor canvas"]');

					if (!editorFrame?.contentDocument) return;

					try {
						const galleries = editorFrame.contentDocument.querySelectorAll(
							`[data-block="${clientId}"], .wp-block-gallery.has-masonry-display`
						);

						galleries.forEach((gallery) => {
							if (gallery.classList.contains("has-masonry-display")) {
								gallery.setAttribute("data-masonry-columns", columns);
								gallery.style.setProperty("--masonry-columns", columns);
							}
						});
					} catch (e) {
						// Cross-origin or other error - ignore
					}
				};

				updateMasonryColumns();
				const timeoutId = setTimeout(updateMasonryColumns, 100);
				return () => clearTimeout(timeoutId);
			}, [attributes.columns, attributes.masonryDisplay, clientId]);

			return React.createElement(
				Fragment,
				null,
				React.createElement(BlockEdit, props),
				isSelected &&
					React.createElement(
						InspectorControls,
						null,
						React.createElement(
							PanelBody,
							{
								title: __("Masonry Layout", "brandy"),
								initialOpen: false,
							},
							React.createElement(ToggleControl, {
								label: __("Enable Masonry Display", "brandy"),
								help: __(
									"Display gallery images in a masonry layout (Pinterest-style grid).",
									"brandy"
								),
								checked: attributes?.masonryDisplay ?? false,
								onChange: (value) => setAttributes({ masonryDisplay: value }),
							})
						)
					)
			);
		};
	}, "GalleryMasonryControls");

	addFilter(
		"editor.BlockEdit",
		"brandy-blocks/gallery-masonry-controls",
		GalleryMasonryControls
	);

	/**
	 * Apply masonry class to block wrapper in editor
	 */
	addFilter(
		"editor.BlockListBlock",
		"brandy-blocks/gallery-masonry-block-wrapper",
		function (BlockListBlock) {
			return function (props) {
				if (isGalleryBlock(props.name) && props.attributes?.masonryDisplay) {
					const columns = props.attributes.columns || 3;
					props.wrapperProps = {
						...props.wrapperProps,
						className:
							((props.wrapperProps?.className || "") + " has-masonry-display").trim(),
						"data-masonry-columns": columns,
						style: {
							...props.wrapperProps?.style,
							"--masonry-columns": columns,
						},
					};
				}
				return React.createElement(BlockListBlock, props);
			};
		}
	);
})();
