// Vitest component coverage for the Phase 19 read-only ship-group
// inspector. The inspector dispatches on the selection variant —
// local / other / incoming / unidentified — and renders a fixed set
// of fields per branch. The tests assert each branch surfaces the
// fields the acceptance criteria call out, plus the
// "no destination resolution" fallback.

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 {
	ReportIncomingShipGroup,
	ReportLocalShipGroup,
	ReportOtherShipGroup,
	ReportPlanet,
	ReportUnidentifiedShipGroup,
} from "../src/api/game-state";
import ShipGroup, {
	type ShipGroupSelection,
} from "../src/lib/inspectors/ship-group.svelte";

const PLANETS: ReportPlanet[] = [
	{
		number: 17,
		name: "Castle",
		x: 100,
		y: 100,
		kind: "local",
		owner: null,
		size: 1000,
		resources: 10,
		industryStockpile: 0,
		materialsStockpile: 0,
		industry: 1000,
		population: 1000,
		colonists: 0,
		production: "Capital",
		freeIndustry: 1000,
	},
	{
		number: 99,
		name: "Outpost",
		x: 200,
		y: 200,
		kind: "other",
		owner: "Foreign",
		size: 500,
		resources: 5,
		industryStockpile: 0,
		materialsStockpile: 0,
		industry: 500,
		population: 500,
		colonists: 0,
		production: "Capital",
		freeIndustry: 500,
	},
];

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

function localGroup(
	overrides: Partial<ReportLocalShipGroup> = {},
): ReportLocalShipGroup {
	return {
		id: "uuid-1",
		count: 2,
		class: "Frontier",
		tech: { drive: 5, weapons: 0, shields: 0, cargo: 1 },
		cargo: "NONE",
		load: 0,
		destination: 17,
		origin: null,
		range: null,
		speed: 0,
		mass: 12,
		state: "In_Orbit",
		fleet: null,
		...overrides,
	};
}

describe("ship-group inspector", () => {
	test("renders the on-planet local group with all required fields", () => {
		const selection: ShipGroupSelection = {
			variant: "local",
			group: localGroup(),
		};
		const ui = render(ShipGroup, { props: { selection, planets: PLANETS } });
		expect(ui.getByTestId("inspector-ship-group-class")).toHaveTextContent(
			"Frontier",
		);
		expect(ui.getByTestId("inspector-ship-group-field-count")).toHaveTextContent(
			"2",
		);
		expect(ui.getByTestId("inspector-ship-group-field-drive")).toHaveTextContent(
			"5",
		);
		expect(
			ui.getByTestId("inspector-ship-group-field-location"),
		).toHaveTextContent("Castle");
		expect(ui.getByTestId("inspector-ship-group-field-state")).toHaveTextContent(
			"In_Orbit",
		);
		expect(
			ui.queryByTestId("inspector-ship-group-field-distance"),
		).toBeNull();
	});

	test("renders the in-hyperspace local group with from / to / distance", () => {
		const selection: ShipGroupSelection = {
			variant: "local",
			group: localGroup({
				origin: 17,
				range: 4.5,
				destination: 99,
				state: "In_Space",
			}),
		};
		const ui = render(ShipGroup, { props: { selection, planets: PLANETS } });
		expect(ui.getByTestId("inspector-ship-group-field-from")).toHaveTextContent(
			"Castle",
		);
		expect(ui.getByTestId("inspector-ship-group-field-to")).toHaveTextContent(
			"Outpost",
		);
		expect(
			ui.getByTestId("inspector-ship-group-field-distance"),
		).toHaveTextContent("4.5");
		expect(
			ui.queryByTestId("inspector-ship-group-field-location"),
		).toBeNull();
	});

	test("renders cargo type and amount when the group is loaded", () => {
		const selection: ShipGroupSelection = {
			variant: "local",
			group: localGroup({ cargo: "COL", load: 1.05 }),
		};
		const ui = render(ShipGroup, { props: { selection, planets: PLANETS } });
		const cargo = ui.getByTestId("inspector-ship-group-field-cargo-load");
		expect(cargo).toHaveTextContent("colonists");
		expect(cargo).toHaveTextContent("1.05");
	});

	test("renders foreign group without fleet/state but with full tech", () => {
		const group: ReportOtherShipGroup = {
			count: 5,
			class: "Cruiser",
			tech: { drive: 8, weapons: 4, shields: 3, cargo: 1 },
			cargo: "NONE",
			load: 0,
			destination: 99,
			origin: null,
			range: null,
			speed: 0,
			mass: 50,
		};
		const selection: ShipGroupSelection = { variant: "other", group };
		const ui = render(ShipGroup, { props: { selection, planets: PLANETS } });
		expect(ui.getByTestId("inspector-ship-group-class")).toHaveTextContent(
			"Cruiser",
		);
		expect(ui.queryByTestId("inspector-ship-group-field-fleet")).toBeNull();
		expect(ui.queryByTestId("inspector-ship-group-field-state")).toBeNull();
	});

	test("incoming group surfaces ETA and trajectory fields", () => {
		const group: ReportIncomingShipGroup = {
			origin: 99,
			destination: 17,
			distance: 80,
			speed: 25,
			mass: 4,
		};
		const selection: ShipGroupSelection = { variant: "incoming", group };
		const ui = render(ShipGroup, { props: { selection, planets: PLANETS } });
		expect(ui.getByTestId("inspector-ship-group-field-from")).toHaveTextContent(
			"Outpost",
		);
		expect(ui.getByTestId("inspector-ship-group-field-to")).toHaveTextContent(
			"Castle",
		);
		// ETA = ceil(80 / 25) = 4.
		expect(ui.getByTestId("inspector-ship-group-field-eta")).toHaveTextContent(
			"4",
		);
		expect(
			ui.getByTestId("inspector-ship-group-field-distance"),
		).toHaveTextContent("80");
	});

	test("incoming group with zero speed renders ETA as the dash placeholder", () => {
		const group: ReportIncomingShipGroup = {
			origin: 99,
			destination: 17,
			distance: 80,
			speed: 0,
			mass: 4,
		};
		const selection: ShipGroupSelection = { variant: "incoming", group };
		const ui = render(ShipGroup, { props: { selection, planets: PLANETS } });
		expect(ui.getByTestId("inspector-ship-group-field-eta")).toHaveTextContent(
			"—",
		);
	});

	test("unidentified group renders coordinates and the no-data hint", () => {
		const group: ReportUnidentifiedShipGroup = { x: 555.5, y: 222.25 };
		const selection: ShipGroupSelection = { variant: "unidentified", group };
		const ui = render(ShipGroup, { props: { selection, planets: PLANETS } });
		const coords = ui.getByTestId("inspector-ship-group-field-coordinates");
		expect(coords).toHaveTextContent("555.5");
		expect(coords).toHaveTextContent("222.25");
		expect(ui.getByTestId("inspector-ship-group-no-data")).toBeInTheDocument();
	});

	test("planet name resolves to '#NN' when missing from the planet list", () => {
		const selection: ShipGroupSelection = {
			variant: "local",
			group: localGroup({ destination: 999 }),
		};
		const ui = render(ShipGroup, { props: { selection, planets: PLANETS } });
		expect(
			ui.getByTestId("inspector-ship-group-field-location"),
		).toHaveTextContent("#999");
	});
});
