// Vitest coverage for the Phase 23 Report View's foreign sciences
// section. Representative for the per-race sub-table shape used by
// `section-foreign-ship-classes.svelte` too. Three scenarios — empty
// list, single-race table, multi-race grouping — exercise the
// decoder's `(race, name)` order and the per-race sub-header.

import "@testing-library/jest-dom/vitest";
import { render } from "@testing-library/svelte";
import { beforeEach, describe, expect, test } from "vitest";

import { i18n } from "../src/lib/i18n/index.svelte";
import type {
	GameReport,
	ReportOtherScience,
} from "../src/api/game-state";
import { RENDERED_REPORT_CONTEXT_KEY } from "../src/lib/rendered-report.svelte";
import { EMPTY_SHIP_GROUPS } from "./helpers/empty-ship-groups";

import SectionForeignSciences from "../src/lib/active-view/report/section-foreign-sciences.svelte";

beforeEach(() => {
	i18n.resetForTests("en");
});

function science(
	overrides: Partial<ReportOtherScience> &
		Pick<ReportOtherScience, "race" | "name">,
): ReportOtherScience {
	return {
		drive: 0,
		weapons: 0,
		shields: 0,
		cargo: 0,
		...overrides,
	};
}

function makeReport(rows: ReportOtherScience[]): GameReport {
	return {
		turn: 1,
		mapWidth: 1000,
		mapHeight: 1000,
		planetCount: 0,
		planets: [],
		race: "Self",
		localShipClass: [],
		routes: [],
		localPlayerDrive: 0,
		localPlayerWeapons: 0,
		localPlayerShields: 0,
		localPlayerCargo: 0,
		...EMPTY_SHIP_GROUPS,
		otherScience: rows,
	};
}

function mountSection(report: GameReport | null) {
	const context = new Map<unknown, unknown>([
		[RENDERED_REPORT_CONTEXT_KEY, { get report() {
			return report;
		} }],
	]);
	return render(SectionForeignSciences, { context });
}

describe("report foreign sciences section", () => {
	test("renders the empty-state copy when no foreign sciences are observed", () => {
		const ui = mountSection(makeReport([]));
		expect(ui.getByTestId("foreign-sciences-empty")).toBeInTheDocument();
	});

	test("renders one sub-table per race with rows sorted by name", () => {
		const ui = mountSection(
			makeReport([
				science({ race: "Andori", name: "AnDrive", drive: 1 }),
				science({ race: "Andori", name: "AnCargo", cargo: 1 }),
				science({ race: "Bajori", name: "BjMix", drive: 0.5, cargo: 0.5 }),
			]),
		);
		const headers = ui.getAllByTestId("report-other-science-race");
		expect(headers).toHaveLength(2);
		expect(headers[0]).toHaveAttribute("data-race", "Andori");
		expect(headers[1]).toHaveAttribute("data-race", "Bajori");

		const rows = ui.getAllByTestId("foreign-sciences-row");
		expect(rows).toHaveLength(3);
		// Andori sub-table comes first; its rows precede Bajori.
		expect(rows[0]).toHaveAttribute("data-race", "Andori");
		expect(rows[0]).toHaveAttribute("data-name", "AnDrive");
		expect(rows[1]).toHaveAttribute("data-race", "Andori");
		expect(rows[1]).toHaveAttribute("data-name", "AnCargo");
		expect(rows[2]).toHaveAttribute("data-race", "Bajori");
		expect(rows[2]).toHaveAttribute("data-name", "BjMix");
	});

	test("renders a single race block when only one foreign science is present", () => {
		const ui = mountSection(
			makeReport([science({ race: "Solo", name: "Singularity", drive: 1 })]),
		);
		const headers = ui.getAllByTestId("report-other-science-race");
		expect(headers).toHaveLength(1);
		expect(headers[0]).toHaveTextContent("Solo sciences");
		const rows = ui.getAllByTestId("foreign-sciences-row");
		expect(rows).toHaveLength(1);
	});
});
