// apps/client/test/e2e/camera-follow.e2e.test.ts
// [int->REQ-CLI-07]
//
// Plan 06-15 Task 3 — D-29 camera-follow mandatory verification (per D-35 hook).
// Asserts that walking the local player toward the room edge causes the Phaser
// camera to pan (cameraScrollX or cameraScrollY changes by at least 8px).
//
// Uses window.__rebno deterministic test hook (D-35, exposed by 06-14 Task 3
// in dev/test mode only) — NOT WebGL canvas-pixel sampling. One screenshot
// artifact per test is fine; pixel-equality is not used for pass/fail.
//
// Threshold choice: 8px is conservative for a 1.5s walk at the BNO movement
// speed derived from Phase 4 server constants. The actual delta observed in
// a passing run is appended to SUMMARY.md for posterity (plan output item f).

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

test('Camera follow: walking toward room edge pans the camera (D-29 mandatory)', async ({
  page,
  accountA,
  inviteSuffix,
}) => {
  // 1. Login and wait for game-ready.
  await loginAs(page, accountA, inviteSuffix);
  await waitForGameReady(page);

  // 2. Capture initial camera + player position via __rebno hook (D-35).
  const before = await page.evaluate(() => {
    const r = (window as unknown as {
      __rebno?: {
        cameraScrollX?: number;
        cameraScrollY?: number;
        localPlayerX?: number;
        localPlayerY?: number;
      };
    }).__rebno;
    return {
      scrollX: r?.cameraScrollX ?? 0,
      scrollY: r?.cameraScrollY ?? 0,
      x: r?.localPlayerX ?? 0,
      y: r?.localPlayerY ?? 0,
    };
  });

  // 3. Focus the canvas so key events reach the Phaser input layer.
  await page.locator('canvas[data-game-ready="true"]').click();

  // 4. Hold ArrowRight (or 'd') for ~1500ms — enough to cross the camera
  //    deadzone (dzW = 32px per BNO hBorder derivation in GameScene.ts).
  await page.keyboard.down('d');
  await page.waitForTimeout(1_500);
  await page.keyboard.up('d');

  // 5. Brief settle time for prediction/reconciliation.
  await page.waitForTimeout(200);

  // 6. Capture post-walk camera + player position.
  const after = await page.evaluate(() => {
    const r = (window as unknown as {
      __rebno?: {
        cameraScrollX?: number;
        cameraScrollY?: number;
        localPlayerX?: number;
        localPlayerY?: number;
      };
    }).__rebno;
    return {
      scrollX: r?.cameraScrollX ?? 0,
      scrollY: r?.cameraScrollY ?? 0,
      x: r?.localPlayerX ?? 0,
      y: r?.localPlayerY ?? 0,
    };
  });

  // 7. Assert camera panned at least 8px total (conservative threshold for 1.5s walk).
  const cameraDelta =
    Math.abs(after.scrollX - before.scrollX) +
    Math.abs(after.scrollY - before.scrollY);
  expect(
    cameraDelta,
    `Camera did not pan: before=(${before.scrollX},${before.scrollY}) after=(${after.scrollX},${after.scrollY})`,
  ).toBeGreaterThanOrEqual(8);

  // 8. Secondary: player moved (position changed on at least one axis).
  const playerMoved = after.x !== before.x || after.y !== before.y;
  expect(
    playerMoved,
    `Player did not move: before=(${before.x},${before.y}) after=(${after.x},${after.y})`,
  ).toBe(true);
});
