<!--
"Ship groups stationed here" subsection of the planet inspector.
The map deliberately hides on-planet groups (rendering them as
offset points crowds the canvas), so this list is the player's
view of which fleets sit in this orbit. Race attribution is
best-effort:
  - LocalGroup → the player's own race (`localRace` prop).
  - OtherGroup on an `other`-kind planet → the planet's owner.
  - OtherGroup elsewhere → "foreign" placeholder; the engine's
    typed contract does not carry per-group ownership outside
    battle rosters.

Phase 20 makes own-ship rows interactive: clicking a row pivots
the inspector to the corresponding ship-group inspector through
the shared `SelectionStore`. The actions panel mounts on top of
the existing ship-group inspector, so the row is the on-planet
entry point for Send / Load / Modernize / etc. Foreign rows stay
non-interactive — there are no actions to drive against another
race's fleet. Phase 21+ will reuse the same row shape inside the
ship-groups table view with an additional `(planet, race)` filter.
-->
<script lang="ts">
	import { getContext } from "svelte";

	import type {
		ReportLocalShipGroup,
		ReportOtherShipGroup,
		ReportPlanet,
	} from "../../../api/game-state";
	import { i18n } from "$lib/i18n/index.svelte";
	import {
		SELECTION_CONTEXT_KEY,
		type SelectionStore,
	} from "$lib/selection.svelte";

	type Props = {
		planet: ReportPlanet;
		localShipGroups: ReportLocalShipGroup[];
		otherShipGroups: ReportOtherShipGroup[];
		localRace: string;
	};
	let { planet, localShipGroups, otherShipGroups, localRace }: Props = $props();

	const selection = getContext<SelectionStore | undefined>(
		SELECTION_CONTEXT_KEY,
	);

	interface StationedRow {
		key: string;
		race: string;
		class: string;
		count: number;
		mass: number;
		selectable: boolean;
		groupId: string | null;
	}

	const stationedRows: StationedRow[] = $derived.by(() => {
		const rows: StationedRow[] = [];
		for (const g of localShipGroups) {
			if (g.destination !== planet.number) continue;
			if (g.origin !== null || g.range !== null) continue;
			rows.push({
				key: `local:${g.id}`,
				race: localRace || i18n.t("game.inspector.planet.ship_groups.race.unknown"),
				class: g.class,
				count: g.count,
				mass: g.mass,
				selectable: true,
				groupId: g.id,
			});
		}
		const foreignRace =
			planet.owner ??
			i18n.t("game.inspector.planet.ship_groups.race.foreign");
		for (let i = 0; i < otherShipGroups.length; i++) {
			const g = otherShipGroups[i]!;
			if (g.destination !== planet.number) continue;
			if (g.origin !== null || g.range !== null) continue;
			rows.push({
				key: `other:${i}`,
				race: foreignRace,
				class: g.class,
				count: g.count,
				mass: g.mass,
				selectable: false,
				groupId: null,
			});
		}
		return rows;
	});

	function formatNumber(value: number): string {
		return value.toLocaleString(undefined, { maximumFractionDigits: 2 });
	}

	function selectLocalGroup(groupId: string): void {
		if (selection === undefined) return;
		selection.selectShipGroup({ variant: "local", id: groupId });
	}
</script>

{#if stationedRows.length > 0}
	<section class="ship-groups" data-testid="inspector-planet-ship-groups">
		<h4>{i18n.t("game.inspector.planet.ship_groups.title")}</h4>
		<ul class="rows">
			{#each stationedRows as row (row.key)}
				<li class="row" data-testid="inspector-planet-ship-groups-row">
					{#if row.selectable && row.groupId !== null}
						{@const groupId = row.groupId}
						<button
							type="button"
							class="select"
							data-testid="inspector-planet-ship-groups-select"
							onclick={() => selectLocalGroup(groupId)}
						>
							<span class="race" data-testid="inspector-planet-ship-groups-race">
								{row.race}
							</span>
							<span class="class">{row.class}</span>
							<span class="count">
								{i18n.t("game.inspector.planet.ship_groups.row.count", {
									count: String(row.count),
								})}
							</span>
							<span class="mass">
								{i18n.t("game.inspector.planet.ship_groups.row.mass", {
									mass: formatNumber(row.mass),
								})}
							</span>
						</button>
					{:else}
						<span class="race" data-testid="inspector-planet-ship-groups-race">
							{row.race}
						</span>
						<span class="class">{row.class}</span>
						<span class="count">
							{i18n.t("game.inspector.planet.ship_groups.row.count", {
								count: String(row.count),
							})}
						</span>
						<span class="mass">
							{i18n.t("game.inspector.planet.ship_groups.row.mass", {
								mass: formatNumber(row.mass),
							})}
						</span>
					{/if}
				</li>
			{/each}
		</ul>
	</section>
{/if}

<style>
	.ship-groups {
		display: flex;
		flex-direction: column;
		gap: 0.4rem;
	}
	h4 {
		margin: 0;
		font-size: 0.85rem;
		text-transform: uppercase;
		letter-spacing: 0.05em;
		color: #aab;
	}
	.rows {
		list-style: none;
		margin: 0;
		padding: 0;
		display: flex;
		flex-direction: column;
		gap: 0.2rem;
	}
	.row {
		display: block;
		font-size: 0.85rem;
		font-variant-numeric: tabular-nums;
	}
	.row > span,
	.row > .select {
		display: grid;
		grid-template-columns: 1fr 1fr auto auto;
		gap: 0.5rem;
	}
	.select {
		width: 100%;
		font: inherit;
		text-align: left;
		background: transparent;
		color: inherit;
		border: 1px solid transparent;
		border-radius: 3px;
		padding: 0.15rem 0.3rem;
		cursor: pointer;
	}
	.select:hover {
		border-color: #2a3150;
		background: #0d1224;
	}
	.race {
		font-weight: 600;
	}
	.class {
		color: #cdd;
	}
	.count,
	.mass {
		color: #aab;
	}
</style>
