// apps/client/test/e2e/fixtures.ts
// [int->REQ-CLI-08]
// Plan 06-08 Task 2 — full Playwright two-client harness fixtures.
// Drives the LoginScene DOM form (D-01 DOM-overlay) seeded by plan 06-04
// (`apps/client/public/forms/login.html`) and waits for the GameScene
// `<canvas data-game-ready="true">` anchor emitted by plan 06-07 GameScene.

import { test as base, expect, type Page } from '@playwright/test';

export interface Account {
  username: string;
  password: string;
}

export interface AppFixtures {
  /**
   * The `?invite=...` URL suffix appended to every navigation. Empty when
   * STAGING_INVITE_TOKEN is unset (local server with STAGING_MODE=0).
   */
  inviteSuffix: string;
  /**
   * Two seeded accounts. Defaults are local-dev fallbacks; staging CI sets
   * UAT_ACCOUNT_A/B + UAT_PASSWORD_A/B.
   */
  accountA: Account;
  accountB: Account;
}

export const test = base.extend<AppFixtures>({
  inviteSuffix: async ({}, use) => {
    const tok = process.env.STAGING_INVITE_TOKEN;
    await use(tok ? `?invite=${encodeURIComponent(tok)}` : '');
  },
  accountA: async ({}, use) => {
    await use({
      username: process.env.UAT_ACCOUNT_A ?? 'alice',
      password: process.env.UAT_PASSWORD_A ?? 'alicepass1234',
    });
  },
  accountB: async ({}, use) => {
    await use({
      username: process.env.UAT_ACCOUNT_B ?? 'bob',
      password: process.env.UAT_PASSWORD_B ?? 'bobpass1234',
    });
  },
});

export { expect };

/**
 * Drive the LoginScene DOM form for a single page.
 *
 * Selectors are the canonical surface emitted by `apps/client/public/forms/login.html`
 * (loaded by LoginScene via `this.load.html('login-form', ...)`):
 *   - `#username` / `[name=username]` (autocomplete=username)
 *   - `#password` / `[name=password]` (autocomplete=current-password)
 *   - `button[type=submit]`
 *
 * Navigates to `/${inviteSuffix}` first; the LoginScene mounts the form on
 * scene start. After submit, GameScene transition is signalled by the
 * `<canvas data-game-ready="true">` attribute (set on first state snapshot).
 */
export async function loginAs(
  page: Page,
  account: Account,
  inviteSuffix: string,
): Promise<void> {
  await page.goto(`/${inviteSuffix}`);
  // Login form is part of the Phaser DOMElement scene — wait for the input
  // node to render before attempting to fill.
  await page.waitForSelector('#username', { timeout: 10_000 });
  await page.fill('#username', account.username);
  await page.fill('#password', account.password);
  await page.click('button[type=submit]');
}

/**
 * Wait for GameScene to be ready (canvas data-game-ready="true").
 * Per plan 06-07, GameScene sets this attribute on the first state snapshot
 * (server's onCreate broadcast); seeing it confirms WS connect + room join
 * + initial state apply succeeded end-to-end.
 */
export async function waitForGameReady(page: Page): Promise<void> {
  await expect(page.locator('canvas[data-game-ready="true"]')).toBeVisible({
    timeout: 15_000,
  });
}
