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

interface PendingGrade {
	evaluationId: string;
	studentId: string;
	value: number | null;
	status: string;
	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 savePendingGrade(grade: PendingGrade): Promise<void> {
	const db = await openDb();
	return new Promise((resolve, reject) => {
		const tx = db.transaction(STORE_NAME, 'readwrite');
		tx.objectStore(STORE_NAME).put(grade);
		tx.oncomplete = () => resolve();
		tx.onerror = () => reject(tx.error);
	});
}

export async function savePendingGrades(grades: PendingGrade[]): Promise<void> {
	const db = await openDb();
	return new Promise((resolve, reject) => {
		const tx = db.transaction(STORE_NAME, 'readwrite');
		const store = tx.objectStore(STORE_NAME);
		for (const grade of grades) {
			store.put(grade);
		}
		tx.oncomplete = () => resolve();
		tx.onerror = () => reject(tx.error);
	});
}

export async function getPendingGrades(evaluationId: string): Promise<PendingGrade[]> {
	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 PendingGrade[]);
		request.onerror = () => reject(request.error);
	});
}

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

export async function hasPendingGrades(evaluationId: string): Promise<boolean> {
	const pending = await getPendingGrades(evaluationId);
	return pending.length > 0;
}
