function gtmkitLoad() {
	const datalayerName = window.gtmkit_settings.datalayer_name;

	let selectedProductVariationData;

	const productBlockIndex = {
		'wp-block-handpicked-products': 1,
		'wp-block-product-best-sellers': 1,
		'wp-block-product-category': 1,
		'wp-block-product-new': 1,
		'wp-block-product-on-sale': 1,
		'wp-block-products-by-attribute': 1,
		'wp-block-product-tag': 1,
		'wp-block-product-top-rated': 1,
	};

	// Set list name and position on product blocks
	document
		.querySelectorAll('.wc-block-grid .wc-block-grid__product')
		.forEach(function (gridItem) {
			const productGrid = gridItem.closest('.wc-block-grid');
			const productData = gridItem.querySelector('.gtmkit_product_data');

			if (productGrid && productData) {
				const productGridClasses = productGrid.classList;

				if (productGridClasses) {
					for (const i in productBlockIndex) {
						if (productGridClasses.contains(i)) {
							const itemData = JSON.parse(
								productData.getAttribute(
									'data-gtmkit_product_data'
								)
							);
							itemData.item_list_name =
								window.gtmkit_settings.wc.text[i];
							itemData.index = productBlockIndex[i];
							productData.setAttribute(
								'data-gtmkit_product_data',
								JSON.stringify(itemData)
							);
							productBlockIndex[i]++;
						}
					}
				}
			}
		});

	// view_item_list event in product lists
	const productDataElements = document.querySelectorAll(
		'.gtmkit_product_data'
	);

	if (productDataElements.length) {
		const items = [];
		let itemData;

		productDataElements.forEach(function (productData) {
			itemData = JSON.parse(
				productData.getAttribute('data-gtmkit_product_data')
			);
			items.push(itemData);
		});

		window[datalayerName].push({ ecommerce: null });
		window[datalayerName].push({
			event: 'view_item_list',
			ecommerce: {
				items,
			},
		});
	}

	// add_to_cart event for simple products in product lists
	document.addEventListener('click', function (e) {
		const eventTargetElement = e.target;
		let event;

		if (!eventTargetElement) {
			return true;
		}

		if (
			eventTargetElement.closest(
				window.gtmkit_settings.wc.css_selectors.product_list_add_to_cart
			)
		) {
			event = 'add_to_cart';
		} else if ( window.gtmkit_settings.wc.wishlist &&
			(eventTargetElement.closest('.products') ||
				eventTargetElement.closest('.wc-block-grid__products')) &&
			eventTargetElement.closest(
				window.gtmkit_settings.wc.css_selectors.product_list_wishlist
			)
		) {
			event = 'add_to_wishlist';
		} else {
			return true;
		}

		const productElement = eventTargetElement.closest(
			window.gtmkit_settings.wc.css_selectors.product_list_element
		);
		const productData =
			productElement &&
			productElement.querySelector('.gtmkit_product_data');
		if (!productData) {
			return true;
		}

		const itemData = JSON.parse(
			productData.getAttribute('data-gtmkit_product_data')
		);

		itemData.quantity = 1;

		window[datalayerName].push({ ecommerce: null });
		window[datalayerName].push({
			event,
			ecommerce: {
				currency: window.gtmkit_data.wc.currency,
				value: itemData.price,
				items: [itemData],
			},
		});
	}, true);

	// add_to_cart event on product page
	document.addEventListener('click', function (e) {
		const eventTargetElement = e.target;

		if (!eventTargetElement) {
			return true;
		}

		let event;
		let formCartElement = eventTargetElement.closest('form.cart');

		if ( ! formCartElement ) {
			let parentNode = eventTargetElement.parentNode;

			while (!formCartElement && parentNode) {
				formCartElement = parentNode.querySelector('form.cart');
				parentNode = parentNode.parentNode;
			}
		}

		if ( formCartElement ) {
			if ( eventTargetElement.closest( '.single_add_to_cart_button:not(.disabled,.input-needed)' ) ) {
				event = 'add_to_cart';
			} else if ( window.gtmkit_settings.wc.wishlist && eventTargetElement.closest( window.gtmkit_settings.wc.css_selectors.single_product_wishlist ) ) {
				event = 'add_to_wishlist';
			} else {
				return true;
			}
		} else {
			return true;
		}

		const productVariantId = formCartElement.querySelectorAll(
			'[name=variation_id]'
		);
		const productIsGrouped =
			formCartElement.classList && formCartElement.classList.contains('grouped_form') &&
			!formCartElement.classList.contains('bundle_form');

		if (productVariantId.length) {
			let quantity = 1;
			let price;
			if (selectedProductVariationData) {
				const quantityElement =
					formCartElement.querySelector('[name=quantity]');
				selectedProductVariationData.quantity =
					(quantityElement && quantityElement.value) || 1;
				quantity = selectedProductVariationData.quantity;
				price = selectedProductVariationData.price;
			}

			if (
				(selectedProductVariationData && event === 'add_to_cart') ||
				event === 'add_to_wishlist'
			) {
				window[datalayerName].push({ ecommerce: null });
				window[datalayerName].push({
					event,
					ecommerce: {
						currency: window.gtmkit_data.wc.currency,
						value: price * quantity,
						items: [selectedProductVariationData],
					},
				});
			}
		} else if (productIsGrouped) {
			const productsInGroup = document.querySelectorAll(
				'.grouped_form .gtmkit_product_data'
			);
			const products = [];
			let value = 0;

			productsInGroup.forEach(function (productData) {
				let productQuantity = document.querySelectorAll(
					'input[name=quantity\\[' +
					productData.getAttribute('data-gtmkit_product_id') +
					'\\]]'
				);

				productQuantity = Number(productQuantity[0].value);
				productQuantity = isNaN(productQuantity) ? 0 : productQuantity;

				if (0 === productQuantity && event === 'add_to_cart') {
					return true;
				} else if (0 === productQuantity && event === 'add_to_wishlist') {
					productQuantity = 1;
				}

				const itemData = JSON.parse(
					productData.getAttribute('data-gtmkit_product_data')
				);

				itemData.quantity = productQuantity;

				products.push(itemData);
				value += itemData.price * itemData.quantity;
			});

			if (0 === products.length) {
				return true;
			}

			window[datalayerName].push({ ecommerce: null });
			window[datalayerName].push({
				event,
				ecommerce: {
					currency: window.gtmkit_data.wc.currency,
					value,
					items: products,
				},
			});
		} else {
			const itemData = JSON.parse(
				formCartElement.querySelector('[name=gtmkit_product_data]') &&
				formCartElement.querySelector('[name=gtmkit_product_data]').value
			);

			const quantityElement = formCartElement.querySelector('[name=quantity]');
			itemData.quantity = ( quantityElement && quantityElement.value ) || 1;

			window[datalayerName].push({ ecommerce: null });
			window[datalayerName].push({
				event,
				ecommerce: {
					currency: window.gtmkit_data.wc.currency,
					value: itemData.price * itemData.quantity,
					items: [itemData],
				},
			});
		}
	}, true);

	// remove_from_cart event on cart remove links
	document.addEventListener('click', function (e) {
		const productData = e.target;

		if (
			!productData ||
			!productData.closest(
				'.mini_cart_item a.remove,.product-remove a.remove'
			)
		) {
			return true;
		}

		const itemData = JSON.parse(
			productData.getAttribute('data-gtmkit_product_data')
		);

		if (!itemData) return true;

		window[datalayerName].push({ ecommerce: null });
		window[datalayerName].push({
			event: 'remove_from_cart',
			ecommerce: {
				items: [itemData],
			},
		});
	}, true);

	// select_item event on clicks in product lists
	document.addEventListener('click', function (e) {
		const eventTargetElement = e.target;
		const linkElement = eventTargetElement.closest( window.gtmkit_settings.wc.css_selectors.product_list_select_item );
		if (!linkElement) return true;

		if ( window.gtmkit_settings.wc.css_selectors.product_list_exclude && linkElement.closest(window.gtmkit_settings.wc.css_selectors.product_list_exclude)) {
			return true;
		}

		const product = eventTargetElement.closest(
			window.gtmkit_settings.wc.css_selectors.product_list_element
		);

		let productData;

		if (product) {
			productData = product.querySelector('.gtmkit_product_data');
			if (!productData) return true;
		} else {
			return true;
		}

		if (
			'undefined' ===
			typeof productData.getAttribute('data-gtmkit_product_data')
		) {
			return true;
		}

		const itemData = JSON.parse(
			productData.getAttribute('data-gtmkit_product_data')
		);

		if (!itemData) return true;

		window[datalayerName].push({ ecommerce: null });
		window[datalayerName].push({
			event: 'select_item',
			ecommerce: {
				items: [itemData],
			},
		});
	}, true);

	// track product variations on product page
	// eslint-disable-next-line no-undef
	jQuery(document).on('found_variation', function (event, productVariation) {
		if ('undefined' === typeof productVariation) return;

		const variationsForm = event.target;
		const gtmkitElement = variationsForm.querySelector(
			'[name=gtmkit_product_data]'
		);

		// Check if the gtmkit_product_data exists and bail early if it doesn't
		if (!gtmkitElement) return;

		const productVariationData = JSON.parse(
			variationsForm.querySelector('[name=gtmkit_product_data]') &&
			variationsForm.querySelector('[name=gtmkit_product_data]').value
		);

		productVariationData.id = productVariationData.item_id =
			window.gtmkit_settings.wc.pid_prefix +
			productVariation.variation_id;
		if (
			window.gtmkit_settings.wc.use_sku &&
			productVariation.sku &&
			'' !== productVariation.sku
		) {
			productVariationData.id = productVariationData.item_id =
				window.gtmkit_settings.wc.pid_prefix + productVariation.sku;
		}

		// gtmkit_price is injected server-side via the
		// woocommerce_available_variation filter so the toggle wins over
		// Woo's display setting; fall back to display_price for safety.
		productVariationData.price =
			'undefined' !== typeof productVariation.gtmkit_price
				? productVariation.gtmkit_price
				: productVariation.display_price;

		const productAttributes = [];
		for (const attribKey in productVariation.attributes) {
			productAttributes.push(productVariation.attributes[attribKey]);
		}
		productVariationData.item_variant = productAttributes
			.filter((n) => n)
			.join('|');
		selectedProductVariationData = productVariationData;

		if (window.gtmkit_settings.wc.view_item.config !== 0) {
			window[datalayerName].push({ ecommerce: null });
			window[datalayerName].push({
				event: 'view_item',
				ecommerce: {
					currency: window.gtmkit_data.wc.currency,
					value: productVariationData.price,
					items: [productVariationData],
				},
			});
		}

		if (window.gtmkit_settings.console_log === true) {
			// eslint-disable-next-line no-console
			console.log(`GTM Kit: selectedProductVariationData`);
			// eslint-disable-next-line no-console
			console.log(selectedProductVariationData);
		}
	});
}

if (document.readyState === 'loading') {
	document.addEventListener('DOMContentLoaded', gtmkitLoad);
} else {
	gtmkitLoad();
}
