/**
 * AI Sales Assistant — frontend widget IFRAME controller.
 *
 * Configuration (POSITION_SIDE, WIDGET_ORIGIN) is passed in via
 * `kwiroWidget` (wp_localize_script) so this file can be a plain static
 * JS asset that wp_enqueue_script can register.
 *
 * @package KwiroAISalesAgent
 */

/* global kwiroWidget */
(function () {
	'use strict';

	var cfg = window.kwiroWidget || {};
	var POSITION_SIDE = cfg.positionSide === 'left' ? 'left' : 'right';
	// SECURITY: validate the origin of every incoming postMessage. Without
	// this, any third-party iframe on the customer's site could send forged
	// `kwiro_resize` / `kwiro_navigate` / `kwiro_add_to_cart` commands to
	// the parent window.
	var WIDGET_ORIGIN = cfg.widgetOrigin || '';

	function isFromWidgetIframe( event ) {
		if ( ! WIDGET_ORIGIN ) {
			return false;
		}
		if ( event.origin !== WIDGET_ORIGIN ) {
			return false;
		}
		var iframe = document.getElementById( 'kwiro-chat-widget' );
		if ( ! iframe || ! iframe.contentWindow ) {
			return false;
		}
		return event.source === iframe.contentWindow;
	}

	function sendViewport() {
		var iframe = document.getElementById( 'kwiro-chat-widget' );
		if ( ! iframe || ! iframe.contentWindow || ! WIDGET_ORIGIN ) {
			return;
		}
		iframe.contentWindow.postMessage( {
			type: 'kwiro_viewport',
			innerWidth: window.innerWidth,
			innerHeight: window.innerHeight
		}, WIDGET_ORIGIN );
	}

	// Send viewport once iframe loads, and on every parent resize.
	document.addEventListener( 'DOMContentLoaded', function () {
		var iframe = document.getElementById( 'kwiro-chat-widget' );
		if ( iframe ) {
			iframe.addEventListener( 'load', sendViewport );
		}
	} );
	window.addEventListener( 'resize', sendViewport );

	window.addEventListener( 'message', function ( event ) {
		// Reject anything not from the legitimate widget iframe.
		if ( ! isFromWidgetIframe( event ) ) {
			return;
		}
		if ( ! event.data ) {
			return;
		}

		// Widget requesting viewport (e.g. on mount race).
		if ( event.data.type === 'kwiro_request_viewport' ) {
			sendViewport();
			return;
		}

		// Dynamic resize — applied to the WRAPPER div (not the iframe) because
		// Chromium renders backdrop-filter on the rectangular bounding box of
		// an iframe BEFORE border-radius clipping, producing corner halos.
		// A div properly clips backdrop-filter to its border-radius.
		if ( event.data.type === 'kwiro_resize' ) {
			var wrap = document.getElementById( 'kwiro-chat-widget-wrap' );
			if ( ! wrap ) {
				return;
			}
			var w = Math.min( event.data.width, window.innerWidth );
			var h = Math.min( event.data.height, window.innerHeight );
			var offset = typeof event.data.offset === 'number' ? event.data.offset : 0;
			var radius = typeof event.data.radius === 'number' ? event.data.radius : 0;
			wrap.style.width = w + 'px';
			wrap.style.height = h + 'px';
			wrap.style.bottom = offset + 'px';
			if ( POSITION_SIDE === 'right' ) {
				wrap.style.right = offset + 'px';
				wrap.style.left = 'auto';
			} else {
				wrap.style.left = offset + 'px';
				wrap.style.right = 'auto';
			}
			wrap.style.borderRadius = radius + 'px';
			// Frosted glass + drop-shadow only when panel is open (radius > 0),
			// so the launcher area stays visually empty when closed.
			var open = radius > 0;
			var blur = open ? 'blur(40px) saturate(180%)' : 'none';
			wrap.style.backdropFilter = blur;
			wrap.style.webkitBackdropFilter = blur;
			wrap.style.boxShadow = open
				? '0 40px 80px -20px rgba(0,0,0,0.25), 0 0 0 0.5px rgba(0,0,0,0.08)'
				: 'none';
			// When closed, allow launcher/greeting shadows to escape the wrapper
			// naturally. When open, clip strictly to the rounded shape.
			wrap.style.overflow = open ? 'hidden' : 'visible';
			return;
		}

		// Navigate the top-level window (widget asks us to go to /checkout, /cart, etc.)
		if ( event.data.type === 'kwiro_navigate' && typeof event.data.path === 'string' ) {
			try {
				var raw = event.data.path;
				// Only allow same-origin paths (start with "/") to avoid hostile redirects.
				if ( raw.charAt( 0 ) === '/' && raw.charAt( 1 ) !== '/' ) {
					window.top.location.assign( raw );
				}
			} catch ( e ) {
				/* cross-origin top — ignore */
			}
			return;
		}

		if ( event.data.type !== 'kwiro_add_to_cart' ) {
			return;
		}
		// SECURITY: validate every numeric field client-side before posting to
		// /wc-ajax. WC will reject invalid product IDs server-side, but a
		// malicious widget bundle (or compromised CDN) could otherwise flood
		// the cart. Cap quantity at 99 — no real shopper buys more than that
		// in one click.
		var productId = parseInt( event.data.productId, 10 );
		if ( ! Number.isFinite( productId ) || productId <= 0 || productId > 2147483647 ) {
			return;
		}
		var rawQty = parseInt( event.data.quantity, 10 );
		var quantity = Number.isFinite( rawQty ) && rawQty > 0 ? Math.min( rawQty, 99 ) : 1;
		var rawVariation = event.data.variationId != null ? parseInt( event.data.variationId, 10 ) : 0;
		var variationId = Number.isFinite( rawVariation ) && rawVariation > 0 && rawVariation <= 2147483647 ? rawVariation : 0;
		var isVariable = variationId > 0;
		var responseId = isVariable ? variationId : productId;

		var formData = new FormData();
		if ( isVariable ) {
			// Variable products: use standard WC form POST (more reliable than AJAX).
			formData.append( 'product_id', String( productId ) );
			formData.append( 'variation_id', String( variationId ) );
			formData.append( 'quantity', String( quantity ) );
			formData.append( 'add-to-cart', String( productId ) );
			var attrs = event.data.variationAttributes || {};
			for ( var key in attrs ) {
				// Reject any attribute key with characters outside [a-z0-9_-];
				// WC's pa_ taxonomy slugs only ever contain those, so anything
				// else is an attempted form-field-name injection.
				if ( typeof key !== 'string' || ! /^[a-zA-Z0-9 _-]{1,40}$/.test( key ) ) {
					continue;
				}
				var attrVal = attrs[ key ];
				if ( typeof attrVal !== 'string' && typeof attrVal !== 'number' ) {
					continue;
				}
				// WC global (taxonomy) attributes are stored as pa_<slug> and the
				// form field must be attribute_pa_<slug>. Add the pa_ prefix if
				// the incoming key doesn't already have it.
				var rawKey = String( key ).toLowerCase().replace( /\s+/g, '-' );
				if ( rawKey.indexOf( 'pa_' ) !== 0 ) {
					rawKey = 'pa_' + rawKey;
				}
				formData.append( 'attribute_' + rawKey, String( attrVal ).toLowerCase().slice( 0, 100 ) );
			}
		} else {
			// Simple products: use AJAX add_to_cart.
			formData.append( 'product_id', String( productId ) );
			formData.append( 'quantity', String( quantity ) );
		}

		var url = isVariable
			? '/?add-to-cart=' + productId
			: '/?wc-ajax=add_to_cart';

		fetch( url, {
			method: 'POST',
			body: formData,
			credentials: 'same-origin'
		} )
			.then( function ( res ) {
				if ( isVariable ) {
					// Variable product form POST returns HTML — success if status is 200/302.
					return { success: res.ok || res.redirected };
				}
				return res.json().then( function ( j ) {
					return { success: ! j.error, fragments: j.fragments };
				} );
			} )
			.then( function ( resData ) {
				var iframe = document.getElementById( 'kwiro-chat-widget' );
				if ( iframe && iframe.contentWindow && WIDGET_ORIGIN ) {
					iframe.contentWindow.postMessage( {
						type: 'kwiro_add_to_cart_result',
						productId: responseId,
						success: resData.success
					}, WIDGET_ORIGIN );
				}
				if ( typeof jQuery !== 'undefined' ) {
					jQuery( document.body ).trigger( 'wc_fragment_refresh' );
				}
			} )
			.catch( function () {
				var iframe = document.getElementById( 'kwiro-chat-widget' );
				if ( iframe && iframe.contentWindow && WIDGET_ORIGIN ) {
					iframe.contentWindow.postMessage( {
						type: 'kwiro_add_to_cart_result',
						productId: responseId,
						success: false,
						error: 'Network error'
					}, WIDGET_ORIGIN );
				}
			} );
	} );
})();
