/**
 * IndexedDB injection helpers for Playwright tests.
 *
 * These functions execute inside the browser via page.evaluate() — they must be
 * self-contained and cannot close over test-scope variables (only the single
 * argument passed to page.evaluate is available).
 *
 * Standard pattern for using inject_badge_and_template:
 *
 *   await page.goto('/events/{event_id}/badges/{badge_id}/print');
 *   await page.waitForLoadState('domcontentloaded');
 *   await page.evaluate(inject_badge_and_template, { badge, template });
 *   await page.reload();
 *   await page.waitForLoadState('domcontentloaded');
 *
 * Why reload after injection: direct IDB writes bypass Dexie's internal
 * change-notification system, so liveQuery subscribers don't re-fire.
 * Reloading starts the page fresh against the already-populated IDB.
 */

/** Injects a badge and badge_template record into ae_events_db. */
export async function inject_badge_and_template(
    { badge, template }: { badge: object; template: object }
): Promise<void> {
    // Wait for Dexie to have fully initialised ae_events_db with its stores.
    // domcontentloaded fires before Dexie's version migration runs, so the DB
    // may not have the 'badge' / 'badge_template' stores yet when we arrive here.
    await new Promise<void>((resolve, reject) => {
        const poll = () => {
            const req = indexedDB.open('ae_events_db');
            req.onsuccess = () => {
                const db = req.result as IDBDatabase;
                const ready = db.objectStoreNames.contains('badge') &&
                              db.objectStoreNames.contains('badge_template');
                db.close();
                if (ready) resolve();
                else setTimeout(poll, 100);
            };
            req.onerror = () => reject((req as IDBRequest).error);
        };
        poll();
    });

    const db = await new Promise<IDBDatabase>((resolve, reject) => {
        const req = indexedDB.open('ae_events_db');
        req.onsuccess = () => resolve(req.result as IDBDatabase);
        req.onerror   = () => reject((req as IDBRequest).error);
    });
    await new Promise<void>((resolve, reject) => {
        const tx = db.transaction(['badge', 'badge_template'], 'readwrite');
        tx.objectStore('badge').put(badge);
        tx.objectStore('badge_template').put(template);
        tx.oncomplete = () => { db.close(); resolve(); };
        tx.onerror    = () => { db.close(); reject(tx.error); };
    });
}
