// apps/client/test/e2e/sprite-state.e2e.test.ts
// [int->REQ-CLI-04] [int->REQ-CLI-07]
// Plan 06-16 D-35 + D-27a — Playwright e2e assertions for sprite-state machine
// and nametag rendering.
//
// D-35: frame state is asserted via window.__rebno.localFrame (set per simulation
// tick by PlayerRenderer.onSimulationTickLocal in dev mode). No canvas pixel
// sampling — deterministic and driver-independent (T-06-16-05 mitigated).
//
// D-27a: nameplate DOM mirror ([data-nameplate]) asserts nametag visibility.

import { test, expect } from './fixtures.js';
import { loginAs, waitForGameReady } from './fixtures.js';

test.describe('sprite-state machine (D-35) + nametag (D-27a)', () => {
  test('player sprite frame switches to Run<R> on rightward movement, back to Stand on stop', async ({
    page,
    accountA,
    inviteSuffix,
  }) => {
    await loginAs(page, accountA, inviteSuffix);
    await waitForGameReady(page);

    // Press right arrow and hold for 500ms
    await page.keyboard.down('ArrowRight');
    await page.waitForTimeout(600);

    // D-35: read frame state from __rebno hook (not canvas pixel sampling)
    const frameWhileRunning = await page.evaluate(
      () => (window as unknown as Record<string, Record<string, string>>).__rebno?.localFrame,
    );

    // Frame key must match Run R pattern: '0028-NaviRunR_NNN'
    expect(frameWhileRunning).toMatch(/^0028-NaviRunR_\d{3}$/);

    // Release right arrow and wait for stop
    await page.keyboard.up('ArrowRight');
    await page.waitForTimeout(300);

    const frameAfterStop = await page.evaluate(
      () => (window as unknown as Record<string, Record<string, string>>).__rebno?.localFrame,
    );

    // Stand R (facing preserved) or Stand D (default) after stop
    expect(frameAfterStop).toMatch(/^(0029-NaviStandR_000|0000-NaviStandD_000)$/);
  });

  test('nameplate DOM mirror is visible for self (count >= 1)', async ({
    page,
    accountA,
    inviteSuffix,
  }) => {
    await loginAs(page, accountA, inviteSuffix);
    await waitForGameReady(page);

    // D-27a: DOM mirror [data-nameplate] must exist for at least self
    const count = await page.locator('[data-nameplate]').count();
    expect(count).toBeGreaterThanOrEqual(1);
  });

  test('nameplate text content matches logged-in username', async ({
    page,
    accountA,
    inviteSuffix,
  }) => {
    await loginAs(page, accountA, inviteSuffix);
    await waitForGameReady(page);

    // The nameplate DOM mirror should contain the logged-in username
    const nameplateEl = page.locator('[data-nameplate]').first();
    await expect(nameplateEl).toBeAttached({ timeout: 5_000 });
    const text = await nameplateEl.textContent();
    // The username is from accountA (default 'alice' or UAT_ACCOUNT_A env)
    expect(text?.trim()).toBeTruthy();
  });
});
