/**
 * Storzen — Back in Stock Notifier — Front-end JS
 *
 * Responsibilities:
 *  1. Listen for subscribe button clicks inside .sz-bis-wrap.
 *  2. Validate email client-side before sending to AJAX handler.
 *  3. Send the AJAX subscribe request and show the server response.
 *  4. For VARIABLE products: listen to WC's found_variation / reset_data
 *     events and show/hide the form + update the product_id based on
 *     the variation selected and whether that variation is out of stock.
 *
 * No jQuery dependency — pure ES2017+ (supported in all WP-targeted browsers).
 * The szBisConfig object is localised by PHP (wp_localize_script).
 * The szBisVariations object (for variable products) is also localised by PHP.
 *
 * @package storzen
 * @since   1.3.0
 */

( function () {
	'use strict';

	// ── Config (localised by PHP) ──────────────────────────────────────────
	/** @type {{ ajaxUrl: string, action: string, showConsent: number, showOosOnly: number, i18n: {submitting: string, error: string} }} */
	var cfg = window.szBisConfig || {};

	/** @type {{ map: Record<string, {oos: boolean}>, parentId: number, showOosOnly: number }|undefined} */
	var variationData = window.szBisVariations;

	// ── Helpers ───────────────────────────────────────────────────────────

	/**
	 * Find the closest .sz-bis-wrap ancestor of an element.
	 *
	 * @param {HTMLElement} el
	 * @returns {HTMLElement|null}
	 */
	function findWrap( el ) {
		return el.closest( '.sz-bis-wrap' );
	}

	/**
	 * Show a message inside the wrap's .sz-bis-message element.
	 *
	 * @param {HTMLElement} wrap
	 * @param {string}      text
	 * @param {'success'|'error'} type
	 */
	function showMessage( wrap, text, type ) {
		var msg = wrap.querySelector( '.sz-bis-message' );
		if ( ! msg ) return;
		msg.textContent = text;
		msg.className   = 'sz-bis-message is-' + type;
		msg.removeAttribute( 'hidden' );
	}

	/**
	 * Set the submit button into loading / normal state.
	 *
	 * @param {HTMLElement} btn
	 * @param {boolean}     loading
	 * @param {string}      [originalText]
	 */
	function setButtonLoading( btn, loading, originalText ) {
		if ( loading ) {
			btn.setAttribute( 'data-original-text', btn.textContent );
			btn.textContent    = cfg.i18n && cfg.i18n.submitting ? cfg.i18n.submitting : 'Submitting…';
			btn.disabled       = true;
			btn.setAttribute( 'aria-busy', 'true' );
		} else {
			btn.textContent = originalText || btn.getAttribute( 'data-original-text' ) || btn.textContent;
			btn.disabled    = false;
			btn.removeAttribute( 'aria-busy' );
		}
	}

	// ── Subscribe click handler ────────────────────────────────────────────

	document.addEventListener( 'click', function ( e ) {
		var btn = e.target.closest( '.sz-bis-btn' );
		if ( ! btn ) return;

		var wrap = findWrap( btn );
		if ( ! wrap ) return;

		var emailInput   = wrap.querySelector( '.sz-bis-email' );
		var consentInput = wrap.querySelector( '.sz-bis-consent-chk' );
		var productId    = wrap.dataset.productId || wrap.getAttribute( 'data-product-id' );
		var nonce        = wrap.dataset.nonce || wrap.getAttribute( 'data-nonce' );

		// Client-side validation.
		if ( ! emailInput || ! emailInput.value.trim() ) {
			showMessage( wrap, 'Please enter your email address.', 'error' );
			emailInput && emailInput.focus();
			return;
		}

		var emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
		if ( ! emailRegex.test( emailInput.value.trim() ) ) {
			showMessage( wrap, 'Please enter a valid email address.', 'error' );
			emailInput.focus();
			return;
		}

		if ( cfg.showConsent && consentInput && ! consentInput.checked ) {
			showMessage( wrap, 'Please tick the consent checkbox.', 'error' );
			return;
		}

		if ( ! productId || ! nonce ) {
			showMessage( wrap, cfg.i18n ? cfg.i18n.error : 'Something went wrong.', 'error' );
			return;
		}

		// Send request.
		setButtonLoading( btn, true );

		var body = new FormData();
		body.append( 'action',     cfg.action || 'storzen_bis_subscribe' );
		body.append( 'nonce',      nonce );
		body.append( 'product_id', productId );
		body.append( 'email',      emailInput.value.trim() );
		body.append( 'consent',    consentInput && consentInput.checked ? '1' : '0' );

		fetch( cfg.ajaxUrl || ( wrap.getAttribute( 'data-ajaxurl' ) || '/wp-admin/admin-ajax.php' ), {
			method:      'POST',
			credentials: 'same-origin',
			body:        body,
		} )
			.then( function ( res ) { return res.json(); } )
			.then( function ( data ) {
				setButtonLoading( btn, false );
				if ( data.success ) {
					showMessage( wrap, data.data.message, 'success' );
					// Hide form fields after success; keep the message visible.
					var fields = wrap.querySelector( '.sz-bis-fields' );
					var intro  = wrap.querySelector( '.sz-bis-intro' );
					var consent = wrap.querySelector( '.sz-bis-consent' );
					if ( fields )  fields.style.display  = 'none';
					if ( intro )   intro.style.display   = 'none';
					if ( consent ) consent.style.display = 'none';
				} else {
					showMessage( wrap, ( data.data && data.data.message ) || ( cfg.i18n && cfg.i18n.error ) || 'Error.', 'error' );
				}
			} )
			.catch( function () {
				setButtonLoading( btn, false );
				showMessage( wrap, cfg.i18n ? cfg.i18n.error : 'Something went wrong. Please try again.', 'error' );
			} );
	} );

	// ── Variable product support ───────────────────────────────────────────

	if ( ! variationData ) return;

	var varMap      = variationData.map      || {};
	var showOosOnly = variationData.showOosOnly;

	/**
	 * Show or hide the BIS form based on the selected variation.
	 *
	 * @param {number|string} variationId  The selected variation ID (0 = none selected).
	 */
	function updateFormForVariation( variationId ) {
		var wraps = document.querySelectorAll( '.sz-bis-wrap[data-bis-variable]' );

		wraps.forEach( function ( wrap ) {
			if ( ! variationId ) {
				// No variation selected — hide form.
				wrap.style.display = 'none';
				return;
			}

			var varInfo = varMap[ variationId ];
			if ( ! varInfo ) {
				wrap.style.display = 'none';
				return;
			}

			var isOos = varInfo.oos;

			if ( showOosOnly && ! isOos ) {
				// Show-only-when-OOS is ON and this variation is in stock.
				wrap.style.display = 'none';
				return;
			}

			// Update the product_id to the variation ID so subscribe goes to the right product.
			wrap.dataset.productId = String( variationId );
			wrap.setAttribute( 'data-product-id', String( variationId ) );
			wrap.style.display = '';
		} );
	}

	// Listen to WooCommerce's variation events on the form.
	document.addEventListener( 'found_variation', function ( e ) {
		var variation = e.detail && e.detail[1];
		if ( variation && variation.variation_id ) {
			updateFormForVariation( variation.variation_id );
		}
	} );

	// jQuery-based WC events (WC fires these on the form element via jQuery trigger).
	if ( window.jQuery ) {
		jQuery( document ).on( 'found_variation', function ( e, variation ) {
			if ( variation && variation.variation_id ) {
				updateFormForVariation( variation.variation_id );
			}
		} );

		jQuery( document ).on( 'reset_data', function () {
			updateFormForVariation( 0 );
		} );
	}

}() );
