<?php
/**
 * True Pinterest-style Masonry Layout for Product Display.
 *
 * @package Product_Display.
 */

// Exit if accessed directly.
if ( ! defined('ABSPATH') ) {
	exit;
}

/**
 * Class PRODDISP_Masonry.
 *
 * This class handles the rendering of the true masonry layout for product display.
 */
class PRODDISP_Masonry extends PRODDISP_Layout_Base {
	/**
	 * Render the masonry layout.
	 *
	 * @param array $products WooCommerce product objects.
	 * @return string HTML output.
	 */
	public function render( $products ) {
		// Enqueue masonry-specific assets
		PRODDISP_Assets::get_instance()->enqueue_masonry_style_assets();

		// Handle pro layout modes
		$pro_result = $this->handle_pro_layout_mode('masonry-grid', 'PRODDISP_PRO_Masonry', 'masonry-grid-locked-style-1.gif', $products);
		if ( $pro_result !== false ) {
			return $pro_result;
		}

		$pro_result = $this->handle_pro_layout_mode('masonry-grid-2', 'PRODDISP_PRO_Masonry', 'masonry-grid-locked-style-2.gif', $products);
		if ( $pro_result !== false ) {
			return $pro_result;
		}

		// Generate unique ID for this masonry instance
		$masonry_id = 'wcps-masonry-' . uniqid();

		// Add wrapper div with proper masonry grid classes
		$output = '<div class="wcps-layout-masonry-grid" id="' . esc_attr($masonry_id) . '">';
		$output .= '<div class="wcps-masonry-container">';

		// Essential grid elements for masonry
		$output .= '<div class="wcps-grid-sizer"></div>';
		$output .= '<div class="wcps-gutter-sizer"></div>';

		// Get predefined size patterns for true masonry effect
		$size_patterns = $this->get_size_patterns();

		$pattern_index = 0;
		$total_patterns = count($size_patterns);

		// Loop through products and create varied sized items
		foreach ( $products as $index => $product ) {
			// Cycle through size patterns
			$current_pattern = $size_patterns[ $pattern_index % $total_patterns ];
			$pattern_index++;

			$output .= $this->render_product($product, $index, $current_pattern);
		}

		$output .= '</div>'; // End .wcps-masonry-container
		$output .= '</div>'; // End .wcps-layout-masonry-grid

		// Enqueue required scripts
		PRODDISP_Assets::get_instance()->enqueue_masonry_assets();

		// Add inline initialization script
		$output .= $this->add_masonry_script($masonry_id);

		return $output;
	}

	/**
	 * Get predefined size patterns for true masonry layout.
	 *
	 * @return array Array of size patterns.
	 */
	private function get_size_patterns() {
		// Create several different patterns to ensure visual variety
		return [
			[
				'width' => 1,
				'height' => 1,
			],  // Standard
			[
				'width' => 2,
				'height' => 1,
			],  // Wide
			[
				'width' => 1,
				'height' => 2,
			],  // Tall
			[
				'width' => 1,
				'height' => 1,
			],  // Standard
			[
				'width' => 1,
				'height' => 1.5,
			], // Medium tall
			[
				'width' => 1,
				'height' => 0.8,
			], // Short
			[
				'width' => 2,
				'height' => 2,
			],  // XL
			[
				'width' => 1,
				'height' => 1,
			],  // Standard
			[
				'width' => 1,
				'height' => 1.3,
			], // Slightly tall
			[
				'width' => 1,
				'height' => 1,
			],  // Standard
			[
				'width' => 1.5,
				'height' => 1,
			], // Medium wide
			[
				'width' => 1,
				'height' => 1,
			],  // Standard
		];
	}

	/**
	 * Render a single product in the masonry layout.
	 *
	 * @param Product_Display $product The product object.
	 * @param int             $index Product index.
	 * @param array           $size_pattern Width and height pattern.
	 * @return string HTML for the product.
	 */
	private function render_product( $product, $index, $size_pattern ) {
		// Set width and height classes based on pattern
		$width_class = ( $size_pattern['width'] >= 2 ) ? 'wcps-width-2' :
					  ( ( $size_pattern['width'] > 1 ) ? 'wcps-width-1-5' : '' );

		$height_class = ( $size_pattern['height'] >= 2 ) ? 'wcps-height-2' :
					   ( ( $size_pattern['height'] > 1.3 ) ? 'wcps-height-1-5' :
					   ( ( $size_pattern['height'] < 1 ) ? 'wcps-height-short' : '' ) );

		// Add custom data attributes for masonry calculations
		$data_attrs = 'data-width="' . esc_attr($size_pattern['width']) . '" ';
		$data_attrs .= 'data-height="' . esc_attr($size_pattern['height']) . '"';

		$output = '<div class="wcps-masonry-item ' . esc_attr($width_class) . ' ' . esc_attr($height_class) . '" ' . $data_attrs . ' itemscope itemtype="https://schema.org/Product">';
		$output .= '<div class="wcps-product">';

		// Add structured data
		$output .= '<meta itemprop="name" content="' . esc_attr($product->get_name()) . '">';
		$output .= '<meta itemprop="url" content="' . esc_url(get_permalink($product->get_id())) . '">';
		if ( $product->get_sku() ) {
			$output .= '<meta itemprop="sku" content="' . esc_attr($product->get_sku()) . '">';
		}

		// Product image with aspect ratio controlled by CSS
		$output .= '<div class="wcps-product-image" style="padding-bottom:' . ( ( $size_pattern['height'] / $size_pattern['width'] ) * 75 ) . '%;">';
		$output .= '<a href="' . esc_url(get_permalink($product->get_id())) . '">';

		if ( $product->get_image_id() ) {
			$alt_text = get_post_meta($product->get_image_id(), '_wp_attachment_image_alt', true);
			if ( empty($alt_text) ) {
				$alt_text = $product->get_name();
			}
			$output .= wp_get_attachment_image($product->get_image_id(), $this->settings['image_size'] ?? 'woocommerce_thumbnail', false, array(
				'class' => 'wcps-image',
				'loading' => 'lazy',
				'alt' => esc_attr($alt_text),
			));
		} else {
			$output .= wc_placeholder_img($this->settings['image_size'] ?? 'woocommerce_thumbnail', array(
				'class' => 'wcps-image',
				'alt' => esc_attr($product->get_name() . ' - ' . __('Product Image', 'product-display')),
			));
		}

		$output .= '</a>';

		// Show action buttons on hover
		if ( isset($this->settings['action_position']) && 'hover' === $this->settings['action_position'] ) {
			$output .= $this->render_product_actions($product);
		}

		$output .= '</div>'; // End .wcps-product-image

		// Product content
		$output .= '<div class="wcps-product-content">';

		// Product title
		if ( isset($this->settings['show_title']) && $this->settings['show_title'] === 'yes' ) {
			$output .= '<h2 class="wcps-product-title" itemprop="name"><a href="' . esc_url(get_permalink($product->get_id())) . '">' . esc_html($product->get_name()) . '</a></h2>';
		}

		// Product price
		if ( isset($this->settings['show_price']) && $this->settings['show_price'] === 'yes' ) {
			$output .= '<div class="wcps-product-price" itemprop="offers" itemscope itemtype="https://schema.org/Offer">';
			$output .= '<meta itemprop="price" content="' . esc_attr($product->get_price()) . '">';
			$output .= '<meta itemprop="priceCurrency" content="' . esc_attr(get_woocommerce_currency()) . '">';
			$output .= '<meta itemprop="availability" content="' . ( $product->is_in_stock() ? 'https://schema.org/InStock' : 'https://schema.org/OutOfStock' ) . '">';
			$output .= $product->get_price_html();
			$output .= '</div>';
		}

		// Product rating
		if ( isset($this->settings['show_rating']) && $this->settings['show_rating'] === 'yes' && $product->get_rating_count() > 0 ) {
			$output .= '<div class="wcps-product-rating" itemprop="aggregateRating" itemscope itemtype="https://schema.org/AggregateRating">';
			$output .= '<meta itemprop="ratingValue" content="' . esc_attr($product->get_average_rating()) . '">';
			$output .= '<meta itemprop="reviewCount" content="' . esc_attr($product->get_rating_count()) . '">';
			$output .= '<meta itemprop="bestRating" content="5">';
			$output .= '<meta itemprop="worstRating" content="1">';
			$output .= wc_get_rating_html($product->get_average_rating(), $product->get_rating_count());
			$output .= '</div>';
		}

		// Product description - adjust length based on card size
		if ( isset($this->settings['show_description']) && $this->settings['show_description'] === 'yes' ) {
			$short_description = $product->get_short_description();
			if ( ! empty($short_description) ) {
				$word_count = ( $size_pattern['width'] * $size_pattern['height'] > 1.5 ) ? 20 : 12;
				$output .= '<div class="wcps-product-description" itemprop="description">' . wp_trim_words($short_description, $word_count, '...') . '</div>';
			}
		}

		// Show action buttons if position is below
		if ( isset($this->settings['action_position']) && 'below' === $this->settings['action_position'] ) {
			$output .= $this->render_product_actions($product);
		}

		$output .= '</div>'; // End .wcps-product-content

		$output .= '</div>'; // End .wcps-product
		$output .= '</div>'; // End .wcps-masonry-item

		return $output;
	}

	/**
	 * Add JavaScript for initializing the true masonry layout.
	 *
	 * @param string $masonry_id Unique ID for this masonry instance.
	 * @return string Inline JavaScript.
	 */
	private function add_masonry_script( $masonry_id ) {
		ob_start();
		?>
		<script type="text/javascript">
			jQuery(document).ready(function($) {
				var $container = $('#<?php echo esc_js($masonry_id); ?> .wcps-masonry-container');
				
				// Get grid sizer width
				function getGridSizerWidth() {
					// Calculate base column width (25% for desktop, adjust for other screens)
					var containerWidth = $container.width();
					var columnCount = 4; // Default column count
					
					// Responsive column count
					if (containerWidth <= 480) {
						columnCount = 1;  // Mobile
					} else if (containerWidth <= 768) {
						columnCount = 2;  // Tablet portrait
					} else if (containerWidth <= 1024) {
						columnCount = 3;  // Tablet landscape
					}
					
					return 100 / columnCount;
				}
				
				// Calculate optimal gutter size based on container width
				function getGutterSize() {
					var containerWidth = $container.width();
					return Math.max(10, Math.min(20, Math.floor(containerWidth * 0.02))); // Min 10px, max 20px
				}
				
				// Initialize masonry with imagesLoaded
				$container.imagesLoaded(function() {
					// Initialize Masonry with percentPosition for better responsiveness
					var msnry = $container.masonry({
						itemSelector: '.wcps-masonry-item',
						columnWidth: '.wcps-grid-sizer',
						gutter: getGutterSize(),
						percentPosition: true,
						transitionDuration: '0.4s',
						initLayout: false, // We'll layout after setting item sizes
						// Use element sizing for better control over item dimensions
						horizontalOrder: false, // Important for true masonry effect
						fitWidth: true // Centers the grid if container is wider
					});
					
					// Set item sizes based on data attributes
					$('.wcps-masonry-item', $container).each(function() {
						var $item = $(this);
						var width = parseFloat($item.attr('data-width')) || 1;
						var colWidth = getGridSizerWidth(); 
						
						// Set percentage width for responsive behavior
						if (width === 2) {
							$item.css('width', (colWidth * 2) + '%');
						} else if (width === 1.5) {
							$item.css('width', (colWidth * 1.5) + '%');
						} else {
							$item.css('width', colWidth + '%');
						}
					});
					
					// Now actually lay out the items
					msnry.masonry('layout');
					
					// Add initialized class for CSS animations
					$container.addClass('wcps-masonry-initialized');
					
					// Final layout adjustment after a short delay
					setTimeout(function() {
						msnry.masonry('layout');
					}, 500);
				});
				
				// Responsive layout updates
				var resizeTimer;
				$(window).on('resize', function() {
					clearTimeout(resizeTimer);
					resizeTimer = setTimeout(function() {
						// Update grid sizer width
						$('.wcps-grid-sizer', $container).css('width', getGridSizerWidth() + '%');
						
						// Update item widths
						$('.wcps-masonry-item', $container).each(function() {
							var $item = $(this);
							var width = parseFloat($item.attr('data-width')) || 1;
							var colWidth = getGridSizerWidth();
							
							if (width === 2) {
								$item.css('width', (colWidth * 2) + '%');
							} else if (width === 1.5) {
								$item.css('width', (colWidth * 1.5) + '%');
							} else {
								$item.css('width', colWidth + '%');
							}
						});
						
						// Update layout
						$container.masonry('layout');
					}, 300);
				});
				
				// Handle hover effects
				$(".wcps-masonry-item").hover(
					function() {
						$(this).addClass("wcps-hover");
					},
					function() {
						$(this).removeClass("wcps-hover");
					}
				);
				
				// Reinitialize after AJAX events or tab changes
				$(document).on('ajaxComplete tab_changed added_to_cart', function() {
					setTimeout(function() {
						$container.masonry('reloadItems').masonry('layout');
					}, 200);
				});
			});
		</script>
		<?php
		return ob_get_clean();
	}
}