const RECENTER_DELAY = 1;
const RECENTER_ANIMATION_DURATION = 0.25;

window.addEventListener("DOMContentLoaded", initializeImageComparison);

function initializeImageComparison() {
	Array.from(document.querySelectorAll("[data-image-comparison]")).forEach((element) => {
		if (!(element instanceof HTMLElement)) return;

		const moveHandler = (/** @type {PointerEvent} **/ event) => {
			const factor = (event.clientX - element.getBoundingClientRect().left) / element.getBoundingClientRect().width;
			const capped = Math.max(0, Math.min(1, factor));

			if (!(element instanceof HTMLElement)) return;
			element.style.setProperty("--comparison-percent", `${capped * 100}%`);
			element.dataset.lastInteraction = "";
		};

		const leaveHandler = (/** @type {PointerEvent} **/ event) => {
			moveHandler(event);

			const randomCode = String(Math.random()).substring(2);
			element.dataset.lastInteraction = randomCode;

			setTimeout(() => {
				if (element.dataset.lastInteraction === randomCode) {
					element.dataset.recenterStartTime = `${Date.now()}`;
					element.dataset.recenterStartValue = `${parseFloat(element.style.getPropertyValue("--comparison-percent"))}`;

					recenterAnimationStep();
				}
			}, RECENTER_DELAY * 1000);
		};

		const recenterAnimationStep = () => {
			if (element.dataset.lastInteraction === "") return;

			const completionFactor = (Date.now() - Number(element.dataset.recenterStartTime)) / (RECENTER_ANIMATION_DURATION * 1000);
			if (completionFactor > 1) {
				element.dataset.lastInteraction = "";
				return;
			}

			const factor = smootherstep(completionFactor);
			const newLocation = lerp(Number(element.dataset.recenterStartValue), 50, factor);
			element.style.setProperty("--comparison-percent", `${newLocation}%`);

			requestAnimationFrame(recenterAnimationStep);
		};

		const lerp = (/** @type {number} **/ a, /** @type {number} **/ b, /** @type {number} **/ t) => (1 - t) * a + t * b;
		const smootherstep = (/** @type {number} **/ x) => x * x * x * (x * (x * 6 - 15) + 10);

		element.addEventListener("pointermove", moveHandler);
		element.addEventListener("pointerenter", moveHandler);
		element.addEventListener("pointerleave", leaveHandler);
		element.addEventListener("dragstart", (event) => event.preventDefault());
	});
}
