// apps/client/test/e2e/cli-08-anim.e2e.test.ts
// [int->REQ-CLI-08]
//
// Plan 06.1-07 Task 1 — GREEN refinement of the 06.1-03 RED skeleton. Asserts
// the D-41 / D-42 sim-tick anim-rate model against the Wave 2/3 wire-up
// (Plan 06.1-04 fractional SpriteStateMachine + PlayerRenderer sim-tick lock).
//
// Pattern: adapts sprite-state.e2e.test.ts lines 16-46 (frame-string sample
// via __rebno.localFrame after key hold; PlayerRenderer.onSimulationTickLocal
// writes the frameKey under DEV/test mode only).
//
// Cadence model (per D6.1-06 canonical formula `image_speed = curspeed / 10`):
//   FRAMES_PER_TICK_AT_RUN = RUN_SPEED / 10 = 5 / 10 = 0.5
//   Run cycle has 6 frames (NaviRunD/R/U/L sprite frame_count, per extracted
//   sprite meta.json).
//   Over 1000 ms = 30 sim ticks × 0.5 frames/tick = 15 frame advances.
//   Across the 6-frame cycle, expect ≥ 3 distinct frame keys observed across
//   20 samples (50 ms apart). Three is the minimum that distinguishes a
//   genuinely-animating sprite from one stuck on a single frame.
//
// Frame-key regex (matches the atlas naming convention emitted by
// SpriteStateMachine.RUN_SPRITE_ID + padPhase): `00NN-NaviRun[DRUL][LR]?_NNN`.
// E.g. `0028-NaviRunR_003`, `0037-NaviRunDR_005`.

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

test('CLI-08 anim — local sprite advances ≥3 distinct frames during 1s KeyD hold (Wave 4 GREEN gate)', async ({
  page,
  accountA,
  inviteSuffix,
}) => {
  await loginAs(page, accountA, inviteSuffix);
  await waitForGameReady(page);

  // 1. Focus canvas so KeyD reaches Phaser input layer.
  await page.locator('canvas[data-game-ready="true"]').click();

  // 2. Hold KeyD and sample __rebno.localFrame every 50 ms for 1000 ms
  //    (20 samples). Distinct frame keys >= 3 proves sim-tick anim advances.
  await page.keyboard.down('KeyD');

  const samples: string[] = [];
  for (let i = 0; i < 20; i++) {
    await page.waitForTimeout(50);
    const localFrame = await page.evaluate(
      () =>
        (
          window as unknown as {
            __rebno?: { localFrame?: string };
          }
        ).__rebno?.localFrame ?? null,
    );
    if (typeof localFrame === 'string' && localFrame.length > 0) {
      samples.push(localFrame);
    }
  }
  await page.keyboard.up('KeyD');

  // 3. Distinct frame keys observed during the hold window.
  const unique = new Set(samples);
  expect(
    unique.size,
    `Expected ≥3 distinct frame keys during 1s hold; observed ${unique.size} (samples=${samples.join(',')})`,
  ).toBeGreaterThanOrEqual(3);

  // 4. Each observed frame must match a NaviRun* pattern (sanity).
  for (const f of unique) {
    expect(f).toMatch(/^00\d{2}-NaviRun[DRUL][LR]?_\d{3}$/);
  }
});
