/**
 * Event listener for install event
 */
self.addEventListener('install', () => {
	// Call to ensure service worker is correctly updated
	self.skipWaiting();
});

/**
 * Event listener for activate event
 */
self.addEventListener('activate', event => {
	event.waitUntil(self.clients.claim());
});

/**
 * Event listener for push event
 */
self.addEventListener('push', event => {
	if (typeof event.data === 'undefined') {
		return;
	}

	let itemId = 0;
	let typeId = 0;
	let userId = 0;
	let notificationVersion = 0;
	let pushToken = '';
	try {
		const notificationData = event.data.json();
		itemId = notificationData.item_id;
		typeId = notificationData.type_id;
		userId = notificationData.user_id;
		notificationVersion = parseInt(notificationData.version, 10);
		pushToken = notificationData.token;
	} catch {
		event.waitUntil(self.registration.showNotification(event.data.text()));
		return;
	}

	event.waitUntil((async() => {
		const getNotificationUrl = '{{ U_WEBPUSH_GET_NOTIFICATION }}';
		const assetsVersion = parseInt('{{ ASSETS_VERSION }}', 10);

		// Force update if versions differ
		if (assetsVersion !== notificationVersion) {
			await self.registration.update();
		}

		const formData = new FormData();
		formData.append('item_id', itemId.toString(10));
		formData.append('type_id', typeId.toString(10));
		formData.append('user_id', userId.toString(10));
		formData.append('token', pushToken);

		try {
			const response = await fetch(getNotificationUrl, {
				method: 'POST',
				headers: {
					'X-Requested-With': 'XMLHttpRequest',
				},
				body: formData,
			});

			const responseData = await response.json();

			const responseBody = responseData.title + '\n' + responseData.text;
			const options = {
				body: responseBody,
				data: responseData,
				icon: responseData.avatar.src,
			};

			await self.registration.showNotification(responseData.heading, options);
		} catch (e) {
			console.error('Push error:', e);
		}
	})());
});

/**
 * Event listener for notification click
 */
self.addEventListener('notificationclick', event => {
	event.notification.close();
	if (typeof event.notification.data !== 'undefined') {
		event.waitUntil(self.clients.openWindow(event.notification.data.url));
	}
});
