"use strict";

console.log('WORKER')
self.__WB_MANIFEST;

self.addEventListener("push", function (event) {
	console.log('data', event.data.text());
	const { message, callId, createdAt, visitor, dst } = JSON.parse(event.data.text());

	const dbPromise = openDB().then(db => {
		return storeCallData(db, { callId, createdAt, visitor, dst });
	});

	const notificationPromise = registration.showNotification(message, {
		body: '30秒以内に回答してください',
		icon: "/icons/android-chrome-192x192.png",
		data: JSON.stringify({ callId, createdAt, visitor, dst }),
		actions: [
			{ action: 'accept', title: '対応可能' },
			{ action: 'reject', title: '対応不可' }
		]
	});

	event.waitUntil(
		Promise.all([dbPromise, notificationPromise]).catch(error => {
			console.error('Error in one of the push event processes:', error);
		})
	);
});

self.addEventListener("notificationclick", function (event) {
    console.log("notificationclick");
    const data = event?.notification?.data;
    event.notification.close();

    event.waitUntil(
        clients.matchAll({ type: "window", includeUncontrolled: true, userVisibleOnly: true })
            .then(function (clientList) {
                let clientUrl = `/actions?data=${encodeURIComponent(data)}&action=${event.action}`;
                // 既存のウィンドウがある場合
				for (let i = 0; i < clientList.length; i++) {
					let client = clientList[i];
					if ('url' in client && client.url.includes(clientUrl) && 'focus' in client){
						client.navigate(clientUrl);
						return client.focus();
					}	
				}

                // Open a new window with the provided URL
				if (clients.openWindow) {
					clients.openWindow(clientUrl);
				}
            })
    );
});

self.addEventListener('install', function(event) {
	console.log('install')
	self.skipWaiting();
});

self.addEventListener('activate', function(event) {
	console.log('activate')
	clients.claim();
});


// 殆どのブラウザで非対応
self.addEventListener('pushsubscriptionchange', function(event) {
	console.log('pushsubscriptionchange')
	event.waitUntil(
		Promise.all([
			Promise.resolve(event.oldSubscription ? deleteSubscription(event.oldSubscription) : true),
			Promise.resolve(event.newSubscription ? event.newSubscription : subscribePush(registration))
				.then(function(sub) { return saveSubscription(sub) })
		])
	)
})


const dbName = 'pwa-db';
const storeName = 'subscriptions';

function openDB() {
	return new Promise((resolve, reject) => {
		const request = indexedDB.open(dbName, 1);
		request.onupgradeneeded = event => {
			let db = event.target.result;
			db.createObjectStore(storeName, { keyPath: 'id' });
		};
		request.onerror = event => reject(event.target.errorCode);
		request.onsuccess = event => resolve(event.target.result);
	});
}

function storeCallData(db, callData) {
	return new Promise((resolve, reject) => {
	  const transaction = db.transaction([storeName], 'readwrite');
	  const store = transaction.objectStore(storeName);
	  const request = store.put(callData);
	  request.onerror = event => reject(event.target.errorCode);
	  request.onsuccess = event => resolve(event.target.result);
	});
  }

async function subscribePush(registration) {
	try {
		console.log(registration)
		// Make the POST request to the server with the push subscription
		const response = await fetch('/api/mobile', {
			method: 'PATCH',
			headers: { 'Content-Type': 'application/json' },
			body: JSON.stringify({ registration })
		});
		
		if (!response.ok) {
			throw new Error('Failed to subscribe to push service.');
		}
		
		const data = await response.json(); // Expecting the identifier in response
		const db = await openDB();
		await storeIdentifier(db, data.identifier);
		console.log('Identifier stored in IndexedDB:', data.identifier);
	} catch (error) {
		console.error('Error in subscribePush:', error);
	}
}

async function deleteSubscription(oldSubscription) {
	console.log(oldSubscription)

	const response = await fetch('/api/mobile', {
		method: 'DELETE',
		headers: { 'Content-Type': 'application/json' },
		body: JSON.stringify({ oldSubscription })
	});
	
	if (!response.ok) {
		throw new Error('Failed to subscribe to push service.');
	}
}