<?php
/**
 * Gallery Masonry Display Block Setting
 *
 * Adds masonry layout option to core/gallery block using CSS columns.
 *
 * @package Brandy\BlockSettings\GalleryMasonryDisplay
 */

namespace Brandy\BlockSettings\GalleryMasonryDisplay;

use Brandy\Traits\SingletonTrait;
use Brandy\Interfaces\ExternalBlockSettingsInterface;

class Caller implements ExternalBlockSettingsInterface {
	use SingletonTrait;

	/**
	 * Track if styles have been enqueued.
	 *
	 * @var bool
	 */
	private $styles_enqueued = false;

	protected function __construct() {
		add_filter( 'block_type_metadata_settings', array( $this, 'declare_attribute' ), 10 );
		add_filter( 'block_type_metadata_settings', array( $this, 'override_callback' ), 10, 2 );
		add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_editor_assets' ) );
	}

	/**
	 * Declare masonryDisplay attribute for gallery block.
	 */
	public function declare_attribute( $settings ) {
		if ( empty( $settings['name'] ) || 'core/gallery' !== $settings['name'] ) {
			return $settings;
		}

		if ( ! empty( $settings['attributes'] ) ) {
			$settings['attributes']['masonryDisplay'] = array(
				'type'    => 'boolean',
				'default' => false,
			);
		}

		return $settings;
	}

	/**
	 * Override gallery block render callback.
	 */
	public function override_callback( $settings, $metadata ) {
		if ( 'core/gallery' === $metadata['name'] ) {
			$settings['render_callback'] = array( $this, 'render_callback' );
		}
		return $settings;
	}

	/**
	 * Enqueue editor scripts and styles.
	 */
	public function enqueue_editor_assets() {
		wp_enqueue_script(
			'brandy/gallery-masonry-display',
			BRANDY_TEMPLATE_URL . '/inc/BlockSettings/GalleryMasonryDisplay/script.js',
			array( 'wp-blocks', 'wp-element', 'wp-editor', 'wp-components', 'wp-i18n' ),
			BRANDY_SCRIPT_VERSION,
			true
		);

		// Enqueue styles for editor preview
		wp_register_style( 'brandy/gallery-masonry-display', false, array(), BRANDY_SCRIPT_VERSION );
		wp_enqueue_style( 'brandy/gallery-masonry-display' );
		wp_add_inline_style( 'brandy/gallery-masonry-display', $this->get_css() );
	}

	/**
	 * Conditionally enqueue frontend styles (only when masonry gallery is used).
	 */
	private function maybe_enqueue_frontend_styles() {
		if ( $this->styles_enqueued || is_admin() ) {
			return;
		}

		$this->styles_enqueued = true;

		wp_register_style( 'brandy/gallery-masonry-display', false, array(), BRANDY_SCRIPT_VERSION );
		wp_enqueue_style( 'brandy/gallery-masonry-display' );
		wp_add_inline_style( 'brandy/gallery-masonry-display', $this->get_css() );
	}

	/**
	 * Render gallery block with masonry support.
	 *
	 * @param array  $attributes Block attributes.
	 * @param string $content    Block content.
	 * @param object $block      Block instance.
	 * @return string Rendered block HTML.
	 */
	public function render_callback( $attributes, $content, $block ) {
		// Use default gallery render if available
		if ( function_exists( 'block_core_gallery_render' ) ) {
			$gallery_content = block_core_gallery_render( $attributes, $content );
		} else {
			return $content;
		}

		// Apply masonry modifications if enabled
		if ( empty( $attributes['masonryDisplay'] ) ) {
			return $gallery_content;
		}

		// Enqueue styles only when masonry is actually used
		$this->maybe_enqueue_frontend_styles();

		$processor = new \WP_HTML_Tag_Processor( $gallery_content );

		// Get column count from gallery attributes, default to 3
		$columns = isset( $attributes['columns'] ) && $attributes['columns'] > 0
			? absint( $attributes['columns'] )
			: 3;

		if ( $processor->next_tag( array( 'class_name' => 'wp-block-gallery' ) ) ) {
			$processor->add_class( 'has-masonry-display' );
			$processor->set_attribute( 'data-masonry-columns', $columns );

			// Add CSS custom property for column count
			$existing_style = $processor->get_attribute( 'style' ) ?? '';
			$new_style      = trim( $existing_style . ' --masonry-columns: ' . $columns . ';' );
			$processor->set_attribute( 'style', $new_style );

			$gallery_content = $processor->get_updated_html();
		}

		return $gallery_content;
	}

	public function get_css() {
		ob_start();
		?>
		/**
		* Gallery Masonry Display Styles
		* Uses CSS columns for masonry layout (Pinterest-style vertical flow)
		*
		* @package Brandy\BlockSettings\GalleryMasonryDisplay
		*/

		/* ==========================================================================
		Container - Override WordPress gallery flexbox with CSS columns
		========================================================================== */

		.wp-block-gallery.has-masonry-display,
		.wp-block-gallery.has-masonry-display.is-layout-flex,
		.wp-block-gallery.has-masonry-display.is-layout-constrained {
			/* Reset flexbox layout */
			display: block !important;
			flex-wrap: unset !important;
			flex-direction: unset !important;
			align-items: unset !important;
			justify-content: unset !important;

			/* CSS Columns for masonry */
			column-count: var(--masonry-columns, 3);
			column-gap: var(--wp--style--block-gap, 1rem);
			column-fill: balance; /* Don't balance - let columns fill naturally */

			/* Reset other defaults */
			list-style-type: none;
			margin: 0;
			padding: 0;
			width: 100%;
			box-sizing: border-box;
		}

		/* Column count via data attribute (highest specificity) */
		.wp-block-gallery.has-masonry-display[data-masonry-columns="1"] { column-count: 1 !important; }
		.wp-block-gallery.has-masonry-display[data-masonry-columns="2"] { column-count: 2 !important; }
		.wp-block-gallery.has-masonry-display[data-masonry-columns="3"] { column-count: 3 !important; }
		.wp-block-gallery.has-masonry-display[data-masonry-columns="4"] { column-count: 4 !important; }
		.wp-block-gallery.has-masonry-display[data-masonry-columns="5"] { column-count: 5 !important; }
		.wp-block-gallery.has-masonry-display[data-masonry-columns="6"] { column-count: 6 !important; }
		.wp-block-gallery.has-masonry-display[data-masonry-columns="7"] { column-count: 7 !important; }
		.wp-block-gallery.has-masonry-display[data-masonry-columns="8"] { column-count: 8 !important; }

		/* Column count via WordPress columns class (fallback) */
		.wp-block-gallery.has-masonry-display.columns-1 { column-count: 1; }
		.wp-block-gallery.has-masonry-display.columns-2 { column-count: 2; }
		.wp-block-gallery.has-masonry-display.columns-3 { column-count: 3; }
		.wp-block-gallery.has-masonry-display.columns-4 { column-count: 4; }
		.wp-block-gallery.has-masonry-display.columns-5 { column-count: 5; }
		.wp-block-gallery.has-masonry-display.columns-6 { column-count: 6; }
		.wp-block-gallery.has-masonry-display.columns-7 { column-count: 7; }
		.wp-block-gallery.has-masonry-display.columns-8 { column-count: 8; }

		/* ==========================================================================
		Responsive breakpoints
		========================================================================== */

		@media (max-width: 781px) {
			.wp-block-gallery.has-masonry-display:not([data-masonry-columns="1"]) {
				column-count: 2 !important;
			}
		}

		@media (max-width: 480px) {
			.wp-block-gallery.has-masonry-display {
				column-count: 1 !important;
			}
		}

		/* ==========================================================================
		Gallery Items - Both old (.blocks-gallery-item) and new (figure.wp-block-image)
		========================================================================== */

		/* Old gallery structure */
		.wp-block-gallery.has-masonry-display .blocks-gallery-item {
			display: block !important;
			width: 100% !important;
			margin: 0 0 var(--wp--style--block-gap, 1rem) 0 !important;
			padding: 0 !important;

			/* Prevent item from breaking across columns */
			break-inside: avoid !important;
			page-break-inside: avoid !important;
			-webkit-column-break-inside: avoid !important;

			/* Reset flexbox properties */
			flex: unset !important;
			flex-grow: unset !important;
			flex-shrink: unset !important;
			flex-basis: unset !important;

			/* Proper sizing */
			height: auto !important;
			min-height: unset !important;
			max-height: none !important;
			box-sizing: border-box;
		}

		/* New gallery structure (has-nested-images) */
		.wp-block-gallery.has-masonry-display.has-nested-images figure.wp-block-image {
			display: block !important;
			width: 100% !important;
			margin: 0 0 var(--wp--style--block-gap, 1rem) 0 !important;
			padding: 0 !important;

			/* Prevent item from breaking across columns */
			break-inside: avoid !important;
			page-break-inside: avoid !important;
			-webkit-column-break-inside: avoid !important;

			/* Reset flexbox properties */
			flex: unset !important;
			flex-grow: unset !important;
			flex-shrink: unset !important;
			flex-basis: unset !important;

			/* Proper sizing - key for natural aspect ratio */
			height: auto !important;
			min-height: unset !important;
			max-height: none !important;
			aspect-ratio: not-set !important;
			box-sizing: border-box;
		}

		/* ==========================================================================
		Inner containers (figures, links, divs)
		========================================================================== */

		.wp-block-gallery.has-masonry-display .blocks-gallery-item figure {
			display: block !important;
			width: 100% !important;
			height: auto !important;
			margin: 0 !important;
			padding: 0 !important;

			/* Reset flex */
			flex: unset !important;
			flex-direction: unset !important;
			flex-grow: unset !important;
			align-items: unset !important;
			justify-content: unset !important;
		}

		.wp-block-gallery.has-masonry-display.has-nested-images figure.wp-block-image > a,
		.wp-block-gallery.has-masonry-display.has-nested-images figure.wp-block-image > div {
			display: block !important;
			width: 100% !important;
			height: auto !important;
			margin: 0 !important;
			padding: 0 !important;
		}

		/* ==========================================================================
		Images - Natural aspect ratio is key for masonry
		========================================================================== */

		.wp-block-gallery.has-masonry-display .blocks-gallery-item img,
		.wp-block-gallery.has-masonry-display.has-nested-images figure.wp-block-image img {
			display: block !important;
			width: 100% !important;
			height: auto !important;
			max-width: 100% !important;

			/* Remove forced dimensions */
			min-height: unset !important;
			max-height: none !important;
			aspect-ratio: not-set !important;

			/* Cover for any crops, but auto height preserves ratio */
			object-fit: cover;
			box-sizing: border-box;
		}

		/* ==========================================================================
		Captions
		========================================================================== */

		.wp-block-gallery.has-masonry-display figcaption,
		.wp-block-gallery.has-masonry-display .blocks-gallery-item__caption {
			position: relative !important;
			margin-top: 0.5rem;
			font-size: 0.875rem;
			text-align: center;

			/* Reset absolute positioning if WordPress applies it */
			bottom: unset !important;
			left: unset !important;
			right: unset !important;
		}

		/* ==========================================================================
		Editor-specific adjustments
		========================================================================== */

		.block-editor-block-list__block .wp-block-gallery.has-masonry-display,
		.editor-styles-wrapper .wp-block-gallery.has-masonry-display {
			display: block !important;
			column-fill: balance;
		}

		.block-editor-block-list__block .wp-block-gallery.has-masonry-display figure.wp-block-image,
		.editor-styles-wrapper .wp-block-gallery.has-masonry-display figure.wp-block-image {
			display: block !important;
			width: 100% !important;
			height: auto !important;
			break-inside: avoid !important;
		}

		<?php 
		return ob_get_clean();
	}
}

Caller::get_instance();
