/**
 * Storzen — Variation Swatches (frontend)
 *
 * Glue layer between our swatch UI and WooCommerce's native variations form.
 * The shadow <select> is still in the DOM (visually hidden); when a swatch is
 * clicked we set the select's value and dispatch the same events WC listens
 * for, so price / availability / images update natively.
 *
 * No external dependencies beyond jQuery (only used because WC's variations.js
 * binds via jQuery events that pure DOM dispatch doesn't reliably reach).
 */
(function ($) {
	'use strict';

	if (typeof window.StorzenSwatchData === 'undefined') {
		window.StorzenSwatchData = {};
	}
	var cfg = window.StorzenSwatchData;

	// ── Set tooltip position attribute from settings ──────────────────────
	function applyTooltipPosition() {
		var pos = cfg.tooltipPosition || 'top';
		document.querySelectorAll('.storzen-swatch[data-tooltip]').forEach(function (el) {
			el.setAttribute('data-pos', pos);
		});
	}

	// ── Click handler: set the shadow <select>, propagate to WC ───────────
	function onSwatchClick(e) {
		var swatch = e.target.closest('.storzen-swatch');
		if (!swatch) return;
		if (swatch.classList.contains('is-out-of-stock')) {
			e.preventDefault();
			return;
		}

		var group     = swatch.closest('.storzen-swatches');
		if (!group) return;

		// Deselect siblings.
		group.querySelectorAll('.storzen-swatch.is-selected').forEach(function (el) {
			el.classList.remove('is-selected');
			el.setAttribute('aria-checked', 'false');
		});
		swatch.classList.add('is-selected');
		swatch.setAttribute('aria-checked', 'true');

		var value     = swatch.getAttribute('data-value');
		var attribute = group.getAttribute('data-attribute');
		var $form     = $(group).closest('.variations_form');

		// On shop cards we don't have a variations_form — show selection only.
		if (!$form.length) {
			updateSelectedLabel(group, swatch.getAttribute('aria-label') || value);
			return;
		}

		// Update label
		updateSelectedLabel(group, swatch.getAttribute('aria-label') || value);

		// Find the shadow <select> that WC reads for this attribute.
		var $select = $form.find('select[name="attribute_' + sanitizeAttrSlug(attribute) + '"]');
		if (!$select.length) {
			// Fall back to the dropdown WC injected (selector may be slightly different).
			$select = $form.find('select').filter(function () {
				return ($(this).attr('name') || '').toLowerCase() === 'attribute_' + attribute.toLowerCase();
			});
		}
		if (!$select.length) return;

		// Animation flag — gets removed after transition ends.
		if (cfg.animation && cfg.animation !== 'none' && cfg.showPriceChange !== false) {
			$form.addClass('storzen-anim-' + cfg.animation).addClass('is-changing');
			window.setTimeout(function () { $form.removeClass('is-changing'); }, 250);
		}

		$select.val(value).trigger('change');

		// Variation gallery sync (Pro). After WC updates the variation, swap
		// the main image. WC fires 'found_variation' on the form when a match
		// resolves; we hook into it via a delegated listener below.
	}

	function updateSelectedLabel(group, label) {
		var attribute = group.getAttribute('data-attribute');
		if (!attribute) return;
		// The label span sits as a SIBLING of the swatches group.
		var sibling = group.nextElementSibling;
		while (sibling) {
			if (sibling.classList && sibling.classList.contains('storzen-swatch-selected-label')
				&& sibling.getAttribute('data-attribute') === attribute) {
				sibling.textContent = label;
				return;
			}
			sibling = sibling.nextElementSibling;
		}
	}

	function sanitizeAttrSlug(attr) {
		// Mirror PHP sanitize_title() rules at a basic level.
		return String(attr).toLowerCase().replace(/[^a-z0-9_-]/g, '-');
	}

	// ── Keyboard support — Space / Enter activate ────────────────────────
	function onSwatchKeydown(e) {
		if (e.key !== 'Enter' && e.key !== ' ') return;
		var swatch = e.target.closest('.storzen-swatch');
		if (!swatch) return;
		e.preventDefault();
		swatch.click();
	}

	// ── Variation gallery sync (Pro) ─────────────────────────────────────
	function bindVariationGallery() {
		if (!cfg.variationGallery) return;

		$('.variations_form').on('found_variation.storzen', function (event, variation) {
			if (!variation || !variation.image || !variation.image.gallery_thumbnail_src) return;

			var $gallery = $(this).closest('.product').find('.woocommerce-product-gallery');
			if (!$gallery.length) return;

			// WooCommerce already swaps the featured image on `found_variation`.
			// What it doesn't do is reorder/refilter the rest of the gallery
			// thumbnails to match the variation. Without a per-variation gallery
			// stored in product meta we can't do better than what's available;
			// this hook is a placeholder for a future enhancement where users
			// can attach gallery images to specific variations.
			$gallery.trigger('storzen:variation_gallery', variation);
		});
	}

	// ── Auto-select first available variation ────────────────────────────
	function autoSelectFirstAvailable() {
		if (!cfg.autoSelectFirst) return;

		$('.variations_form').each(function () {
			var $form = $(this);
			$form.find('.storzen-swatches').each(function () {
				var $group = $(this);
				// Skip if user already selected something or default exists.
				if ($group.find('.storzen-swatch.is-selected').length) return;

				var $first = $group.find('.storzen-swatch').not('.is-out-of-stock').first();
				if ($first.length) {
					// Defer one tick so WC variations form is fully initialized.
					window.setTimeout(function () { $first.trigger('click'); }, 50);
				}
			});
		});
	}

	// ── Init ─────────────────────────────────────────────────────────────
	function init() {
		applyTooltipPosition();
		bindVariationGallery();
		autoSelectFirstAvailable();

		// Delegated handlers — work for swatches injected by AJAX (filters, infinite scroll).
		document.addEventListener('click',    onSwatchClick);
		document.addEventListener('keydown',  onSwatchKeydown);
	}

	if (document.readyState === 'loading') {
		document.addEventListener('DOMContentLoaded', init);
	} else {
		init();
	}
})(window.jQuery || function () { return { length: 0, find: function () { return this; }, on: function () { return this; }, each: function () { return this; } }; });
