import { test, expect } from '@playwright/test';
import { ae_app_local_data_defaults } from './_helpers/ae_defaults';
import { testing_event_id, testing_account_id } from './_helpers/env';

const demo_event = testing_event_id;

test.describe('Cold-start: Event Settings (IndexedDB empty)', () => {
  test.beforeEach(async ({ page }) => {
    page.on('pageerror', (err) => console.error(`BROWSER ERROR: ${err.message}`));
    page.on('console', (msg) => {
      if (msg.type() === 'error' || msg.type() === 'warning')
        console.error(`BROWSER [${msg.type().toUpperCase()}]: ${msg.text()}`);
    });

    // Provide app localStorage before any scripts run
    await page.addInitScript(
      ({ defaults, event_id, account_id }) => {
        const testData = {
          ...defaults,
          account_id: account_id,
          // Administrator implies lower-level access flags are true;
          // Manager and Super accesses are explicitly set per test requirements.
          administrator_access: true,
          trusted_access: true,
          authenticated_access: true,
          manager_access: false,
          super_access: false,
          edit_mode: true,
          // Ensure the layout/components that bind this prop don't receive undefined
          mod_abstracts_json: {},
          // Provide a test person id so components that expect an authenticated
          // user/person render deterministically in tests
          person_id: 'HMQRNPIXQMK', // Per README test data
          user: { id: 'HMQRNPIXQMK' }, // Per README test data
          mod: { ...defaults.mod, events: { ...defaults.mod.events, event_id: event_id } }
        };
        window.localStorage.setItem('ae_loc', JSON.stringify(testData));
      },
      { defaults: ae_app_local_data_defaults, event_id: demo_event, account_id: testing_account_id }
    );

    // Navigate to the application's origin so the page context is allowed
    // to access the IndexedDB API, then delete known Dexie DBs to simulate
    // a cold start. We wrap deleteDatabase in Promises to wait for completion.
    await page.goto('/');
    await page.evaluate(() => {
      const dbs = [
        'ae_events_db',
        'ae_journals_db',
        'ae_posts_db',
        'ae_archives_db',
        'ae_core_db',
        'ae_sponsorships_db'
      ];
      return Promise.all(
        dbs.map((name) =>
          new Promise((resolve) => {
            try {
              const req = indexedDB.deleteDatabase(name);
              req.onsuccess = () => resolve(true);
              req.onerror = () => resolve(false);
              req.onblocked = () => resolve(false);
            } catch (e) {
              // If deleteDatabase throws, resolve to avoid hanging the test
              resolve(false);
            }
          })
        )
      );
    });

    // Seed IndexedDB with the event record so the page's local liveQuery
    // (which reads from IDB) finds it immediately on mount.
    await page.evaluate(({ demo_event }) => {
      return new Promise<void>((resolve) => {
        try {
          const req = indexedDB.open('ae_events_db', 1);
          req.onupgradeneeded = (ev) => {
            const db = (ev.target as IDBOpenDBRequest).result;
            if (!db.objectStoreNames.contains('event')) {
              db.createObjectStore('event', { keyPath: 'id' });
            }
          };
          req.onsuccess = () => {
            const db = req.result;
            const tx = db.transaction('event', 'readwrite');
            const store = tx.objectStore('event');
            store.put({ id: demo_event, event_id: demo_event, name: 'Cold Start Test Event', cfg_json: {}, mod_pres_mgmt_json: {}, mod_badges_json: {}, mod_abstracts_json: {} });
            tx.oncomplete = () => {
              db.close();
              resolve();
            };
            tx.onerror = () => {
              db.close();
              resolve();
            };
          };
          req.onerror = () => resolve();
        } catch (e) {
          resolve();
        }
      });
    }, { demo_event });

    // Minimal network mock for the event GET used by the settings page
    await page.route('**/v3/**', async (route) => {
      const req = route.request();
      const url = req.url();

            if (url.includes(`/v3/crud/event/${demo_event}`) && req.method() === 'GET') {
        return route.fulfill({
          status: 200,
          contentType: 'application/json',
                body: JSON.stringify({ data: {
            id: demo_event,
            event_id: demo_event,
            name: 'Cold Start Test Event',
            cfg_json: {},
            mod_pres_mgmt_json: {},
            mod_badges_json: {},
            mod_abstracts_json: {}
          } })
        });
      }

      // Default: empty envelope so other calls don't error
      return route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ data: [] }) });
    });

    // (already set above)
  });

  test('renders Event Settings without prior IndexedDB cache', async ({ page }) => {
    await page.goto(`/events/${demo_event}/settings`);

    const add_btn = page.getByRole('button', { name: 'Add New Badge' });
    await expect(add_btn).toBeVisible({ timeout: 10000 });
  });
});
