import "fake-indexeddb/auto";
import { beforeEach, describe, expect, it } from "vitest";
import type { Progress, Settings } from "../types";
import { getProgress, getSettings, openDB, saveProgress, saveSettings } from "./db";

let testCounter = 0;

describe("IndexedDB wrapper", () => {
	let db: IDBDatabase;

	beforeEach(async () => {
		// Each test gets a fresh database by using a unique name
		testCounter++;
		db = await openDB(`zauberwald-test-${testCounter}`);
	});

	it("openDB resolves to an IDBDatabase with 5 object store names", () => {
		const storeNames = Array.from(db.objectStoreNames);
		expect(storeNames).toHaveLength(5);
		expect(storeNames).toContain("progress");
		expect(storeNames).toContain("companionAssets");
		expect(storeNames).toContain("styleReference");
		expect(storeNames).toContain("forestElements");
		expect(storeNames).toContain("settings");
	});

	it("saveProgress then getProgress returns same data", async () => {
		const progress: Progress = {
			id: 1,
			currentLevel: 1,
			completedLevels: [],
			totalSessions: 0,
			sessionDates: [],
			selectedCharacter: "fee",
			selectedLayout: "de",
			totalCorrect: 0,
			totalErrors: 0,
			errorKeyCounts: {},
			lastPlayedLevels: [],
			currentForestPage: 0,
		};
		await saveProgress(db, progress);
		const result = await getProgress(db);
		expect(result).toEqual(progress);
	});

	it("saveSettings then getSettings returns same data", async () => {
		const settings: Settings = {
			id: 1,
			audioEnabled: true,
			speechEnabled: false,
			apiKey: "test-key",
			apiCallsToday: { text: 0, image: 0 },
			lastApiCallDate: "2026-03-29",
		};
		await saveSettings(db, settings);
		const result = await getSettings(db);
		expect(result).toEqual(settings);
	});

	it("getProgress on empty DB returns null", async () => {
		const result = await getProgress(db);
		expect(result).toBeNull();
	});

	it("getSettings on empty DB returns null", async () => {
		const result = await getSettings(db);
		expect(result).toBeNull();
	});
});
