(function (window, document) {
	'use strict';

	if (window.FoodordSwipeDismiss) {
		return;
	}

	const interactiveSelector = 'button, a, input, select, textarea, [contenteditable="true"], [role="button"]';
	const topActivationHeight = 84;
	const directionThreshold = 8;
	const velocityThreshold = 0.55;
	const minimumVelocityDistance = 40;
	const resetDelay = 360;
	const configurations = [
		{
			sheet: '.foodord-pro-stampcard-modal__dialog',
			root: '.foodord-pro-stampcard-modal',
			close: '.foodord-pro-stampcard-modal__close',
			media: '(max-width: 600px)',
			activeClass: 'is-visible'
		},
		{
			sheet: '.foodord-banner-modal-dialog',
			root: '.foodord-banner-modal-overlay',
			close: '.foodord-banner-modal-close',
			media: '(max-width: 1024px)',
			activeClass: 'is-visible'
		},
		{
			sheet: '.foodord-scroll-nav__search-overlay-content',
			root: '.foodord-scroll-nav__search-overlay',
			close: '.foodord-scroll-nav__search-overlay-close',
			media: '(max-width: 1024px)',
			activeClass: 'is-open'
		},
		{
			sheet: '.foodord-mobile-cart__modal-content',
			root: '#foodord-mobile-cart-modal',
			close: '.foodord-mobile-cart__close-btn',
			media: '(max-width: 1024px)',
			activeClass: 'active'
		},
		{
			sheet: '.foodord-sheet-backdrop .foodord-sheet',
			root: '.foodord-sheet-backdrop',
			close: '.foodord-sheet__close',
			media: '(max-width: 768px)',
			activeClass: 'is-visible'
		},
		{
			sheet: '#foodord-product-modal .foodord-modal-content',
			root: '#foodord-product-modal',
			close: '.foodord-modal-close',
			media: '(max-width: 768px)',
			activeClass: 'is-open'
		}
	];

	let gesture = null;

	function findConfiguration(target) {
		if (!(target instanceof Element)) {
			return null;
		}

		for (const configuration of configurations) {
			const sheet = target.closest(configuration.sheet);
			if (!sheet || !window.matchMedia(configuration.media).matches) {
				continue;
			}

			const root = sheet.closest(configuration.root);
			if (!root || !root.classList.contains(configuration.activeClass)) {
				continue;
			}

			return { configuration, root, sheet };
		}

		return null;
	}

	function cancelMotion(activeGesture) {
		if (!activeGesture || !activeGesture.motion) {
			return;
		}

		activeGesture.motion.cancel();
		activeGesture.motion = null;
	}

	function transformForOffset(offsetY) {
		return `translate3d(0, ${Math.max(0, offsetY)}px, 0)`;
	}

	function updateDragPosition(activeGesture, offsetY) {
		if (!activeGesture.sheet.isConnected) {
			return;
		}

		const transform = transformForOffset(offsetY);
		activeGesture.offsetY = offsetY;

		if (activeGesture.motion && activeGesture.motion.effect && typeof activeGesture.motion.effect.setKeyframes === 'function') {
			activeGesture.motion.effect.setKeyframes([{ transform }, { transform }]);
			activeGesture.motion.currentTime = 1;
			return;
		}

		cancelMotion(activeGesture);
		activeGesture.motion = activeGesture.sheet.animate([{ transform }, { transform }], {
			duration: 1,
			fill: 'both'
		});
		activeGesture.motion.pause();
		activeGesture.motion.currentTime = 1;
	}

	function animateToOffset(activeGesture, offsetY, duration, easing) {
		if (!activeGesture.sheet.isConnected) {
			return;
		}

		const startOffset = activeGesture.offsetY || 0;
		cancelMotion(activeGesture);
		activeGesture.motion = activeGesture.sheet.animate([
			{ transform: transformForOffset(startOffset) },
			{ transform: transformForOffset(offsetY) }
		], {
			duration,
			easing,
			fill: 'forwards'
		});
		activeGesture.offsetY = offsetY;
	}

	function snapBack(activeGesture) {
		if (!activeGesture.sheet.isConnected) {
			return;
		}

		animateToOffset(activeGesture, 0, 280, 'cubic-bezier(0.22, 1, 0.36, 1)');
		window.setTimeout(function () {
			cancelMotion(activeGesture);
		}, 300);
	}

	function dismiss(activeGesture) {
		const { configuration, root, sheet } = activeGesture;
		const closeButton = root.querySelector(configuration.close);
		const dismissalDistance = Math.max(window.innerHeight, sheet.getBoundingClientRect().height);

		animateToOffset(activeGesture, dismissalDistance, 240, 'cubic-bezier(0.4, 0, 1, 1)');

		if (closeButton) {
			closeButton.click();
		}

		window.setTimeout(function () {
			cancelMotion(activeGesture);
		}, resetDelay);
	}

	function finishGesture(event, cancelled) {
		if (!gesture) {
			return;
		}

		const activeGesture = gesture;
		gesture = null;

		if (!activeGesture.dragging || cancelled) {
			if (activeGesture.dragging) {
				snapBack(activeGesture);
			}
			return;
		}

		const touch = event.changedTouches && event.changedTouches[0];
		const endY = touch ? touch.clientY : activeGesture.currentY;
		const distance = Math.max(0, endY - activeGesture.startY);
		const elapsed = Math.max(1, window.performance.now() - activeGesture.startTime);
		const velocity = distance / elapsed;
		const sheetHeight = activeGesture.sheet.getBoundingClientRect().height;
		const distanceThreshold = Math.min(160, Math.max(96, sheetHeight * 0.18));
		const shouldDismiss = distance >= distanceThreshold || (
			distance >= minimumVelocityDistance && velocity >= velocityThreshold
		);

		if (shouldDismiss) {
			dismiss(activeGesture);
			return;
		}

		snapBack(activeGesture);
	}

	document.addEventListener('touchstart', function (event) {
		if (gesture || event.touches.length !== 1) {
			return;
		}

		const match = findConfiguration(event.target);
		if (!match || event.target.closest(interactiveSelector)) {
			return;
		}

		const touch = event.touches[0];
		const rect = match.sheet.getBoundingClientRect();
		if (touch.clientY - rect.top > topActivationHeight) {
			return;
		}

		gesture = {
			...match,
			startX: touch.clientX,
			startY: touch.clientY,
			currentY: touch.clientY,
			startTime: window.performance.now(),
			dragging: false,
			offsetY: 0,
			motion: null
		};
	}, { passive: true, capture: true });

	document.addEventListener('touchmove', function (event) {
		if (!gesture || event.touches.length !== 1) {
			return;
		}

		const touch = event.touches[0];
		const deltaX = touch.clientX - gesture.startX;
		const deltaY = touch.clientY - gesture.startY;

		if (!gesture.dragging) {
			if (Math.abs(deltaX) < directionThreshold && Math.abs(deltaY) < directionThreshold) {
				return;
			}

			if (deltaY <= 0 || Math.abs(deltaX) > Math.abs(deltaY)) {
				gesture = null;
				return;
			}

			gesture.dragging = true;
		}

		if (deltaY <= 0) {
			return;
		}

		event.preventDefault();
		gesture.currentY = touch.clientY;
		updateDragPosition(gesture, deltaY);
	}, { passive: false, capture: true });

	document.addEventListener('touchend', function (event) {
		finishGesture(event, false);
	}, { passive: true, capture: true });

	document.addEventListener('touchcancel', function (event) {
		finishGesture(event, true);
	}, { passive: true, capture: true });

	window.FoodordSwipeDismiss = true;
})(window, document);
