const DB_NAME = 'classeo-appreciations';
const DB_VERSION = 1;
const STORE_NAME = 'pending-appreciations';

interface PendingAppreciation {
	evaluationId: string;
	studentId: string;
	appreciation: string | null;
	savedAt: number;
}

function openDb(): Promise<IDBDatabase> {
	return new Promise((resolve, reject) => {
		const request = indexedDB.open(DB_NAME, DB_VERSION);

		request.onupgradeneeded = () => {
			const db = request.result;
			if (!db.objectStoreNames.contains(STORE_NAME)) {
				const store = db.createObjectStore(STORE_NAME, {
					keyPath: ['evaluationId', 'studentId'],
				});
				store.createIndex('byEvaluation', 'evaluationId', { unique: false });
			}
		};

		request.onsuccess = () => resolve(request.result);
		request.onerror = () => reject(request.error);
	});
}

export async function savePendingAppreciation(appreciation: PendingAppreciation): Promise<void> {
	const db = await openDb();
	return new Promise((resolve, reject) => {
		const tx = db.transaction(STORE_NAME, 'readwrite');
		tx.objectStore(STORE_NAME).put(appreciation);
		tx.oncomplete = () => resolve();
		tx.onerror = () => reject(tx.error);
	});
}

export async function getPendingAppreciations(evaluationId: string): Promise<PendingAppreciation[]> {
	const db = await openDb();
	return new Promise((resolve, reject) => {
		const tx = db.transaction(STORE_NAME, 'readonly');
		const index = tx.objectStore(STORE_NAME).index('byEvaluation');
		const request = index.getAll(evaluationId);
		request.onsuccess = () => resolve(request.result as PendingAppreciation[]);
		request.onerror = () => reject(request.error);
	});
}

export async function clearPendingAppreciations(evaluationId: string): Promise<void> {
	const db = await openDb();
	const pending = await getPendingAppreciations(evaluationId);
	return new Promise((resolve, reject) => {
		const tx = db.transaction(STORE_NAME, 'readwrite');
		const store = tx.objectStore(STORE_NAME);
		for (const item of pending) {
			store.delete([item.evaluationId, item.studentId]);
		}
		tx.oncomplete = () => resolve();
		tx.onerror = () => reject(tx.error);
	});
}
