// Phase 19 end-to-end smoke against the synthetic-report path. Loads
// a hand-crafted JSON with a Tancordia-style mix of planets and ship
// groups through the DEV-only file picker on `/lobby`, lets the
// in-game shell layout swap into synthetic mode, and asserts the map
// canvas mounts. Detailed click / hit-test fidelity for ship-group
// variants lives in the unit tests (`tests/state-binding-groups.test.ts`
// and `tests/inspector-ship-group.test.ts`); this spec catches the
// glue: lobby loader → in-memory registry → layout bypass → renderer
// boot.

import { expect, test, type Page } from "@playwright/test";

// Seed an authenticated session through `/__debug/store` so the
// root layout's redirect-to-login guard passes. The synthetic flow
// itself does not talk to the gateway, but the session check still
// runs at every navigation. The full `__galaxyDebug` shape is
// declared globally in `tests/e2e/storage-keypair-persistence.spec.ts`;
// here we only need `loadSession` + `setDeviceSessionId`.
async function seedSession(page: Page): Promise<void> {
	await page.goto("/__debug/store");
	await expect(page.getByTestId("debug-store-ready")).toBeVisible();
	await page.waitForFunction(
		() => (window as unknown as { __galaxyDebug?: { ready?: boolean } }).__galaxyDebug?.ready === true,
	);
	await page.evaluate(async () => {
		const debug = (window as unknown as {
			__galaxyDebug: {
				loadSession(): Promise<unknown>;
				setDeviceSessionId(id: string): Promise<void>;
			};
		}).__galaxyDebug;
		await debug.loadSession();
		await debug.setDeviceSessionId("phase-19-synthetic-session");
	});
}

const SYNTHETIC_REPORT_FIXTURE = {
	turn: 39,
	mapWidth: 200,
	mapHeight: 200,
	mapPlanets: 4,
	race: "Earthlings",
	player: [
		{
			name: "Earthlings",
			drive: 5,
			weapons: 3,
			shields: 2,
			cargo: 1,
			population: 1000,
			industry: 1000,
			planets: 2,
			relation: "-",
			votes: 5,
			extinct: false,
		},
	],
	localPlanet: [
		{
			number: 1,
			name: "Earth",
			x: 50,
			y: 100,
			size: 1000,
			population: 1000,
			industry: 1000,
			resources: 10,
			production: "Capital",
			capital: 0,
			material: 0,
			colonists: 100,
			freeIndustry: 1000,
		},
		{
			number: 2,
			name: "Mars",
			x: 150,
			y: 100,
			size: 500,
			population: 500,
			industry: 500,
			resources: 5,
			production: "Capital",
			capital: 0,
			material: 0,
			colonists: 50,
			freeIndustry: 500,
		},
	],
	otherPlanet: [],
	uninhabitedPlanet: [],
	unidentifiedPlanet: [
		{ number: 3, x: 50, y: 50 },
		{ number: 4, x: 150, y: 50 },
	],
	localShipClass: [
		{
			name: "Frontier",
			drive: 5,
			armament: 0,
			weapons: 0,
			shields: 0,
			cargo: 1,
			mass: 12,
		},
	],
	localGroup: [
		{
			id: "11111111-2222-3333-4444-555555555555",
			number: 2,
			class: "Frontier",
			tech: { drive: 5, weapons: 0, shields: 0, cargo: 1 },
			cargo: "-",
			load: 0,
			destination: 1,
			speed: 0,
			mass: 12,
			state: "In_Orbit",
		},
	],
	otherGroup: [],
	incomingGroup: [
		{
			origin: 4,
			destination: 1,
			distance: 50,
			speed: 25,
			mass: 4,
		},
	],
	unidentifiedGroup: [],
	localFleet: [],
};

test("synthetic-report loader navigates from lobby to map and renders", async ({
	page,
}) => {
	await seedSession(page);
	await page.goto("/lobby");
	await expect(page.getByTestId("lobby-synthetic-section")).toBeVisible();

	const file = page.getByTestId("lobby-synthetic-file");
	await file.setInputFiles({
		name: "phase19.json",
		mimeType: "application/json",
		buffer: Buffer.from(JSON.stringify(SYNTHETIC_REPORT_FIXTURE)),
	});

	await page.waitForURL(/\/games\/synthetic-[^/]+\/map$/, {
		timeout: 5_000,
	});

	// The renderer canvas mounts inside the active-view host. Even if
	// the WebGL/WebGPU backend is unavailable in CI, the layout still
	// reaches `ready` once the report is loaded — the assertion is
	// gentle on purpose so the spec doesn't flake on headless renders.
	const canvas = page.locator("canvas");
	await expect(canvas.first()).toBeVisible({ timeout: 10_000 });
});
