<?php
/**
 * Load the iframe personalisation JavaScript code.
 *
 * @package Fast-Events/Helper/Template/Js/Personalise-Iframe
 *
 * @var array $tickets     Array of tickets.
 * @var bool  $is_uid      Is this via the order uid or a list of ticket ids?
 *
 * @since 2.1.0
 * @since 2.5.0 Improved error handling and UI behavior.
 */

defined( 'ABSPATH' ) || exit;

global $wp_query;

$fe_localize = array(
	'home'  => esc_url_raw( home_url() ),
	'root'  => esc_url_raw( rest_url( '/fast-events/v1/' ) ),
	'nonce' => wp_create_nonce( 'wp_rest' ),
);
if ( $is_uid ) {
	$fe_localize['uid']           = $wp_query->query_vars['redirect_uid'];
	$fe_localize['ticket_share']  = __( 'Share {} ticket', 'fast-events' );
	$fe_localize['tickets_share'] = __( 'Share {} tickets', 'fast-events' );
}

?>

<script>
	<?php if ( false ) { ?>
	/**
	 * JavaScript functions for the personalisation dialogue.
	 *
	 * Global type definition.
	 * @typedef {Object}  fePersData       - Array of order and ticket data.
	 * @property {Object} order_input      - Order input data (fields, tickets, invoice)
	 * @property {Object} invoice          - Invoice data
	 * @property {String} invoice_nonce    - Nonce for invoice REST requests
	 * @property {String} share_nonce      - Nonce for share REST requests
	 * @property {String} order_id         - Unique order id
	 * @property {String} no_fields        - If true, there are no personalisation fields
	 *
	 * @typedef {Object}  feLocalize       - Array of localisation strings.
	 * @property {String} uid              - Order uid (Only visible if called via uid)
	 * @property {String} download_invoice - Order uid (Only visible if called via uid)
	 * @property {String} invoice          - Invoice
	 * @property {String} order            - order
	 */

	<?php } ?>
	(function () {

		const FE_TIMEOUT = 10000;

		const feLocalize = <?php echo wp_json_encode( $fe_localize ); ?>;
		let fePersData = <?php echo wp_json_encode( $tickets ); ?>;

		const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]')
		const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl))

		<?php if ( $is_uid ) { ?>
		// The number of tickets to share for personalisation or download
		let numTicketsShare = 0;

		// The set of ticket ids that are share
		let ticketKeys = new Set();
		<?php } ?>

		// Generate qrcodes
		function generateQrcodes() {
			document.querySelectorAll('div[id^=fe-qrcode]').forEach(qrcode => {
				const key = qrcode.id.split(/[\s-]+/).pop();
				new QRCode(qrcode, fePersData['data'][key]['qrcode']);
				qrcode.classList.remove('d-none');
			});
		}

		// Show the error message and let it disappear after 3 seconds
		function showError(domObj, error) {
			domObj.innerText = error;
			domObj.classList.remove('d-none');
			setTimeout(function () {
				domObj.innerText = '';
				domObj.classList.add('d-none');
			}, 3000);
		}

		/**
		 * Toggles UI state while a fetch is pending.
		 *
		 * @param {HTMLButtonElement}  feButton
		 * @param {boolean}            active  true → show spinner, hide cursor, disable button
		 */
		function setLoadingState(feButton, active) {
			document.body.style.cursor = active ? 'wait' : 'default';
			feButton.style.cursor = active ? 'wait' : 'default';
			feButton.disabled = active;
			feButton.style.opacity = active ? '0.6' : '1';
		}

		<?php if ( ! isset( $tickets['download'] ) ) { ?>
		// Create personalised data html.
		function showPersonalisedData(fields, targetKey) {
			let html = '<hr class="border-3 border-secondary m-1" />';
			for (const key in fields) {
				html += '<div class="row"><div class="form-floating"  style="margin-bottom: -0.75rem !important;">';
				html += '<input type="text" readonly class="form-control-plaintext text-truncate" value="' +fields[key] + '">';
				html += '<label>' + key + '</label></div>';
			}
			document.getElementById('ticket-pers-data-' + targetKey).innerHTML = html;
			document.getElementById('ticket-personalise-' + targetKey).classList.add('d-none');
			fePersData['data'][targetKey]['personalised'] = true;
			fePersData['data'][targetKey]['locked'] = true;
			fePersData['data'][targetKey]['data'] = fields;
			if (!fePersData['data'].filter(e => e['locked'] === false).length) {
				window.parent.location.reload();
			}
		}
		<?php } ?>

		<?php if ( $is_uid ) { ?>
		// Increase or decrease the number of tickets to share and tell the parent to display it
		function shareCounter(cnt, key) {
			if (cnt === 1) {
				ticketKeys.add(key);
			} else {
				ticketKeys.delete(key);
			}
			numTicketsShare += cnt;
			if (numTicketsShare <= 0) {
				numTicketsShare = 0;
			}
			let msg = {  // Inform parent.
				type: 4,
				text: numTicketsShare === 1 ? feLocalize['ticket_share'] : feLocalize['tickets_share'],
				count: numTicketsShare,
			}
			window.parentIFrame.sendMessage(JSON.stringify(msg))
		}

		// The parent received a share click => process it in the iFrame.
		window.iFrameResizer = {
			onMessage: function (messageData) {
				try {
					if (ticketKeys.size === 0) {
						alert('<?php esc_html_e( 'No tickets selected', 'fast-events' ); ?>');
						return;
					}
					document.body.style.cursor = 'wait';
					let urlPart = 'personalise/share/';
					const formData = new FormData();
					formData.append('ids', fePersData['data'].map(el => el['id']).join('-'));
					formData.append('keys', Array.from(ticketKeys).join('-'));
					if (fePersData.hasOwnProperty('download')) {
						formData.append('hashes', fePersData['data'].map(el => el['hash']).join('-'));
						urlPart += 'download/';
					} else {
						formData.append('nonces', fePersData['data'].map(el => el['nonce']).join('-'));
					}
					fetch(feLocalize.root + urlPart + fePersData.share_nonce + '/' + feLocalize.uid, {
						method: 'POST',
						signal: AbortSignal.timeout(FE_TIMEOUT),
						body: formData,
						headers: {
							'X-WP-Nonce': feLocalize.nonce,
						}
					})
						.then((response) => {
							return response.json()
						}).then((data) => {
						if (data.hasOwnProperty('link')) {
							ticketKeys.forEach(key => {
								const uncheck = document.getElementById('ticket-uncheck-' + key);
								const checked = document.getElementById('ticket-checked-' + key);
								const badge = document.getElementById('ticket-badge-' + key);
								const badgeChecked = document.getElementById('ticket-badge-checked-' + key);
								checked.classList.add('d-none');
								uncheck.classList.remove('d-none');
								badge.classList.remove('d-none');
								badgeChecked.classList.remove('d-none');
							});
							ticketKeys.clear();
							numTicketsShare = 0;
							let msg = {
								type: 5,
								link: data['link'],
								label: '<?php esc_html_e( 'Use the following link', 'fast-events' ); ?>',
								cancel: '<?php esc_html_e( 'Cancel', 'fast-events' ); ?>',
								copy: '<?php esc_html_e( 'Copy link', 'fast-events' ); ?>',
							}
							window.parentIFrame.sendMessage(JSON.stringify(msg))
						} else {
							alert(data.message);
						}
					});

				} catch (e) {
					alert('<?php esc_html_e( 'Fatal error: ', 'fast-events' ); ?>' + e.message);
				} finally {
					document.body.style.cursor = 'default';
				}
			}
		}

		// Listen for unchecked button clicks.
		const btnsCheck = document.querySelectorAll('button[id^=ticket-uncheck]');
		btnsCheck.forEach(btn => {
			btn.onclick = async function (ev) {
				ev.currentTarget.classList.add('d-none');
				ev.currentTarget.nextElementSibling.classList.remove('d-none')
				shareCounter(1, ev.currentTarget.id.split(/[\s-]+/).pop());
			}
		});


		// Listen for checked button clicks.
		const btnsChecked = document.querySelectorAll('button[id^=ticket-checked]');
		btnsChecked.forEach(btn => {
			btn.onclick = async function (ev) {
				ev.currentTarget.classList.add('d-none');
				ev.currentTarget.previousElementSibling.classList.remove('d-none')
				shareCounter(-1, ev.currentTarget.id.split(/[\s-]+/).pop());
			}
		});


		// Listen for invoice button if button is pressed. Can only be used by the orderer and not by share receivers
		const feInvoiceButton = document.getElementById('fe-pers-invoice-button');
		if (feInvoiceButton) {
			feInvoiceButton.onclick = async function (ev) {
				ev.preventDefault();
				if (!fePersData.order_input.invoice.hasOwnProperty('locked')) { // Save the data
					const alertMsg = document.getElementById('fe-pers-invoice-alert');
					try {
						setLoadingState(this, true);
						let response = await fetch(feLocalize.root + 'personalise/invoice/' + fePersData.invoice_nonce + '/' + feLocalize.uid, {
							method: 'POST',
							signal: AbortSignal.timeout(FE_TIMEOUT),
							body: new FormData(document.getElementById('fe-pers-invoice')),
							headers: {
								'X-WP-Nonce': feLocalize.nonce,
							}
						})
						const json = await response.json();
						if (response.ok) {
							// Make checkbox invisible.
							const feInvoiceLocked = document.getElementById('invoice-locked');
							if (feInvoiceLocked) {
								feInvoiceLocked.style.display = 'none';
							}
							// Disable all input elements.
							const fePersInvoice = document.getElementById('fe-pers-invoice');
							if (fePersInvoice) {
								const elements = fePersInvoice.elements;
								for (let i = 0, len = elements.length; i < len; ++i) {
									elements[i].disabled = true;
								}
							}
							feInvoiceButton.innerText = '<?php esc_html_e( 'Download invoice', 'fast-events' ); ?>';
							fePersData.order_input.invoice.locked = true;
						} else {
							showError(alertMsg, json.message);
						}
					} catch (e) {
						showError(alertMsg, '<?php esc_html_e( 'Fatal error: ', 'fast-events' ); ?>' + e.message);
					} finally {
						setLoadingState(this, false);
					}
				} else { // Download the invoice.
					let msg = {
						type: 1,
						url:  feLocalize.root + 'invoice/' + feLocalize.uid,
					}
					window.parentIFrame.sendMessage(JSON.stringify(msg))
				}
			}
		}
		<?php } ?>

		<?php if ( ! isset( $tickets['download'] ) ) { ?>
		// Listen for edit (personalise) button clicks.
		const btnsEdit = document.querySelectorAll('button[id^=ticket-personalise]');
		btnsEdit.forEach(btn => {
			btn.onclick = async function (ev) {
				const key = ev.currentTarget.id.split(/[\s-]+/).pop();
				const alertMsg = document.getElementById('ticket-pers-input-alert-' + key);
				try {
					setLoadingState(this, true);
					let response = await fetch(feLocalize.root + 'personalise/' + fePersData['data'][key]['id'] + '/' + fePersData['data'][key]['nonce'] + '/' + fePersData['data'][key]['hash'], {
						method: 'GET',
						signal: AbortSignal.timeout(FE_TIMEOUT),
						headers: {
							'X-WP-Nonce': feLocalize.nonce,
						}
					})
					const json = await response.json();
					if (response.ok) {
						if (json.locked === true) {
							showPersonalisedData(json.data, key);
							showError(alertMsg, '<?php esc_html_e( 'Ticket already personalised by someone else', 'fast-events' ); ?>');
							return;
						}
						if (json.no_fields === true) {
							document.getElementById('ticket-personalise-' + key).classList.add('d-none');
							showError(alertMsg, '<?php esc_html_e( 'This ticket has no personalisation fields', 'fast-events' ); ?>');
							return;
						}
						document.getElementById('ticket-pers-input-' + key).classList.remove('d-none');
						document.getElementById('ticket-pers-input-fields-' + key).innerHTML = json.html;
					} else {
						showError(alertMsg, json.message);
					}
				} catch (e) {
					showError(alertMsg, '<?php esc_html_e( 'Fatal error: ', 'fast-events' ); ?>' + e.message);
				} finally {
					setLoadingState(this, false);
				}
			}
		});

		// Listen for closing the ticket personalisation dialogue.
		const btnsEditClose = document.querySelectorAll('button[id^=ticket-pers-input-close]');
		btnsEditClose.forEach(btn => {
			btn.onclick = async function (ev) {
				const key = ev.currentTarget.id.split(/[\s-]+/).pop();
				const alertMsg = document.getElementById('ticket-pers-input-alert-' + key);
				alertMsg.innerText = '';
				alertMsg.classList.add('d-none');
				document.getElementById('ticket-pers-input-' + key).classList.add('d-none');
			}
		});

		// Listen for save personalisation data.
		const btnsEditSave = document.querySelectorAll('button[id^=ticket-pers-input-save]');
		btnsEditSave.forEach(btn => {
			btn.onclick = async function (ev) {
				const key = ev.currentTarget.id.split(/[\s-]+/).pop();
				const alertMsg = document.getElementById('ticket-pers-input-alert-' + key);
				try {
					setLoadingState(this, true);
					let response = await fetch(feLocalize.root + 'personalise/' + fePersData['data'][key]['id'] + '/' + fePersData['data'][key]['nonce'] + '/' + fePersData['data'][key]['hash'], {
						method: 'POST',
						signal: AbortSignal.timeout(FE_TIMEOUT),
						body: new FormData(document.getElementById('ticket-pers-input-form-' + key)),
						headers: {
							'X-WP-Nonce': feLocalize.nonce,
						}
					})
					const json = await response.json();
					if (response.ok) {
						document.getElementById('ticket-pers-input-' + key).classList.add('d-none');
						showPersonalisedData(json.data, key);
					} else {
						showError(alertMsg, json.message);
					}
				} catch (e) {
					showError(alertMsg, '<?php esc_html_e( 'Fatal error: ', 'fast-events' ); ?>' + e.message);
				} finally {
					setLoadingState(this, false);
				}
			}
		});
		<?php } ?>

		// Listen for download individual ticket.
		const btnsDownload = document.querySelectorAll('button[id^=ticket-download]');
		btnsDownload.forEach(btn => {
			btn.onclick = async function (ev) {
				const key = ev.currentTarget.id.split(/[\s-]+/).pop();
				let msg = {
					type: 2,
					url:  feLocalize.root + 'tickets/' + fePersData['data'][key]['id'] + '/' + fePersData['data'][key]['hash'],
				}
				window.parentIFrame.sendMessage(JSON.stringify(msg))
			}
		});

		// Download all tickets.
		const ticketsDownload = document.getElementById('tickets-download');
		ticketsDownload.onclick = async function () {
			let msg = {
				type: 1,
				url:  fePersData['download'],
			}
			window.parentIFrame.sendMessage(JSON.stringify(msg))
		}

		// Check if qrcodes should be generated.
		if (fePersData.hasOwnProperty('download')) {
			setTimeout(function () {
				generateQrcodes();
			}, 200);
		}

	})();
</script>
<?php
