(function ($) {
	"use strict";

	/**
	 * All of the code for your public-facing JavaScript source
	 * should reside in this file.
	 *
	 * Note: It has been assumed you will write jQuery code here, so the
	 * $ function reference has been prepared for usage within the scope
	 * of this function.
	 *
	 * This enables you to define handlers, for when the DOM is ready:
	 *
	 * $(function() {
	 *
	 * });
	 *
	 * When the window is loaded:
	 *
	 * $( window ).load(function() {
	 *
	 * });
	 *
	 * ...and/or other possibilities.
	 *
	 * Ideally, it is not considered best practise to attach more than a
	 * single DOM-ready or window-load handler for a particular page.
	 * Although scripts in the WordPress core, Plugins and Themes may be
	 * practising this, we should strive to set a better example in our own work.
	 */

	$(window).on("load", function () {
		initModelViewers();
		initModelViewerDimensions();
	});

	$(window).on("resize", function () {
		resizeModelViewerWrapper();
	});

	const resizeModelViewerWrapper = () => {
		const wrappers = document.querySelectorAll(".u3dmv-model-viewer-wrapper");

		wrappers.forEach(function (wrapper) {
			// Get the originally set height (from inline style or CSS)
			const originalHeight = wrapper.dataset.originalHeight || getComputedStyle(wrapper).height;

			// Store it in data-* so it’s preserved
			wrapper.dataset.originalHeight = originalHeight;

			const originalHeightFloat = parseFloat(originalHeight);
			const currentWidth = wrapper.offsetWidth;

			// Set height to the smaller of the width or original height
			const newHeight = Math.min(currentWidth, originalHeightFloat);
			wrapper.style.height = `${newHeight}px`;
		});
	};

	const initModelViewers = () => {
		self.ModelViewerElement = self.ModelViewerElement || {};

		$(".model-viewer").each(function () {
			const $modelViewer = $(this);
			const $progressText = $modelViewer.siblings(".progress-text");

			$modelViewer.on("progress", function (event) {
				const progress = Math.round(event.originalEvent.detail.totalProgress * 100);
				$progressText.text(`Loading ${progress}%`).show();

				if (progress === 100) {
					$progressText.hide();
				}
			});

			$modelViewer.on("progress", onMVWProgess);
		});
	};

	const initModelViewerDimensions = () => {
		const modelViewers = document.querySelectorAll("model-viewer[data-dim-mode]");
		if (!modelViewers || modelViewers.length === 0) return;

		modelViewers.forEach((viewer) => {
			const { dimX, dimY, dimZ, dimMode, scaleFactor } = viewer.dataset;

			// dimensions not set
			if (!dimX && !dimY && !dimZ && !scaleFactor && !dimMode) return;

			const scale = scaleFactor ? parseFloat(scaleFactor) : "1";
			const validScale = !isNaN(scale) && scale > 0 ? scale : 1;
			const useCustomDimensions = dimMode === "custom";
			const customDimensionsSet = dimX && dimY && dimZ;

			viewer.addEventListener("load", () => {
				const center = viewer.getBoundingBoxCenter();
				const realSize = viewer.getDimensions(); // Keep using real size for positions

				const x2 = realSize.x / 2;
				const y2 = realSize.y / 2;
				const z2 = realSize.z / 2;

				const dimXFloat = parseFloat(dimX);
				const dimYFloat = parseFloat(dimY);
				const dimZFloat = parseFloat(dimZ);

				// Position dots using REAL dimensions
				viewer.updateHotspot({
					name: "hotspot-dot+X-Y+Z",
					position: `${center.x + x2} ${center.y - y2} ${center.z + z2}`,
				});
				viewer.updateHotspot({
					name: "hotspot-dot+X-Y-Z",
					position: `${center.x + x2} ${center.y - y2} ${center.z - z2}`,
				});
				viewer.updateHotspot({
					name: "hotspot-dot+X+Y-Z",
					position: `${center.x + x2} ${center.y + y2} ${center.z - z2}`,
				});
				viewer.updateHotspot({
					name: "hotspot-dot-X+Y-Z",
					position: `${center.x - x2} ${center.y + y2} ${center.z - z2}`,
				});
				viewer.updateHotspot({
					name: "hotspot-dot-X-Y-Z",
					position: `${center.x - x2} ${center.y - y2} ${center.z - z2}`,
				});
				viewer.updateHotspot({
					name: "hotspot-dot-X-Y+Z",
					position: `${center.x - x2} ${center.y - y2} ${center.z + z2}`,
				});

				// Position dimensions using real dimensions too
				viewer.updateHotspot({
					name: "hotspot-dim+X-Y",
					position: `${center.x + x2 * 1.2} ${center.y - y2 * 1.1} ${center.z}`,
				});
				viewer.updateHotspot({
					name: "hotspot-dim+X-Z",
					position: `${center.x + x2 * 1.2} ${center.y} ${center.z - z2 * 1.2}`,
				});
				viewer.updateHotspot({
					name: "hotspot-dim+Y-Z",
					position: `${center.x} ${center.y + y2 * 1.1} ${center.z - z2 * 1.1}`,
				});
				viewer.updateHotspot({
					name: "hotspot-dim-X-Z",
					position: `${center.x - x2 * 1.2} ${center.y} ${center.z - z2 * 1.2}`,
				});
				viewer.updateHotspot({
					name: "hotspot-dim-X-Y",
					position: `${center.x - x2 * 1.2} ${center.y - y2 * 1.1} ${center.z}`,
				});

				viewer.querySelector('button[slot="hotspot-dim+X-Y"]').textContent =
					useCustomDimensions && customDimensionsSet ? `${dimZFloat.toFixed(2)} cm` : `${(realSize.z.toFixed(2) * validScale).toFixed(2)} cm`;

				viewer.querySelector('button[slot="hotspot-dim+X-Z"]').textContent =
					useCustomDimensions && customDimensionsSet ? `${dimYFloat.toFixed(2)} cm` : `${(realSize.y.toFixed(2) * validScale).toFixed(2)} cm`;

				viewer.querySelector('button[slot="hotspot-dim+Y-Z"]').textContent =
					useCustomDimensions && customDimensionsSet ? `${dimXFloat.toFixed(2)} cm` : `${(realSize.x.toFixed(2) * validScale).toFixed(2)} cm`;

				viewer.querySelector('button[slot="hotspot-dim-X-Z"]').textContent =
					useCustomDimensions && customDimensionsSet ? `${dimYFloat.toFixed(2)} cm` : `${(realSize.y.toFixed(2) * validScale).toFixed(2)} cm`;

				viewer.querySelector('button[slot="hotspot-dim-X-Y"]').textContent =
					useCustomDimensions && customDimensionsSet ? `${dimZFloat.toFixed(2)} cm` : `${(realSize.z.toFixed(2) * validScale).toFixed(2)} cm`;

				renderSVG();
				viewer.addEventListener("camera-change", renderSVG);
			});
		});
	};

	function drawLine(svgLine, dotHotspot1, dotHotspot2, dimensionHotspot) {
		if (dotHotspot1 && dotHotspot2) {
			svgLine.setAttribute("x1", dotHotspot1.canvasPosition.x);
			svgLine.setAttribute("y1", dotHotspot1.canvasPosition.y);
			svgLine.setAttribute("x2", dotHotspot2.canvasPosition.x);
			svgLine.setAttribute("y2", dotHotspot2.canvasPosition.y);

			// use provided optional hotspot to tie visibility of this svg line to
			if (dimensionHotspot && !dimensionHotspot.facingCamera) {
				svgLine.classList.add("hide");
			} else {
				svgLine.classList.remove("hide");
			}
		}
	}

	const renderSVG = () => {
		const modelViewers = document.querySelectorAll("model-viewer[data-dim-mode]");
		// const modelViewer = document.getElementById("u3dmv-model-viewer-woo");
		// const dimLines = document.querySelectorAll("model-viewer[data-dim-mode] line");

		modelViewers.forEach((viewer) => {
			const dimLines = viewer.querySelectorAll("line");
			drawLine(dimLines[0], viewer.queryHotspot("hotspot-dot+X-Y+Z"), viewer.queryHotspot("hotspot-dot+X-Y-Z"), viewer.queryHotspot("hotspot-dim+X-Y"));
			drawLine(dimLines[1], viewer.queryHotspot("hotspot-dot+X-Y-Z"), viewer.queryHotspot("hotspot-dot+X+Y-Z"), viewer.queryHotspot("hotspot-dim+X-Z"));
			drawLine(dimLines[2], viewer.queryHotspot("hotspot-dot+X+Y-Z"), viewer.queryHotspot("hotspot-dot-X+Y-Z")); // always visible
			drawLine(dimLines[3], viewer.queryHotspot("hotspot-dot-X+Y-Z"), viewer.queryHotspot("hotspot-dot-X-Y-Z"), viewer.queryHotspot("hotspot-dim-X-Z"));
			drawLine(dimLines[4], viewer.queryHotspot("hotspot-dot-X-Y-Z"), viewer.queryHotspot("hotspot-dot-X-Y+Z"), viewer.queryHotspot("hotspot-dim-X-Y"));
		});
	};

	const onMVWProgess = function (event) {
		const $progressBar = $(event.target).find(".progress-bar");
		const $updatingBar = $(event.target).find(".update-bar");

		$updatingBar.css("width", event.originalEvent.detail.totalProgress * 100 + "%");

		if (event.originalEvent.detail.totalProgress === 1) {
			$progressBar.addClass("hide");
			$(event.target).off("progress", onMVWProgess);
		} else {
			$progressBar.removeClass("hide");
		}
	};
})(jQuery);
