/**
 * FoodOrd Product Modal JavaScript
 *
 * @package FoodOrd
 * @since 1.0
 */

(function ($) {
	'use strict';

	const parseToggleValue = function (value) {
		if (value === true || value === 'yes' || value === 'true' || value === 1 || value === '1') {
			return true;
		}

		if (value === false || value === 'no' || value === 'false' || value === 0 || value === '0') {
			return false;
		}

		return Boolean(value);
	};

	const areUpsellsEnabled = function () {
		if (typeof window.foodord_modal_vars === 'undefined' || !Object.prototype.hasOwnProperty.call(window.foodord_modal_vars, 'modal_upsells_enabled')) {
			return true;
		}

		return parseToggleValue(window.foodord_modal_vars.modal_upsells_enabled);
	};

	const showUnavailableProductToast = function (source) {
		if (window.FoodordStoreStatusToast && typeof window.FoodordStoreStatusToast.showUnavailableProduct === 'function') {
			window.FoodordStoreStatusToast.showUnavailableProduct(source);
		}
	};

	/**
	 * Product Modal Class
	 */
	class FoodOrdProductModal {
		constructor() {
			this.modal = null;
			this.modalOverlay = null;
			this.currentProductId = null;
			this.currentCartItemKey = '';
			this.pendingPrefillOptions = {};
			this.isLoading = false;
			this.lastFocusedElement = null;
			this.footer = null;
			this.thumbnailResizeObserver = null;
			this.closeAnimationTimeout = null;
			this.openFocusTimeout = null;
			this.modalAnimationDuration = 320;

			this.init();
		}

		init() {
			this.createModalHTML();
			this.bindEvents();
			this.initFooter();
		}

		/**
		 * Initialize footer functionality
		 */
		initFooter() {
			// Initialize footer only if the class is available
			if (typeof window.FoodOrdModalFooter !== 'undefined') {
				this.footer = new window.FoodOrdModalFooter(this);
				// Expose footer instance for other scripts to access
				if (this.modal && this.modal.length) {
					this.modal.data('footerInstance', this.footer);
				}
			}
		}

		/**
		 * Create modal HTML structure
		 */
		createModalHTML() {
			const upsellSkeletonHtml = (areUpsellsEnabled() && window.FoodordUpsellSkeleton && typeof window.FoodordUpsellSkeleton.buildRail === 'function')
				? window.FoodordUpsellSkeleton.buildRail({ context: 'modal', count: 3 })
				: '';

			const skeletonRows = `
				<div class="foodord-skeleton__topping-row">
					<div class="foodord-skeleton__line foodord-skeleton foodord-skeleton__label"></div>
					<div class="foodord-skeleton__line foodord-skeleton foodord-skeleton__badge"></div>
				</div>
				<div class="foodord-skeleton__option foodord-skeleton"></div>
				<div class="foodord-skeleton__option foodord-skeleton"></div>
				<div class="foodord-skeleton__option foodord-skeleton"></div>
			`;

			const skeletonBlock = `
				<div class="foodord-skeleton__block">
					${skeletonRows}
				</div>
				<div class="foodord-skeleton__block">
					${skeletonRows}
				</div>
			`;

			const modalHTML = `
				<div id="foodord-product-modal" class="foodord-modal" role="dialog" aria-modal="true" aria-hidden="true">
					<div class="foodord-modal-overlay">
						<div class="foodord-modal-container">
							<div class="foodord-modal-content">
								<span class="foodord-swipe-dismiss__handle" aria-hidden="true"></span>
								<button class="foodord-modal-close" aria-label="Close modal">
									<svg width="24" height="24" viewBox="0 0 24 24" fill="none">
										<path stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M18 6L6 18M6 6l12 12"/>
									</svg>
								</button>
								<div class="foodord-modal-body">
									<div class="foodord-modal-loading">
										<div class="foodord-skeleton-wrapper">
											<div class="foodord-skeleton__image foodord-skeleton"></div>
											<div class="foodord-skeleton__details">
												<div class="foodord-skeleton__title-row">
													<div class="foodord-skeleton__line foodord-skeleton foodord-skeleton__title"></div>
												</div>
												<div class="foodord-skeleton__line foodord-skeleton foodord-skeleton__price"></div>
												<div class="foodord-skeleton__line foodord-skeleton foodord-skeleton__desc-line"></div>
												<div class="foodord-skeleton__line foodord-skeleton foodord-skeleton__desc-line foodord-skeleton__desc-line--short"></div>
												${skeletonBlock}
											</div>
											${upsellSkeletonHtml}
											<div class="foodord-skeleton__footer">
												<div class="foodord-skeleton__qty foodord-skeleton"></div>
												<div class="foodord-skeleton__cta foodord-skeleton"></div>
											</div>
										</div>
									</div>
									<div class="foodord-modal-product-content"></div>
								</div>
							</div>
						</div>
					</div>
				</div>
			`;

			$('body').append(modalHTML);
			this.modal = $('#foodord-product-modal');
			this.modalOverlay = this.modal.find('.foodord-modal-overlay');
		}

		getActiveOrderMode() {
			const mobileToggle = document.querySelector('.foodord-mode-toggle-mobile[data-active-mode]');
			const mobileMode = mobileToggle ? mobileToggle.getAttribute('data-active-mode') : '';
			if (mobileMode === 'pickup' || mobileMode === 'delivery') {
				return mobileMode;
			}

			if (
				window.FoodordDeliveryPickup
				&& (window.FoodordDeliveryPickup.currentMode === 'pickup' || window.FoodordDeliveryPickup.currentMode === 'delivery')
			) {
				return window.FoodordDeliveryPickup.currentMode;
			}

			if (
				window.foodord_location_vars
				&& (window.foodord_location_vars.mode === 'pickup' || window.foodord_location_vars.mode === 'delivery')
			) {
				return window.foodord_location_vars.mode;
			}

			if (document.querySelector('.wr-card.is-pickup')) {
				return 'pickup';
			}

			return 'delivery';
		}

		isStoreOpenForMode(mode) {
			const normalized = mode === 'pickup' ? 'pickup' : 'delivery';
			const status = window.FoodordStoreStatus || null;

			if (status && status.modes && typeof status.modes === 'object') {
				const data = status.modes[normalized];
				if (data) {
					if (data.manual_locked || data.locked || data.custom_closed) {
						return false;
					}
					if (data.is_open) {
						return true;
					}
					if (data.preorder_enabled && data.preorder_open) {
						return true;
					}
					return false;
				}
			}

			if (status && typeof status.isOpen === 'boolean') {
				return status.isOpen;
			}

			return true;
		}

		blockClosedStoreEvent(event = null) {
			const mode = this.getActiveOrderMode();
			if (this.isStoreOpenForMode(mode)) {
				return false;
			}

			if (event) {
				event.preventDefault();
				event.stopPropagation();
				event.stopImmediatePropagation();
			}

			if (window.FoodordStoreStatusToast && typeof window.FoodordStoreStatusToast.show === 'function') {
				window.FoodordStoreStatusToast.show(mode);
			}

			return true;
		}

		/**
		 * Bind event handlers
		 */
		bindEvents() {
			// Product card click handler - using capture phase to catch event early
			document.addEventListener('click', (e) => {
				const productCard = e.target.closest('.foodord-product-card');

				if (!productCard) {
					return;
				}

				const availabilityFlag = (productCard.getAttribute('data-foodord-available') || '').toLowerCase();
				if (
					productCard.classList.contains('foodord-product-card--unavailable')
					|| availabilityFlag === '0'
					|| availabilityFlag === 'false'
					|| availabilityFlag === 'no'
				) {
					e.preventDefault();
					e.stopPropagation();
					e.stopImmediatePropagation();
					showUnavailableProductToast(productCard);
					return;
				}

				if (e.target.closest('[data-allergy-trigger="true"]')) {
					return;
				}

				if (e.target.closest('.foodord-pro-bogo-badge') || e.target.closest('.foodord-pro-price__badge')) {
					return;
				}

				if (e.target.closest('.foodord-pro-bogo-badge')) {
					return;
				}

				const reservationPreorder = !!productCard.closest('[data-foodord-reservation-preorder-products]');
				if (!reservationPreorder && this.blockClosedStoreEvent(e)) {
					return;
				}

				if (productCard.dataset && productCard.dataset.foodordDirectAdd === '1') {
					return;
				}

				if (e.target.closest('[data-foodord-direct-add="1"]')) {
					return;
				}

				// Check if click is on add to cart button or its children
				if (e.target.closest('.product-actions')) {
					// Prevent default add to cart behavior and open modal instead
					e.preventDefault();
					e.stopPropagation();
					e.stopImmediatePropagation();
				}

				// Check if click is on a link inside the card (other than add to cart)
				if (e.target.tagName === 'A' || e.target.closest('a:not(.add_to_cart_button)')) {
					e.preventDefault();
					e.stopPropagation();
					e.stopImmediatePropagation();
				}

				// Always prevent default on the card itself
				e.preventDefault();
				e.stopPropagation();
				e.stopImmediatePropagation();

				const productId = productCard.getAttribute('data-product-id');

				if (productId) {
					// Store the element that triggered modal opening
					this.lastFocusedElement = productCard;
					this.openModal(parseInt(productId, 10), {
						trigger: productCard,
						context: reservationPreorder ? 'reservation_preorder' : ''
					});
				} else {
					console.error('No product ID found on clicked element');
				}
			}, true); // Use capture phase

			// Close modal handlers
			this.modal.on('click', '.foodord-modal-close', (e) => {
				e.preventDefault();
				this.closeModal();
			});

			this.modal.on('click', '[data-foodord-modal-upsell-trigger="true"]', (e) => {
				e.preventDefault();

				const productId = parseInt($(e.currentTarget).attr('data-product-id'), 10);

				if (!productId || productId === this.currentProductId) {
					return;
				}

				this.openModal(productId);
			});

			document.addEventListener('click', (e) => {
				const trigger = e.target.closest('[data-foodord-upsell-direct-add="1"]');

				if (!trigger) {
					return;
				}

				e.preventDefault();
				e.stopPropagation();

				const productId = parseInt(trigger.getAttribute('data-product-id'), 10) || 0;

				if (!productId) {
					return;
				}

				this.directAddUpsellProduct(productId, trigger);
			});

			this.modal.on('click', '[data-foodord-upsells-scroll]', (e) => {
				e.preventDefault();

				const button = e.currentTarget;
				const direction = button.getAttribute('data-foodord-upsells-scroll');
				const section = button.closest('.foodord-modal-upsells');
				const rail = section ? section.querySelector('.foodord-modal-upsells__grid') : null;

				if (!rail) {
					return;
				}

				const firstCard = rail.querySelector('.foodord-modal-upsells__item');
				const cardRect = firstCard ? firstCard.getBoundingClientRect() : null;
				const railStyle = window.getComputedStyle(rail);
				const gap = parseFloat(railStyle.gap || railStyle.columnGap || '12') || 12;
				const scrollAmount = cardRect ? Math.round(cardRect.width + gap) : Math.round(rail.clientWidth * 0.8);

				rail.scrollBy({
					left: direction === 'prev' ? -scrollAmount : scrollAmount,
					behavior: 'smooth'
				});
			});

			this.modal.on('click', '[data-foodord-thumbnail-scroll]', (e) => {
				e.preventDefault();

				const button = e.currentTarget;
				const direction = button.getAttribute('data-foodord-thumbnail-scroll');
				const shell = button.closest('[data-foodord-thumbnails-shell]');
				const rail = shell ? shell.querySelector('[data-foodord-thumbnails-track]') : null;

				if (!rail) {
					return;
				}

				const firstThumbnail = rail.querySelector('.foodord-product-thumbnail');
				const thumbnailRect = firstThumbnail ? firstThumbnail.getBoundingClientRect() : null;
				const railStyle = window.getComputedStyle(rail);
				const gap = parseFloat(railStyle.gap || railStyle.columnGap || '12') || 12;
				const scrollAmount = thumbnailRect ? Math.round(thumbnailRect.width + gap) : Math.round(rail.clientWidth * 0.75);

				rail.scrollBy({
					left: direction === 'prev' ? -scrollAmount : scrollAmount,
					behavior: 'smooth'
				});
			});

			this.modalOverlay.on('click', (e) => {
				// Only close if clicking directly on the overlay, not on child elements
				if (e.target === e.currentTarget) {
					this.closeModal();
				}
			});

			// Keyboard handling
			$(document).on('keydown', (e) => {
				if (e.keyCode === 27 && this.isModalOpen()) {
					this.closeModal();
				}
			});

			// Focus trap
			this.modal.on('keydown', (e) => {
				if (e.keyCode === 9) {
					this.handleTabKey(e);
				}
			});
		}

		getUpsellAddingLabel() {
			if (
				typeof window.foodordModalFooterI18n === 'object' &&
				window.foodordModalFooterI18n !== null &&
				typeof window.foodordModalFooterI18n.adding === 'string' &&
				window.foodordModalFooterI18n.adding
			) {
				return window.foodordModalFooterI18n.adding;
			}

			return 'Adding…';
		}

		buildUpsellLoadingHtml() {
			const statusLabel = $('<div></div>').text(this.getUpsellAddingLabel()).html();
			return '<span class="foodord-add-to-cart-spinner" aria-hidden="true"></span><span class="screen-reader-text">' + statusLabel + '</span>';
		}

		getUpsellAddedLabel() {
			if (
				typeof window.foodord_modal_vars === 'object' &&
				window.foodord_modal_vars !== null &&
				typeof window.foodord_modal_vars.i18n === 'object' &&
				window.foodord_modal_vars.i18n !== null &&
				typeof window.foodord_modal_vars.i18n.added_to_cart === 'string' &&
				window.foodord_modal_vars.i18n.added_to_cart
			) {
				return window.foodord_modal_vars.i18n.added_to_cart;
			}

			return 'Added to cart';
		}

		setUpsellButtonLoadingState(button, isLoading) {
			const $button = $(button);

			if (!$button.length) {
				return;
			}

			if (isLoading) {
				if (!$button.data('foodordOriginalHtml')) {
					$button.data('foodordOriginalHtml', $button.html());
				}

				$button
					.prop('disabled', true)
					.attr('aria-busy', 'true')
					.addClass('is-loading')
					.html(this.buildUpsellLoadingHtml());

				return;
			}

			const originalHtml = $button.data('foodordOriginalHtml');

			$button
				.prop('disabled', false)
				.removeAttr('aria-busy')
				.removeClass('is-loading');

			if (typeof originalHtml === 'string' && originalHtml.length) {
				$button.html(originalHtml);
			}
		}

		setUpsellButtonAddedState(button) {
			const $button = $(button);

			if (!$button.length) {
				return;
			}

			const existingTimer = $button.data('foodordUpsellAddedTimer');
			if (existingTimer) {
				window.clearTimeout(existingTimer);
			}

			if (!$button.data('foodordOriginalAriaLabel')) {
				$button.data('foodordOriginalAriaLabel', $button.attr('aria-label') || '');
			}

			$button
				.prop('disabled', true)
				.attr('aria-label', this.getUpsellAddedLabel())
				.addClass('is-added');

			const timer = window.setTimeout(() => {
				const originalAriaLabel = $button.data('foodordOriginalAriaLabel');

				$button
					.prop('disabled', false)
					.removeClass('is-added')
					.removeData('foodordUpsellAddedTimer');

				if (typeof originalAriaLabel === 'string' && originalAriaLabel.length) {
					$button.attr('aria-label', originalAriaLabel);
				} else {
					$button.removeAttr('aria-label');
				}
			}, 2000);

			$button.data('foodordUpsellAddedTimer', timer);
		}

		refreshFoodordCartState() {
			if (typeof foodord_modal_vars === 'undefined') {
				return null;
			}

			if (typeof window.FoodordCard !== 'undefined' && typeof window.FoodordCard.showUpsellSkeleton === 'function') {
				window.FoodordCard.showUpsellSkeleton(true);
			}

			if (typeof window.FoodordMobileCart !== 'undefined' && typeof window.FoodordMobileCart.showUpsellSkeleton === 'function') {
				window.FoodordMobileCart.showUpsellSkeleton(true);
			}

			return $.post(foodord_modal_vars.ajax_url, {
				action: 'foodord_get_cart_items',
				nonce: foodord_modal_vars.nonce
			}).done((response) => {
				if (!response || !response.success || !response.data) {
					return;
				}

				if (typeof window.FoodordCard !== 'undefined' && typeof window.FoodordCard.applyCartResponse === 'function') {
					window.FoodordCard.applyCartResponse(response.data);
				}

				document.dispatchEvent(new CustomEvent('foodord_cart_updated', {
					detail: response.data
				}));
			});
		}

		directAddUpsellProduct(productId, button) {
			if (!productId || typeof foodord_modal_vars === 'undefined') {
				return;
			}

			const $button = $(button);

			if ($button.hasClass('is-loading')) {
				return;
			}

			this.setUpsellButtonLoadingState(button, true);

			$.post(foodord_modal_vars.ajax_url, {
				action: 'foodord_add_to_cart',
				product_id: productId,
				quantity: 1,
				nonce: foodord_modal_vars.nonce
			}, (response) => {
				if (!response || response.success === false || response.error) {
					this.setUpsellButtonLoadingState(button, false);
					return;
				}

				if (response.fragments) {
					$.each(response.fragments, function (key, value) {
						$(key).replaceWith(value);
					});
				}

				if (response.cart_hash) {
					$(document.body).trigger('wc_fragment_refresh');
				}

				const refreshRequest = this.refreshFoodordCartState();

				if (refreshRequest && typeof refreshRequest.always === 'function') {
					refreshRequest.always(() => {
						this.setUpsellButtonLoadingState(button, false);
						this.setUpsellButtonAddedState(button);
					});
					return;
				}

				this.setUpsellButtonLoadingState(button, false);
				this.setUpsellButtonAddedState(button);
			}).fail(() => {
				this.setUpsellButtonLoadingState(button, false);
			});
		}

		/**
		 * Open product modal
		 * @param {number} productId - WooCommerce product ID
		 */
		openModal(productId, options = {}) {
			if (this.isLoading || !productId) {
				return;
			}

			const normalizedOptions = options && typeof options === 'object' ? { ...options } : {};
			if (!normalizedOptions.cartItemKey && normalizedOptions.context !== 'reservation_preorder' && this.blockClosedStoreEvent()) {
				return;
			}

			this.currentProductId = productId;
			this.currentCartItemKey = normalizedOptions.cartItemKey ? String(normalizedOptions.cartItemKey) : '';
			this.pendingPrefillOptions = normalizedOptions;
			this.isLoading = true;
			if (normalizedOptions.trigger) {
				this.lastFocusedElement = normalizedOptions.trigger;
			}

			// Show modal and loading state
			this.showModal();
			this.showLoading();

			// Check if required variables exist
			if (typeof foodord_modal_vars === 'undefined') {
				console.error('foodord_modal_vars is not defined');
				this.showError('Modal configuration error');
				return;
			}

			// Fetch product data via AJAX
			$.ajax({
				url: foodord_modal_vars.ajax_url,
				type: 'POST',
				data: {
					action: 'foodord_get_product_modal',
					product_id: productId,
					nonce: foodord_modal_vars.nonce,
					cart_item_key: this.currentCartItemKey || '',
					context: normalizedOptions.context || ''
				},
				success: (response) => {
					this.isLoading = false;
					if (response.success && response.data) {
						let htmlContent = response.data;
						let prefillData = null;
						if (response.data && typeof response.data === 'object' && Object.prototype.hasOwnProperty.call(response.data, 'html')) {
							htmlContent = response.data.html;
							prefillData = response.data.prefill || null;
						}
						if (!prefillData && this.currentCartItemKey) {
							prefillData = { cart_item_key: this.currentCartItemKey };
							if (this.pendingPrefillOptions) {
								if (this.pendingPrefillOptions.quantity) {
									prefillData.quantity = this.pendingPrefillOptions.quantity;
								}
								if (this.pendingPrefillOptions.variationId) {
									prefillData.variation_id = this.pendingPrefillOptions.variationId;
								}
								if (this.pendingPrefillOptions.toppingsSignature) {
									prefillData.toppings_signature = this.pendingPrefillOptions.toppingsSignature;
								}
							}
						}
						this.showProductContent(htmlContent, prefillData);
						this.pendingPrefillOptions = {};
					} else {
						console.error('AJAX error:', response);
						this.pendingPrefillOptions = {};
						this.showError(response.data || 'Failed to load product data');
					}
				},
				error: (jqXHR, textStatus, errorThrown) => {
					console.error('AJAX network error:', {
						jqXHR: jqXHR,
						textStatus: textStatus,
						errorThrown: errorThrown,
						responseText: jqXHR.responseText,
						status: jqXHR.status
					});

					// Try to parse error message
					let errorMessage = 'Network error: ' + textStatus;
					if (jqXHR.responseText) {
						try {
							const response = JSON.parse(jqXHR.responseText);
							if (response.data) {
								errorMessage = response.data;
							}
						} catch ( /* eslint-disable-line no-unused-vars */ _ignored) {
							// If response can't be parsed, use default error message
						}
					}

					this.isLoading = false;
					this.pendingPrefillOptions = {};
					this.showError(errorMessage);
				}
			});
		}

		/**
		 * Show modal
		 */
		showModal() {
			if (this.closeAnimationTimeout) {
				clearTimeout(this.closeAnimationTimeout);
				this.closeAnimationTimeout = null;
			}

			if (this.openFocusTimeout) {
				clearTimeout(this.openFocusTimeout);
				this.openFocusTimeout = null;
			}

			// Set dynamic viewport height for mobile devices
			this.setViewportHeight();

			// Keep aria state in sync with visibility for accessibility and CSS visibility rules
			this.modal
				.stop(true, true)
				.removeClass('hidden is-closing')
				.addClass('visible')
				.attr('aria-hidden', 'true')
				.show();

			window.requestAnimationFrame(() => {
				this.modal
					.addClass('is-open')
					.attr('aria-hidden', 'false');
			});

			this.openFocusTimeout = setTimeout(() => {
				this.modal.find('.foodord-modal-close').focus();
				this.openFocusTimeout = null;
			}, this.modalAnimationDuration);

			$('body').addClass('foodord-modal-open');

			// Update viewport height on resize and orientation change
			const updateVhHandler = () => this.setViewportHeight();
			$(window).on('resize.foodordModal orientationchange.foodordModal', updateVhHandler);
		}

		/**
		 * Close modal
		 */
		closeModal() {
			if (!this.modal || !this.modal.length || !this.modal.is(':visible') || this.modal.hasClass('is-closing')) {
				return;
			}

			if (this.openFocusTimeout) {
				clearTimeout(this.openFocusTimeout);
				this.openFocusTimeout = null;
			}

			// Remove viewport height event listeners
			$(window).off('resize.foodordModal orientationchange.foodordModal');
			this.destroyThumbnailScroller();

			// Move focus back to the element that opened the modal BEFORE closing
			if (this.lastFocusedElement) {
				// Add tabindex if element doesn't have one to make it focusable
				if (!this.lastFocusedElement.hasAttribute('tabindex')) {
					this.lastFocusedElement.setAttribute('tabindex', '-1');
				}
				this.lastFocusedElement.focus();
			} else {
				// Fallback: focus on body
				document.body.setAttribute('tabindex', '-1');
				document.body.focus();
			}

			this.currentCartItemKey = '';
			this.pendingPrefillOptions = {};
			this.currentProductId = null;
			this.isLoading = false;
			this.lastFocusedElement = null;

			this.modal
				.removeClass('is-open')
				.addClass('is-closing')
				.attr('aria-hidden', 'true');

			const finishClose = () => {
				this.modal
					.hide()
					.removeClass('visible is-closing');
				this.modal.find('.foodord-modal-product-content').empty();

				// Reset footer state
				if (this.footer) {
					this.footer.resetFooterState();
				}

				$('body').removeClass('foodord-modal-open');
				this.closeAnimationTimeout = null;
			};

			if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
				finishClose();
				return;
			}

			this.closeAnimationTimeout = setTimeout(finishClose, this.modalAnimationDuration);
		}

		/**
		 * Show loading state
		 */
		showLoading() {
			this.modal.find('.foodord-modal-loading').removeClass('hidden').addClass('visible');
			this.modal.find('.foodord-modal-product-content').removeClass('visible').addClass('hidden');
		}

		/**
		 * Show product content
		 * @param {string} content - HTML content
		 */
		showProductContent(content, prefillData = null) {
			this.destroyThumbnailScroller();
			this.modal.find('.foodord-modal-loading').removeClass('visible').addClass('hidden');
			this.modal.find('.foodord-modal-product-content').html(content).removeClass('hidden').addClass('visible');
			this.modal.find('.foodord-modal-body').scrollTop(0);
			if (typeof window.foodordLazyLoadScan === 'function') {
				window.foodordLazyLoadScan(this.modal[0] || document);
			}
			if (window.FoodordUpsellSkeleton && typeof window.FoodordUpsellSkeleton.hydrateScope === 'function') {
				window.FoodordUpsellSkeleton.hydrateScope(this.modal[0] || document);
			}

			this.initModalContent(prefillData);
		}

		initMainImageLoading() {
			const $imageWrap = this.modal.find('.foodord-product-main-image');
			const $mainImage = this.modal.find('#foodord-main-image');

			if (!$imageWrap.length || !$mainImage.length) {
				return;
			}

			const imageElement = $mainImage.get(0);
			const clearLoadingState = () => {
				$imageWrap.removeClass('foodord-product-main-image--loading');
			};

			$mainImage.off('.foodordMainImageLoading');
			$imageWrap.addClass('foodord-product-main-image--loading');

			if (imageElement && imageElement.complete) {
				clearLoadingState();
				return;
			}

			$mainImage.on('load.foodordMainImageLoading error.foodordMainImageLoading', clearLoadingState);
		}

		/**
		 * Show error message
		 * @param {string} message - Error message
		 */
		showError(message) {
			this.modal.find('.foodord-modal-loading').removeClass('visible').addClass('hidden');
			this.modal.find('.foodord-modal-product-content').html(
				`<div class="foodord-modal-error">
				<p>Error: ${message}</p>
				<button type="button" class="button foodord-error-close">Close</button>
			</div>`
			).removeClass('hidden').addClass('visible');

			// Bind close button event
			this.modal.find('.foodord-error-close').on('click', () => {
				this.closeModal();
			});
		}

		/**
		 * Set dynamic viewport height for mobile devices
		 * This fixes the issue with mobile browser address bars
		 */
		setViewportHeight() {
			const vh = window.innerHeight * 0.01;
			document.documentElement.style.setProperty('--foodord-vh', `${vh}px`);
		}

		/**
		 * Check if modal is open
		 * @returns {boolean}
		 */
		isModalOpen() {
			return this.modal.is(':visible');
		}

		/**
		 * Handle tab key for focus trap
		 * @param {Event} e - Keyboard event
		 */
		handleTabKey(e) {
			const focusableElements = this.modal.find(
				'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
			).filter(':visible');

			const firstElement = focusableElements.first();
			const lastElement = focusableElements.last();

			if (e.shiftKey) {
				if (document.activeElement === firstElement[0]) {
					e.preventDefault();
					lastElement.focus();
				}
			} else {
				if (document.activeElement === lastElement[0]) {
					e.preventDefault();
					firstElement.focus();
				}
			}
		}

		/**
		 * Initialize modal content interactions
		 */
		initModalContent(prefillData = null) {
			// Initialize footer controls
			if (this.footer) {
				this.footer.initFooterControls();
			}

			// Initialize sticky header
			this.initStickyHeader();

			// Initialize upsell scroller controls
			this.initUpsellScroller();

			// Initialize thumbnail scroller controls
			this.initThumbnailScroller();

			// Hook variation price into footer CTA when variation selected
			const $variationFormsHook = this.modal.find('.variations_form');
			if ($variationFormsHook.length) {
				$variationFormsHook.each((_i, form) => {
					const $form = $(form);
					$form.off('found_variation.wrModal reset_data.wrModal')
						.on('found_variation.wrModal', (e, variation) => {
							if (variation && typeof variation.display_price !== 'undefined') {
								const price = parseFloat(variation.display_price);
								const $btn = this.modal.find('.foodord-modal-footer .foodord-add-to-cart-btn');
								if ($btn.length && !isNaN(price)) {
									$btn.data('unit-price', price);
									if (this.footer && typeof this.footer.updateAddToCartCta === 'function') {
										this.footer.updateAddToCartCta();
									}
								}
							}
						})
						.on('reset_data.wrModal', () => {
							const $btn = this.modal.find('.foodord-modal-footer .foodord-add-to-cart-btn');
							if ($btn.length) {
								const initial = parseFloat($btn.data('unit-price-initial'));
								$btn.data('unit-price', isNaN(initial) ? 0 : initial);
								if (this.footer && typeof this.footer.updateAddToCartCta === 'function') {
									this.footer.updateAddToCartCta();
								}
							}
						});
				});
			}

			// Handle thumbnail clicks
			this.modal.find('.foodord-product-thumbnail').off('click').on('click', (e) => {
				const $thumbnail = $(e.currentTarget);
				const imageUrl = $thumbnail.data('image-url');
				const imageAlt = $thumbnail.data('image-alt');
				const $mainImage = this.modal.find('#foodord-main-image');
				const $imageWrap = this.modal.find('.foodord-product-main-image');

				if (imageUrl && $mainImage.length && $imageWrap.length) {
					$imageWrap.addClass('foodord-product-main-image--loading');
					$mainImage.off('.foodordMainImageLoading').on('load.foodordMainImageLoading error.foodordMainImageLoading', () => {
						$imageWrap.removeClass('foodord-product-main-image--loading');
					});
					$mainImage.attr('src', imageUrl).attr('alt', imageAlt);

					const mainImageElement = $mainImage.get(0);
					if (mainImageElement && mainImageElement.complete) {
						$imageWrap.removeClass('foodord-product-main-image--loading');
					}

					this.modal.find('.foodord-product-thumbnail').removeClass('active');
					$thumbnail.addClass('active');

					const thumbnailElement = $thumbnail.get(0);
					if (thumbnailElement && typeof thumbnailElement.scrollIntoView === 'function') {
						thumbnailElement.scrollIntoView({ block: 'nearest', inline: 'nearest' });
					}

					const rail = thumbnailElement ? thumbnailElement.closest('[data-foodord-thumbnails-track]') : null;
					if (rail && typeof rail.foodordThumbnailScrollHandler === 'function') {
						window.requestAnimationFrame(rail.foodordThumbnailScrollHandler);
					}
				}
			});

			this.initMainImageLoading();

			// Initialize WooCommerce variation forms injected via AJAX (if any)
			const $variationFormsInit = this.modal.find('.variations_form');
			if ($variationFormsInit.length && typeof $.fn.wc_variation_form === 'function') {
				$variationFormsInit.each(function () {
					const $form = $(this);
					$form.wc_variation_form();
					$form.find('.variations select').trigger('change');
				});
				// Notify WooCommerce scripts that new variation forms exist
				$(document).trigger('wc_variation_form');
			}

			// Initialize radio-select sync for variation attributes
			this.initRadioSelectSync();

			if (window.foodordToppings && typeof window.foodordToppings.initializeCollapsibleGroups === 'function') {
				window.foodordToppings.initializeCollapsibleGroups(this.modal);
			}

			if (window.foodordToppings && typeof window.foodordToppings.updateSelectedStates === 'function') {
				window.foodordToppings.updateSelectedStates();
			}

			if (this.footer && typeof this.footer.setPrefillData === 'function') {
				if (prefillData) {
					setTimeout(() => {
						this.footer.setPrefillData(prefillData);
					}, 0);
				} else {
					this.footer.setPrefillData(null);
				}
			}
		}

		/**
		 * Initialize upsell scroller controls
		 */
		initUpsellScroller() {
			const sections = this.modal.find('.foodord-modal-upsells');

			if (!sections.length) {
				return;
			}

			sections.each((_index, section) => {
				const rail = section.querySelector('.foodord-modal-upsells__grid');
				const nav = section.querySelector('.foodord-modal-upsells__nav');
				const prevButton = section.querySelector('[data-foodord-upsells-scroll="prev"]');
				const nextButton = section.querySelector('[data-foodord-upsells-scroll="next"]');

				if (!rail || !nav || !prevButton || !nextButton) {
					return;
				}

				const updateButtons = () => {
					const cards = Array.from(rail.querySelectorAll('.foodord-modal-upsells__item'));
					const hasOverflow = cards.some((card) => {
						const cardRightEdge = Math.ceil(card.offsetLeft + card.offsetWidth);
						return cardRightEdge > rail.clientWidth + 1;
					});
					const maxScrollLeft = hasOverflow ? Math.max(0, rail.scrollWidth - rail.clientWidth) : 0;
					const currentScrollLeft = Math.ceil(rail.scrollLeft);

					nav.hidden = !hasOverflow;
					prevButton.disabled = !hasOverflow || currentScrollLeft <= 1;
					nextButton.disabled = !hasOverflow || currentScrollLeft >= maxScrollLeft - 1;
				};

				if (rail.foodordUpsellScrollHandler) {
					rail.removeEventListener('scroll', rail.foodordUpsellScrollHandler);
				}

				rail.foodordUpsellScrollHandler = updateButtons;
				rail.addEventListener('scroll', updateButtons, { passive: true });

				window.requestAnimationFrame(() => {
					updateButtons();
					window.requestAnimationFrame(updateButtons);
				});
			});
		}

		/**
		 * Remove thumbnail scroller observers.
		 */
		destroyThumbnailScroller() {
			if (this.thumbnailResizeObserver) {
				this.thumbnailResizeObserver.disconnect();
				this.thumbnailResizeObserver = null;
			}

			if (!this.modal || !this.modal.length) {
				return;
			}

			this.modal.find('[data-foodord-thumbnails-track]').each((_index, rail) => {
				if (rail.foodordThumbnailScrollHandler) {
					rail.removeEventListener('scroll', rail.foodordThumbnailScrollHandler);
					delete rail.foodordThumbnailScrollHandler;
				}
			});
		}

		/**
		 * Initialize thumbnail scroller controls and edge fades.
		 */
		initThumbnailScroller() {
			this.destroyThumbnailScroller();

			const shells = this.modal.find('[data-foodord-thumbnails-shell]');

			if (!shells.length) {
				return;
			}

			const updateHandlers = [];
			const resizeObserver = typeof window.ResizeObserver !== 'undefined'
				? new window.ResizeObserver(() => {
					updateHandlers.forEach((updateHandler) => updateHandler());
				})
				: null;

			shells.each((_index, shell) => {
				const rail = shell.querySelector('[data-foodord-thumbnails-track]');
				const prevButton = shell.querySelector('[data-foodord-thumbnail-scroll="prev"]');
				const nextButton = shell.querySelector('[data-foodord-thumbnail-scroll="next"]');

				if (!rail || !prevButton || !nextButton) {
					return;
				}

				const updateState = () => {
					const maxScrollLeft = Math.max(0, rail.scrollWidth - rail.clientWidth);
					const currentScrollLeft = Math.ceil(rail.scrollLeft);
					const hasOverflow = maxScrollLeft > 1;
					const hasOverflowLeft = hasOverflow && currentScrollLeft > 1;
					const hasOverflowRight = hasOverflow && currentScrollLeft < maxScrollLeft - 1;

					shell.classList.toggle('has-overflow-left', hasOverflowLeft);
					shell.classList.toggle('has-overflow-right', hasOverflowRight);
					shell.classList.toggle('has-overflow', hasOverflow);

					prevButton.hidden = !hasOverflowLeft;
					prevButton.disabled = !hasOverflowLeft;
					nextButton.hidden = !hasOverflowRight;
					nextButton.disabled = !hasOverflowRight;
				};

				rail.foodordThumbnailScrollHandler = updateState;
				rail.addEventListener('scroll', updateState, { passive: true });
				updateHandlers.push(updateState);

				if (resizeObserver) {
					resizeObserver.observe(shell);
					resizeObserver.observe(rail);
				}

				window.requestAnimationFrame(() => {
					updateState();
					window.requestAnimationFrame(updateState);
				});
			});

			this.thumbnailResizeObserver = resizeObserver;
		}

		/**
		 * Initialize sticky header functionality
		 */
		initStickyHeader() {
			const $modalBody = this.modal.find('.foodord-modal-body');
			const $productTitle = this.modal.find('.foodord-product-title-row');

			if (!$modalBody.length || !$productTitle.length) {
				return;
			}

			$modalBody.off('scroll.stickyHeader').on('scroll.stickyHeader', () => {
				const titleElement = $productTitle[0];
				if (!titleElement || !titleElement.getBoundingClientRect) {
					return;
				}
				const rect = titleElement.getBoundingClientRect();
				const modalBodyRect = $modalBody[0].getBoundingClientRect();

				// Check if title has reached the top of modal body (sticky position)
				const isSticky = rect.top <= modalBodyRect.top;

				if (isSticky) {
					$productTitle.addClass('sticky-active');
				} else {
					$productTitle.removeClass('sticky-active');
				}
			});
		}

		/**
		 * Initialize radio button <-> select sync for variation attributes
		 */
		initRadioSelectSync() {
			const $modal = this.modal;

			// Handle radio button clicks
			$modal.off('change.foodordRadio', '.foodord-attr-input').on('change.foodordRadio', '.foodord-attr-input', function () {
				const $radio = $(this);
				const targetSelector = $radio.data('target-select');
				const value = $radio.val();

				if (targetSelector) {
					const $select = $modal.find(targetSelector);
					if ($select.length) {
						// Update the select to match radio selection
						$select.val(value).trigger('change');
						// Visual feedback: mark selected radio's label
						$radio.closest('.foodord-attr-options').find('.foodord-attr-option').removeClass('is-selected');
						$radio.closest('.foodord-attr-option').addClass('is-selected');

						// Update header selection status
						if (window.foodordToppings && typeof window.foodordToppings.updateHeaderStatus === 'function') {
							window.foodordToppings.updateHeaderStatus($radio.closest('.foodord-attr-wrapper'));
						}
					}
				}
			});

			// Listen for programmatic select changes (from WooCommerce JS)
			$modal.off('change.foodordSelect', '.variations select').on('change.foodordSelect', '.variations select', function () {
				const $select = $(this);
				const value = $select.val();
				const selectId = $select.attr('id');

				if (selectId) {
					// Find corresponding radio group
					const $radios = $modal.find('.foodord-attr-input[data-target-select="#' + selectId + '"]');
					if ($radios.length) {
						// Uncheck all radios in group
						$radios.prop('checked', false).closest('.foodord-attr-option').removeClass('is-selected');
						if (value) {
							$radios.filter('[value="' + value + '"]').prop('checked', true).closest('.foodord-attr-option').addClass('is-selected');
						}

						// Update header selection status
						if (window.foodordToppings && typeof window.foodordToppings.updateHeaderStatus === 'function') {
							window.foodordToppings.updateHeaderStatus($select.closest('.foodord-attr-wrapper'));
						}
					}
				}
			});

			// Listen for WooCommerce update_variation_values event to disable/enable radio options
			$modal.off('woocommerce_update_variation_values.foodordModal').on('woocommerce_update_variation_values.foodordModal', '.variations_form', function () {
				const $form = $(this);

				// Check each select for available options
				$form.find('.variations select').each(function () {
					const $select = $(this);
					const selectId = $select.attr('id');

					if (selectId) {
						const $radios = $modal.find('.foodord-attr-input[data-target-select="#' + selectId + '"]');
						// Update radio availability based on select options
						$radios.each(function () {
							const $radio = $(this);
							const radioValue = $radio.val();
							const $option = $select.find('option[value="' + radioValue + '"]');
							const isDisabled = $option.is(':disabled');

							$radio.prop('disabled', isDisabled);
							$radio.closest('.foodord-attr-option').toggleClass('is-disabled', isDisabled);
						});
					}
				});
			});

			// Trigger initial sync
			$modal.find('.variations select').trigger('change.foodordSelect');
		}

	}
	// Initialize modal when document is ready
	$(document).ready(() => {
		if (typeof foodord_modal_vars !== 'undefined') {
			const modalInstance = new FoodOrdProductModal();
			window.foodordModal = modalInstance;
		} else {
			console.error('foodord_modal_vars not available - modal will not work');
		}
	});

})(jQuery);
