/**
 * FoodOrd Products JavaScript
 *
 * @package Foodord
 */

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

		// Card click handler - ready for modal implementation.
		$('.foodord-product-card').on(
			'click',
			function (e) {
				const availabilityFlag = (String($(this).attr('data-foodord-available') || '')).toLowerCase();
				if (
					$(this).hasClass('foodord-product-card--unavailable')
					|| availabilityFlag === '0'
					|| availabilityFlag === 'false'
					|| availabilityFlag === 'no'
				) {
					e.preventDefault();
					e.stopPropagation();
					e.stopImmediatePropagation();
					showUnavailableProductToast(this);
					return;
				}

				if ($(e.target).closest('.add_to_cart_button, .foodord-allergy-trigger').length) {
					return;
				}

				const productUrl = $(this).data('product-url');
				if (productUrl) {
					window.location.href = productUrl;
				}
			}
		);

		function adjustDescriptionForMobile() {
			if (window.innerWidth <= 480) {
				$('.foodord-product-card .product-description p').each(
					function () {
						const $p = $(this);
						const originalText = $p.data('original-text') || $p.text();

						if (!$p.data('original-text')) {
							$p.data('original-text', originalText);
						}

						const words = originalText.trim().split(/\s+/);
						if (words.length > 6) {
							const firstLine = words.slice(0, 6).join(' ');
							const remainingWords = words.slice(6).join(' ');
							$p.html(firstLine + '<br>' + remainingWords);
						} else {
							$p.html(originalText);
						}
					}
				);
			} else {
				$('.foodord-product-card .product-description p').each(
					function () {
						const $p = $(this);
						const originalText = $p.data('original-text');
						if (originalText) {
							const words = originalText.trim().split(/\s+/);
							if (words.length > 7) {
								const firstLine = words.slice(0, 7).join(' ');
								const remainingWords = words.slice(7).join(' ');
								$p.html(firstLine + '<br>' + remainingWords);
							} else {
								$p.html(originalText);
							}
						}
					}
				);
			}
		}

		adjustDescriptionForMobile();

		const clearProductCardSkeleton = function (card) {
			if (!card || !card.classList.contains('foodord-product-card--loading')) {
				return;
			}

			const startedAt = Number(card.dataset.foodordCardSkeletonStartedAt || 0);
			const elapsed = startedAt > 0 ? Date.now() - startedAt : 0;
			const minimumDuration = 280;

			if (elapsed < minimumDuration) {
				window.setTimeout(function () {
					clearProductCardSkeleton(card);
				}, minimumDuration - elapsed);
				return;
			}

			card.classList.remove('foodord-product-card--loading');
			card.classList.add('foodord-product-card--loaded');
		};

		const hydrateProductCardSkeleton = function (card) {
			if (!card || card.dataset.foodordCardSkeletonReady === '1') {
				return;
			}

			card.dataset.foodordCardSkeletonReady = '1';
			card.dataset.foodordCardSkeletonStartedAt = String(Date.now());

			const images = Array.from(card.querySelectorAll('.product-image'));
			if (!images.length) {
				window.requestAnimationFrame(function () {
					clearProductCardSkeleton(card);
				});
				return;
			}

			let pendingImages = 0;
			let isFinished = false;

			const finish = function () {
				if (isFinished) {
					return;
				}

				isFinished = true;
				clearProductCardSkeleton(card);
			};

			const handleImageComplete = function () {
				pendingImages -= 1;
				if (pendingImages <= 0) {
					finish();
				}
			};

				images.forEach(function (image) {
					if (!image) {
						return;
					}

					if (image.complete) {
						// Already settled (loaded or failed), do not wait for events.
						return;
					}

					pendingImages += 1;
					image.addEventListener('load', handleImageComplete, { once: true });
					image.addEventListener('error', handleImageComplete, { once: true });
				});

				if (pendingImages === 0) {
					window.requestAnimationFrame(function () {
						finish();
					});
				}
			};

		const initProductCardSkeletons = function (scope) {
			const root = scope && scope.querySelectorAll ? scope : document;
			const cards = root.querySelectorAll('.foodord-product-card--loading');

			if (!cards.length) {
				return;
			}

			cards.forEach(function (card) {
				hydrateProductCardSkeleton(card);
			});
		};

		initProductCardSkeletons(document);

		const LABEL_ROW_MATCHED_CLASS = 'foodord-product-card--label-row-matched';
		const LABEL_CARD_CLASS = 'foodord-product-card--has-labels';
		const LABEL_ROW_MANAGED_KEY = 'foodordLabelRowManaged';

		const getVisibleProductCards = function (container) {
			return Array.from(container.children).filter(function (element) {
				if (!element.classList || !element.classList.contains('foodord-product-card')) {
					return false;
				}

				if (element.hidden || element.classList.contains('foodord-product-card--listing-hidden')) {
					return false;
				}

				const rect = element.getBoundingClientRect();
				return rect.width > 0 && rect.height > 0;
			});
		};

		const resetLabelRowCards = function (cards) {
			cards.forEach(function (card) {
				if (card.dataset[LABEL_ROW_MANAGED_KEY] !== '1') {
					return;
				}

				card.classList.remove(LABEL_ROW_MATCHED_CLASS);
				delete card.dataset[LABEL_ROW_MANAGED_KEY];
			});
		};

		const groupCardsByVisualRow = function (cards) {
			return cards.reduce(function (rows, card) {
				const rect = card.getBoundingClientRect();
				const top = Math.round(rect.top);
				const row = rows.find(function (existingRow) {
					return Math.abs(existingRow.top - top) <= 2;
				});

				if (row) {
					row.cards.push(card);
				} else {
					rows.push({
						top,
						cards: [card],
					});
				}

				return rows;
			}, []);
		};

		const syncProductLabelRowHeights = function (scope) {
			const root = scope && scope.querySelectorAll ? scope : document;
			const containers = root.classList && root.classList.contains('foodord-category-products')
				? [root]
				: Array.from(root.querySelectorAll('.foodord-category-products'));

			containers.forEach(function (container) {
				const cards = getVisibleProductCards(container);
				resetLabelRowCards(cards);

				if (cards.length < 2) {
					return;
				}

				groupCardsByVisualRow(cards).forEach(function (row) {
					const hasLabelCard = row.cards.some(function (card) {
						return card.classList.contains(LABEL_CARD_CLASS);
					});

					if (!hasLabelCard || row.cards.length < 2) {
						return;
					}

					row.cards.forEach(function (card) {
						card.classList.add(LABEL_ROW_MATCHED_CLASS);
						card.dataset[LABEL_ROW_MANAGED_KEY] = '1';
					});
				});
			});
		};

		let labelRowSyncTimer = 0;
		const scheduleProductLabelRowHeights = function (scope) {
			window.clearTimeout(labelRowSyncTimer);
			window.requestAnimationFrame(function () {
				labelRowSyncTimer = window.setTimeout(function () {
					syncProductLabelRowHeights(scope || document);
				}, 30);
			});
		};

		scheduleProductLabelRowHeights(document);
		window.addEventListener('resize', function () {
			scheduleProductLabelRowHeights(document);
		}, { passive: true });
		window.addEventListener('load', function () {
			scheduleProductLabelRowHeights(document);
		}, { once: true });

		const initCampaignRails = function () {
			const rails = document.querySelectorAll('[data-foodord-campaigns-rail]');
			if (!rails.length) {
				return;
			}

			const isDesktopViewport = function () {
				return window.innerWidth > 768;
			};

			const openCampaignsModal = function (event) {
				const trigger = document.querySelector('.foodord-banner-campaigns-btn');
				if (!trigger) {
					return;
				}

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

				document.body.setAttribute('data-foodord-modal-skip-focus', '1');
				trigger.click();
			};

			rails.forEach(function (rail) {
				const track = rail.querySelector('[data-foodord-campaigns-track]');
				const prevBtn = rail.querySelector('[data-foodord-campaigns-prev]');
				const nextBtn = rail.querySelector('[data-foodord-campaigns-next]');
				const cards = rail.querySelectorAll('.foodord-products-campaigns__card');

				if (!track || !prevBtn || !nextBtn || rail.dataset.foodordCampaignRailReady === '1') {
					return;
				}

				const updateButtons = function () {
					if (!isDesktopViewport()) {
						prevBtn.classList.add('is-hidden');
						nextBtn.classList.add('is-hidden');
						prevBtn.disabled = true;
						nextBtn.disabled = true;
						return;
					}

					const maxScrollLeft = Math.max(track.scrollWidth - track.clientWidth, 0);
					const canScroll = maxScrollLeft > 6;
					const atStart = track.scrollLeft <= 6;
					const atEnd = track.scrollLeft >= (maxScrollLeft - 6);

					prevBtn.disabled = !canScroll || atStart;
					nextBtn.disabled = !canScroll || atEnd;

					prevBtn.classList.toggle('is-hidden', !canScroll || atStart);
					nextBtn.classList.toggle('is-hidden', !canScroll || atEnd);
				};

				const scrollTrack = function (direction) {
					const distance = Math.max(track.clientWidth * 0.82, 220);
					track.scrollBy({
						left: direction * distance,
						behavior: 'smooth',
					});
				};

				prevBtn.addEventListener('click', function () {
					scrollTrack(-1);
				});

				nextBtn.addEventListener('click', function () {
					scrollTrack(1);
				});

				if (cards.length) {
					const hasCampaignsTrigger = !!document.querySelector('.foodord-banner-campaigns-btn');
					cards.forEach(function (card) {
						card.classList.toggle('is-clickable', hasCampaignsTrigger);
						card.setAttribute('role', hasCampaignsTrigger ? 'button' : 'listitem');

						if (hasCampaignsTrigger) {
							card.setAttribute('tabindex', '0');
							card.setAttribute('aria-haspopup', 'dialog');
							card.setAttribute('aria-label', card.dataset.foodordCampaignCardLabel || 'View active campaigns');
						} else {
							card.removeAttribute('tabindex');
							card.removeAttribute('aria-haspopup');
							card.removeAttribute('aria-label');
						}

						if (!hasCampaignsTrigger) {
							return;
						}

						card.addEventListener('click', openCampaignsModal);
						card.addEventListener('keydown', function (event) {
							if (event.key === 'Enter' || event.key === ' ') {
								openCampaignsModal(event);
							}
						});
					});
				}

				track.addEventListener('scroll', updateButtons, { passive: true });
				window.addEventListener('resize', updateButtons, { passive: true });

				updateButtons();
				rail.dataset.foodordCampaignRailReady = '1';
			});
		};

		initCampaignRails();

		$(window).on(
			'resize',
			function () {
				clearTimeout(window.resizeTimer);
				window.resizeTimer = setTimeout(function () {
					adjustDescriptionForMobile();
				}, 100);
			}
		);

		const CARD_BADGE_CLASS = 'foodord-card-count';
		const CARD_BADGE_VISIBLE_CLASS = 'foodord-card-count--visible';
		const CARD_BADGE_FLASH_CLASS = 'foodord-card-count--flash';
		const CARD_STATUS_BADGE_CLASS = 'foodord-product-card__status-badge';
		const CARD_LISTING_HIDDEN_CLASS = 'foodord-product-card--listing-hidden';
		const CARD_CART_STRIPE_CLASS = 'foodord-product-card__cart-stripe';
		const CARD_CART_STRIPE_ENTER_CLASS = 'foodord-product-card__cart-stripe--entering';
		const CARD_CART_STRIPE_LEAVE_CLASS = 'foodord-product-card__cart-stripe--leaving';
		let countsRefreshTimer = null;
		const COUNTS_REFRESH_DELAY = 0;

		const scheduleProductCountRefresh = function (delay) {
			const timeout = typeof delay === 'number' ? delay : COUNTS_REFRESH_DELAY;
			if (countsRefreshTimer) {
				clearTimeout(countsRefreshTimer);
			}
			if (timeout <= 0) {
				refreshProductCounts();
				return;
			}
			countsRefreshTimer = window.setTimeout(refreshProductCounts, timeout);
		};

		const refreshProductCounts = function () {
			if (typeof window.foodord_modal_vars === 'undefined') {
				return;
			}

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

				const countMap = buildCountMap(response.data.cart_items);
				applyCountsToCards(countMap);
			});
		};

		const updateCategoryVisibility = function () {
			$('.foodord-category-section').each(function () {
				const $section = $(this);
				const visibleCards = $section.find('.foodord-product-card').filter(function () {
					return !$(this).prop('hidden') && !$(this).hasClass(CARD_LISTING_HIDDEN_CLASS);
				}).length;

				$section.prop('hidden', visibleCards === 0);
			});
		};

		const setCardAvailability = function ($card, isAvailable, unavailableLabel, unavailableMessage, isHidden) {
			if (!$card || !$card.length) {
				return;
			}

			const hidden = !!isHidden;
			$card.toggleClass(CARD_LISTING_HIDDEN_CLASS, hidden);
			$card.prop('hidden', hidden);
			if (hidden) {
				updateCategoryVisibility();
				return;
			}

			const addToCartLabel = (window.foodord_products_vars && window.foodord_products_vars.add_to_cart_label) || 'Add to cart';
			const available = !!isAvailable;
			const fallbackLabel = (window.foodord_products_vars && window.foodord_products_vars.not_available_label) || 'Not available';
			const label = !available && typeof unavailableLabel === 'string' && unavailableLabel.length ? unavailableLabel : fallbackLabel;
			const $button = $card.find('.add_to_cart_button').first();
			let $statusBadge = $card.find('.' + CARD_STATUS_BADGE_CLASS).first();

			$card.attr('data-foodord-available', available ? '1' : '0');
			$card.attr('data-foodord-availability-label', available ? '' : label);
			$card.attr('data-foodord-availability-message', available || typeof unavailableMessage !== 'string' ? '' : unavailableMessage);
			$card.attr('aria-disabled', available ? 'false' : 'true');
			$card.toggleClass('foodord-product-card--unavailable', !available);

			if ($button.length) {
				$button.toggleClass('is-disabled', !available);
				$button.toggleClass('foodord-product-card__button--disabled', !available);
				$button.prop('disabled', !available);
				$button.attr('aria-disabled', available ? 'false' : 'true');
				if (available) {
					$button.removeAttr('tabindex');
				} else {
					$button.attr('tabindex', '-1');
				}
				$button.attr('aria-label', available ? addToCartLabel : label);
				$button.empty().append(
					$('<span>', {
						class: 'screen-reader-text',
						text: available ? addToCartLabel : label
					})
				);
			}

			if (!available) {
				if (!$statusBadge.length) {
					$statusBadge = $('<span>', {
						class: CARD_STATUS_BADGE_CLASS,
						'aria-hidden': 'true',
						text: label
					});
					$card.prepend($statusBadge);
				} else {
					$statusBadge.text(label);
				}
			} else if ($statusBadge.length) {
				$statusBadge.remove();
			}
		};

		const refreshProductAvailability = function () {
			if (typeof jQuery === 'undefined' || typeof window.foodord_products_vars === 'undefined') {
				return;
			}

			const productIds = [];

			$('.foodord-product-card[data-product-id]').each(function () {
				const productId = Number($(this).attr('data-product-id'));
				if (productId > 0) {
					productIds.push(productId);
				}
			});

			if (!productIds.length) {
				return;
			}

			$.post(
				window.foodord_products_vars.ajax_url,
				{
					action: 'foodord_get_products_availability',
					nonce: window.foodord_products_vars.nonce,
					product_ids: productIds,
				}
			).done(function (response) {
				if (!response || !response.success || !response.data || !response.data.products) {
					return;
				}

				$('.foodord-product-card[data-product-id]').each(function () {
					const $card = $(this);
					const productId = String($card.attr('data-product-id') || '');
					const productState = response.data.products[productId];

					if (!productState || typeof productState.available === 'undefined') {
						return;
					}

					setCardAvailability($card, !!productState.available, productState.label, productState.message, !!productState.hidden);
				});
				updateCategoryVisibility();
			});
		};

		const buildCountMap = function (items) {
			const totals = {};
			(items || []).forEach(function (item) {
				const productId = Number(item.product_id || item.id);
				const quantity = Number(item.quantity || 0);
				if (!productId || quantity <= 0) {
					return;
				}
				totals[productId] = (totals[productId] || 0) + quantity;
			});
			return totals;
		};

		const applyCountsToCards = function (countMap) {
			$('.foodord-product-card').each(function () {
				const $card = $(this);
				const productId = Number($card.data('product-id'));
				const count = countMap[productId] || 0;
				updateCardCountBadge($card, count);
			});
		};



		const animateCounter = function ($el, newValue) {
			const currentVal = parseInt($el.data('last-val'), 10);
			const oldValue = !isNaN(currentVal) ? currentVal : (parseInt($el.text(), 10) || 0);

			if (oldValue === newValue) return;

			// Clear any existing animation cleanup timers
			const existingTimer = $el.data('animation-timer');
			if (existingTimer) {
				clearTimeout(existingTimer);
			}

			const direction = newValue > oldValue ? 'is-incrementing' : 'is-decrementing';

			// Create animation structure
			const $container = $('<span>', { class: 'foodord-counter-animate ' + direction });
			const $oldNum = $('<span>', { class: 'foodord-counter-number foodord-counter-number--old' }).text(oldValue);
			const $newNum = $('<span>', { class: 'foodord-counter-number foodord-counter-number--new' }).text(newValue);

			$container.append($oldNum).append($newNum);
			$el.data('last-val', newValue).empty().append($container);

			// Trigger animation
			requestAnimationFrame(() => {
				$container.addClass('animate-active');
			});

			// Cleanup after animation
			const timer = setTimeout(() => {
				if ($el.data('last-val') === newValue) {
					$el.text(newValue);
				}
				$el.removeData('animation-timer');
			}, 400);

			$el.data('animation-timer', timer);
		};


		const clearCartStripeAnimation = function ($stripe) {
			if (!$stripe || !$stripe.length) {
				return;
			}

			const timer = $stripe.data('foodordStripeTimer');
			if (timer) {
				window.clearTimeout(timer);
				$stripe.removeData('foodordStripeTimer');
			}

			$stripe.off('animationend.foodordCartStripe');
		};

		const showCardCartStripe = function ($card) {
			let $stripe = $card.find('.' + CARD_CART_STRIPE_CLASS).first();

			if (!$stripe.length) {
				$stripe = $('<span>', {
					class: CARD_CART_STRIPE_CLASS + ' ' + CARD_CART_STRIPE_ENTER_CLASS,
					'aria-hidden': 'true',
				});
				$card.prepend($stripe);

				const clearEnteringState = function () {
					clearCartStripeAnimation($stripe);
					$stripe.removeClass(CARD_CART_STRIPE_ENTER_CLASS);
				};
				const timer = window.setTimeout(clearEnteringState, 420);

				$stripe.data('foodordStripeTimer', timer);
				$stripe.on('animationend.foodordCartStripe', clearEnteringState);

				return $stripe;
			}

			clearCartStripeAnimation($stripe);
			$stripe.removeClass(CARD_CART_STRIPE_LEAVE_CLASS);

			return $stripe;
		};

		const hideCardCartStripe = function ($stripe) {
			if (!$stripe || !$stripe.length) {
				return;
			}

			clearCartStripeAnimation($stripe);
			$stripe.removeClass(CARD_CART_STRIPE_ENTER_CLASS).addClass(CARD_CART_STRIPE_LEAVE_CLASS);

			const removeStripe = function () {
				clearCartStripeAnimation($stripe);
				$stripe.remove();
			};
			const timer = window.setTimeout(removeStripe, 320);

			$stripe.data('foodordStripeTimer', timer);
			$stripe.on('animationend.foodordCartStripe', removeStripe);
		};


		const updateCardCountBadge = function ($card, count) {
			if (!$card || !$card.length) {
				return;
			}

			let $badge = $card.find('.' + CARD_BADGE_CLASS).first();
			const $stripe = $card.find('.' + CARD_CART_STRIPE_CLASS).first();
			const $btn = $card.find('.add_to_cart_button');
			const previous = Number($card.data('foodordCardCount') || 0);

			if (count > 0) {
				showCardCartStripe($card);

				if (!$badge.length) {
					$badge = $('<span>', {
						class: CARD_BADGE_CLASS,
						'aria-hidden': 'true',
					});

					if ($btn.length) {
						$btn.append($badge);
					} else {
						$card.append($badge);
					}
					$badge.text(count).addClass(CARD_BADGE_VISIBLE_CLASS);
				} else {
					animateCounter($badge, count);
				}

				if ($btn.length) {
					$btn.addClass('foodord-button-has-count');
				}

				if (count > previous) {
					$badge.addClass(CARD_BADGE_FLASH_CLASS);
					window.setTimeout(function () {
						$badge.removeClass(CARD_BADGE_FLASH_CLASS);
					}, 650);
				}

				$card.attr('data-foodord-card-count', count);
				$card.addClass('foodord-product-card--in-cart');
			} else {
				if ($badge.length) {
					$badge.remove();
				}
				if ($stripe.length) {
					hideCardCartStripe($stripe);
				}
				if ($btn.length) {
					$btn.removeClass('foodord-button-has-count');
				}
				$card.removeAttr('data-foodord-card-count');
				$card.removeClass('foodord-product-card--in-cart');
			}

			$card.data('foodordCardCount', count);
		};


		scheduleProductCountRefresh(50);

		$(document.body).on(
			'added_to_cart removed_from_cart updated_cart_totals wc_fragments_refreshed',
			function () {
				scheduleProductCountRefresh();
				scheduleProductLabelRowHeights(document);
			}
		);

		document.addEventListener(
			'foodord_cart_updated',
			function () {
				scheduleProductCountRefresh();
				scheduleProductLabelRowHeights(document);
			}
		);

		document.addEventListener(
			'wrc:deliveryModeSynced',
			function () {
				refreshProductAvailability();
				scheduleProductLabelRowHeights(document);
			}
		);
	}
);
