/*!
 * parcselect-label-bridge.js
 *
 * JS bridge: relays postMessage events from the parcelselector.com iframe
 * (sitting in the WP admin order edit screen) to WordPress AJAX endpoints,
 * and posts results back to the iframe.
 *
 * Refactored 2026-05-15 from inline wp_add_inline_script (FIX #10):
 *   - was hardcoded inside class-ps-label-embed.php :: bridge_js()
 *   - version was pinned at 4.0.6 regardless of plugin version
 *   - F12 PS_LOG telemetry could not introspect inline source
 *
 * All dynamic values arrive via wp_localize_script as window.parcselectLabelBridgeCfg:
 *   parcselectLabelBridgeCfg.iframeOrigin  string  origin of the embedded iframe
 *   parcselectLabelBridgeCfg.nonce         string  WP nonce for parcselect_label_consent
 *   parcselectLabelBridgeCfg.version       string  PARCSELECT_VERSION (drives console banner)
 *   parcselectLabelBridgeCfg.ajaxUrl       string  fallback when window.ajaxurl is missing
 */
(function () {
	'use strict';

	var CFG = window.parcselectLabelBridgeCfg || {};
	var IFRAME_ORIGIN = CFG.iframeOrigin || '';
	var NONCE = CFG.nonce || '';
	var VERSION = CFG.version || '?';
	var AJAX_URL = (typeof window.ajaxurl !== 'undefined' && window.ajaxurl) || CFG.ajaxUrl || '/wp-admin/admin-ajax.php';

	try { window.PS_LOG && window.PS_LOG('BRIDGE_INIT', VERSION, CFG); } catch (e) {}
	try { console.log('[PS-BRIDGE] v' + VERSION + ' init — listening for postMessage from', IFRAME_ORIGIN); } catch (e) {}

	if (!IFRAME_ORIGIN) {
		try { console.warn('[PS-BRIDGE] no iframeOrigin in parcselectLabelBridgeCfg — bridge inert'); } catch (e) {}
		return;
	}

	function esc(s) {
		return String(s || '')
			.replace(/&/g, '&amp;')
			.replace(/</g, '&lt;')
			.replace(/>/g, '&gt;')
			.replace(/"/g, '&quot;');
	}

	function postBack(action, payload) {
		// Iframe ID: accept both 'ps-label-iframe' (current) and
		// 'parcselect-label-iframe' (legacy / other render paths).
		var iframe = document.getElementById('ps-label-iframe') || document.getElementById('parcselect-label-iframe');
		try { console.log('[PS-BRIDGE] postBack to iframe:', action, payload, 'iframeFound:', !!iframe); } catch (e) {}
		if (iframe && iframe.contentWindow) {
			iframe.contentWindow.postMessage({ type: action, data: payload }, IFRAME_ORIGIN);
		}
	}

	window.addEventListener('message', function (e) {
		try {
			if (e.origin === IFRAME_ORIGIN) {
				console.log('[PS-BRIDGE] MSG IN from iframe:', (e.data && e.data.type) || '(no type)', e.data);
			}
		} catch (err) {}
		if (e.origin !== IFRAME_ORIGIN) { return; }
		if (!e.data || typeof e.data !== 'object') { return; }

		// Normalise type: iframe sends `ps_label_*` OR `parcselect_label_*`.
		// Accept both so bridge matches regardless of which prefix VPS uses.
		var _t = String(e.data.type || '');
		var _norm = _t.replace(/^ps_label_/, 'parcselect_label_');

		// --- Consent step ---
		if (_norm === 'parcselect_label_consent') {
			try { console.log('[PS-BRIDGE] consent received, calling AJAX. order_id=', e.data.order_id, 'step=', e.data.step); } catch (err) {}
			var fd = new FormData();
			fd.append('action', 'parcselect_label_accept_consent');
			fd.append('nonce', NONCE);
			fd.append('order_id', e.data.order_id || 0);
			fd.append('step', e.data.step || '');
			fetch(AJAX_URL, { method: 'POST', body: fd, credentials: 'same-origin' })
				.then(function (r) {
					try { console.log('[PS-BRIDGE] AJAX consent HTTP', r.status); } catch (err) {}
					return r.json();
				})
				.then(function (j) {
					try { console.log('[PS-BRIDGE] AJAX consent response:', j); } catch (err) {}
					// Send response back under BOTH names — iframe may listen on either.
					postBack('parcselect_label_consent_result', { success: !!j.success, step: e.data.step, error: j.data && j.data.message });
					postBack('parcselect_label_consent_result', { success: !!j.success, step: e.data.step, error: j.data && j.data.message });
				})
				.catch(function (err) {
					try { console.error('[PS-BRIDGE] AJAX consent FAILED:', err); } catch (e2) {}
					postBack('parcselect_label_consent_result', { success: false, step: e.data.step, error: err.message });
					postBack('parcselect_label_consent_result', { success: false, step: e.data.step, error: err.message });
				});
		}

		// --- Sender save ---
		if (_norm === 'parcselect_label_save_sender') {
			var fd2 = new FormData();
			fd2.append('action', 'parcselect_label_save_sender');
			fd2.append('nonce', NONCE);
			fd2.append('order_id', e.data.order_id || 0);
			var keys = ['sender_name', 'sender_company', 'sender_street', 'sender_city', 'sender_postcode', 'sender_phone', 'sender_email'];
			for (var i = 0; i < keys.length; i++) {
				fd2.append(keys[i], (e.data.data && e.data.data[keys[i]]) || '');
			}
			fetch(AJAX_URL, { method: 'POST', body: fd2, credentials: 'same-origin' })
				.then(function (r) { return r.json(); })
				.then(function (j) {
					postBack('parcselect_label_sender_result', { success: !!j.success, error: j.data && j.data.message, fields: j.data && j.data.fields });
					postBack('parcselect_label_sender_result', { success: !!j.success, error: j.data && j.data.message, fields: j.data && j.data.fields });
				})
				.catch(function (err) {
					postBack('parcselect_label_sender_result', { success: false, error: err.message });
					postBack('parcselect_label_sender_result', { success: false, error: err.message });
				});
		}

		// --- v4.0.7 ZERO-LEAK: completed event IGNORED ---
		// The `parcselect_label_completed` / `ps_label_completed` postMessage
		// handler was removed. Iframe on VPS (with shared SOL wallet where X21
		// cannot reliably scope TXs per shop) was able to push
		// {tracking_number, label_url, txid} directly into the admin DOM via
		// postMessage without any HMAC, nonce, or installation_id check.
		// Legitimate sources of "label completed" UI state are now:
		//   1. Webhook /ps/v1/label-callback (HMAC + installation_id match)
		//   2. Admin click on "Sprawdź płatność" button in metabox
		if (_norm === 'parcselect_label_completed') {
			try { console.warn('[PS-BRIDGE] IGNORED parcselect_label_completed from iframe — DOM insert disabled in v4.0.7 (anti-leak). Use webhook or admin recheck.', e.data); } catch (err) {}
		}

		// --- v4.0.13 FAZA 2 — size selection → plugin-native Stage 4 ---
		// Iframe emits ps_label_size_selected when user clicks A/B/C.
		// Plugin calls create_session AJAX (unique dust lamports), reloads
		// page. Plugin-native Stage 4 (QR + polling) takes over before VPS
		// iframe can auto-render foreign PAYMENT CONFIRMED.
		if (_norm === 'parcselect_label_size_selected') {
			try { console.log('[PS-BRIDGE] v4.0.13 size_selected intercepted:', e.data); } catch (err) {}
			var _d = e.data.data || e.data;
			var sz = String(_d.size || '').toUpperCase();
			if (['A', 'B', 'C'].indexOf(sz) === -1) { return; }
			var wt = parseFloat(_d.weight || 1.0);
			var oid = parseInt(_d.order_id || 0, 10);
			if (!oid) {
				try { console.error('[PS-BRIDGE] no order_id in size_selected'); } catch (e2) {}
				return;
			}
			// DEV-5 2026-05-16: debounce — iframe potrafi wyemitowac
			// size_selected wielokrotnie (re-render / podwojny klik); bez
			// locka szlo N rownoleglych create_session => podwojna sesja.
			if (window.__PSLB_CS_INFLIGHT) {
				try { console.warn('[PS-BRIDGE] create_session juz w toku - duplikat zignorowany'); } catch (e2) {}
				return;
			}
			window.__PSLB_CS_INFLIGHT = true;
			var fd3 = new FormData();
			fd3.append('action', 'parcselect_label_create_session');
			fd3.append('nonce', NONCE);
			fd3.append('order_id', oid);
			fd3.append('size', sz);
			fd3.append('weight', wt);
			fetch(AJAX_URL, { method: 'POST', body: fd3, credentials: 'same-origin' })
				.then(function (r) {
					// DEV-5 2026-05-16: serwer moze oddac HTML (strona bledu /
					// timeout) zamiast JSON -> r.json() rzucalo "Unexpected token '<'".
					return r.text().then(function (t) {
						try { return JSON.parse(t); }
						catch (_e) { throw new Error('serwer zwrocil HTTP ' + r.status + ' (nie JSON)'); }
					});
				})
				.then(function (j) {
					try { console.log('[PS-BRIDGE] create_session:', j); } catch (err) {}
					if (j && j.success) { window.location.reload(); }
					else { window.__PSLB_CS_INFLIGHT = false; }
				})
				.catch(function (err) {
					window.__PSLB_CS_INFLIGHT = false;
					try { console.error('[PS-BRIDGE] create_session NET:', err); } catch (e2) {}
				});
		}
	});

	// === v4.0.4 ZERO-LEAK ELIMINATION (root cause kill) ===
	// Polling JS that hit ceb/v1/order-status every 10 seconds and POSTed
	// the response straight to ajax_save_tracking has been REMOVED. With a
	// shared SOL wallet, the VPS endpoint cannot reliably scope responses
	// to a single shop, and the front-end had no proof that incoming data
	// belonged to THIS install. Source of truth from now on: webhook
	// /ps/v1/label-callback (HMAC + installation_id verified). If webhook
	// does not arrive, admin uses the explicit "Sprawdź płatność" button
	// on the metabox. No automatic front-end polling permitted.
})();
