<!--
Phase 15 production-controls subsection of the planet inspector.
Renders four main segments — industry / materials / research / build
ship — and reveals a sub-row when the player picks a category that
needs a target (research → tech field or science, build ship →
designed class). Every leaf click appends a `setProductionType`
command to the local order draft via `OrderDraftStore`; the
collapse-by-`planetNumber` rule inside `add` keeps at most one
production choice per planet.

The currently-active segment is derived from `planet.production`
through a parser that mirrors the engine's
`Cache.PlanetProductionDisplayName` mapping. While the player is
mid-navigation (e.g. clicked Research but has not picked a tech yet)
a transient `expandedMain` override widens the visible state so the
sub-row can appear without forcing the player to commit a choice
first; the override resets whenever the inspector switches to a
different planet or after any leaf click.

Phase 15 deliberately defers the per-type forecast number — see
`ui/docs/calc-bridge.md` for the gap analysis. The component does
not render forecast text; the existing `freeIndustry` ("free
production") row in the parent inspector is unchanged.

Phase 21 widens the Research sub-row: in addition to the four tech
buttons the player sees one extra button per defined science from
`localScience`. The active highlight prefers a science-name match
over the four tech display strings, so a science deliberately named
exactly "Drive" / "Weapons" / "Shields" / "Cargo" shadows the
matching tech button (the engine sends a single ambiguous display
string in `planet.production`; user-defined sciences win because
they carry more user intent).
-->
<script lang="ts">
	import { getContext } from "svelte";
	import type {
		ReportPlanet,
		ScienceSummary,
		ShipClassSummary,
	} from "../../../api/game-state";
	import { i18n, type TranslationKey } from "$lib/i18n/index.svelte";
	import {
		ORDER_DRAFT_CONTEXT_KEY,
		OrderDraftStore,
	} from "../../../sync/order-draft.svelte";
	import type { ProductionType } from "../../../sync/order-types";

	type Props = {
		planet: ReportPlanet;
		localShipClass: ShipClassSummary[];
		localScience: ScienceSummary[];
	};
	let { planet, localShipClass, localScience }: Props = $props();

	type MainSegment = "industry" | "materials" | "research" | "ship";

	const draft = getContext<OrderDraftStore | undefined>(
		ORDER_DRAFT_CONTEXT_KEY,
	);
	const disabled = draft === undefined;

	let expandedMain: MainSegment | null = $state(null);

	const parsedMain = $derived(
		parseMain(planet.production, localShipClass, localScience),
	);
	const selectedMain = $derived(expandedMain ?? parsedMain);
	const activeResearch = $derived(parseResearch(planet.production, localScience));
	const activeScience = $derived(parseScience(planet.production, localScience));
	const activeShip = $derived(parseShip(planet.production, localShipClass));

	$effect(() => {
		// Reset the expand-override whenever the inspector switches to a
		// different planet so a stale category does not leak across the
		// selection boundary.
		void planet.number;
		expandedMain = null;
	});

	const RESEARCH_OPTIONS: ReadonlyArray<{
		fbs: ProductionType;
		slug: "drive" | "weapons" | "shields" | "cargo";
		labelKey: TranslationKey;
	}> = [
		{
			fbs: "DRIVE",
			slug: "drive",
			labelKey: "game.inspector.planet.production.research.drive",
		},
		{
			fbs: "WEAPONS",
			slug: "weapons",
			labelKey: "game.inspector.planet.production.research.weapons",
		},
		{
			fbs: "SHIELDS",
			slug: "shields",
			labelKey: "game.inspector.planet.production.research.shields",
		},
		{
			fbs: "CARGO",
			slug: "cargo",
			labelKey: "game.inspector.planet.production.research.cargo",
		},
	];

	function parseMain(
		value: string | null,
		classes: ShipClassSummary[],
		sciences: ScienceSummary[],
	): MainSegment | null {
		if (value === null || value === "" || value === "-") return null;
		// Sciences first: a user-named "Drive" science wins over the
		// Drive tech display string. If no science matches, fall through
		// to tech / ship class detection.
		if (sciences.some((s) => s.name === value)) return "research";
		switch (value) {
			case "Capital":
				return "industry";
			case "Material":
				return "materials";
			case "Drive":
			case "Weapons":
			case "Shields":
			case "Cargo":
				return "research";
		}
		return classes.some((c) => c.name === value) ? "ship" : null;
	}

	function parseResearch(
		value: string | null,
		sciences: ScienceSummary[],
	): ProductionType | null {
		// A science name shadows the four tech display strings — when a
		// science matches we surface no tech-button highlight so the
		// science button gets the active styling instead.
		if (value !== null && sciences.some((s) => s.name === value)) return null;
		switch (value) {
			case "Drive":
				return "DRIVE";
			case "Weapons":
				return "WEAPONS";
			case "Shields":
				return "SHIELDS";
			case "Cargo":
				return "CARGO";
			default:
				return null;
		}
	}

	function parseScience(
		value: string | null,
		sciences: ScienceSummary[],
	): string | null {
		if (value === null || value === "") return null;
		return sciences.some((s) => s.name === value) ? value : null;
	}

	function parseShip(
		value: string | null,
		classes: ShipClassSummary[],
	): string | null {
		if (value === null || value === "") return null;
		return classes.some((c) => c.name === value) ? value : null;
	}

	function clickMain(segment: MainSegment): void {
		if (segment === "industry") {
			void emit("CAP", "");
			expandedMain = null;
			return;
		}
		if (segment === "materials") {
			void emit("MAT", "");
			expandedMain = null;
			return;
		}
		expandedMain = segment;
	}

	function clickResearch(value: ProductionType): void {
		void emit(value, "");
		expandedMain = null;
	}

	function clickScience(name: string): void {
		void emit("SCIENCE", name);
		expandedMain = null;
	}

	function clickShip(name: string): void {
		void emit("SHIP", name);
		expandedMain = null;
	}

	async function emit(
		productionType: ProductionType,
		subject: string,
	): Promise<void> {
		if (draft === undefined) return;
		await draft.add({
			kind: "setProductionType",
			id: crypto.randomUUID(),
			planetNumber: planet.number,
			productionType,
			subject,
		});
	}
</script>

<section class="production" data-testid="inspector-planet-production">
	<h4 class="title">
		{i18n.t("game.inspector.planet.production.title")}
	</h4>
	<div class="row main">
		<button
			type="button"
			class="seg"
			class:active={selectedMain === "industry"}
			data-testid="inspector-planet-production-segment-industry"
			disabled={disabled}
			onclick={() => clickMain("industry")}
		>
			{i18n.t("game.inspector.planet.production.option.industry")}
		</button>
		<button
			type="button"
			class="seg"
			class:active={selectedMain === "materials"}
			data-testid="inspector-planet-production-segment-materials"
			disabled={disabled}
			onclick={() => clickMain("materials")}
		>
			{i18n.t("game.inspector.planet.production.option.materials")}
		</button>
		<button
			type="button"
			class="seg"
			class:active={selectedMain === "research"}
			data-testid="inspector-planet-production-segment-research"
			disabled={disabled}
			onclick={() => clickMain("research")}
		>
			{i18n.t("game.inspector.planet.production.option.research")}
		</button>
		<button
			type="button"
			class="seg"
			class:active={selectedMain === "ship"}
			data-testid="inspector-planet-production-segment-ship"
			disabled={disabled}
			onclick={() => clickMain("ship")}
		>
			{i18n.t("game.inspector.planet.production.option.ship")}
		</button>
	</div>

	{#if selectedMain === "research"}
		<div class="row sub" data-testid="inspector-planet-production-research-row">
			{#each RESEARCH_OPTIONS as option (option.fbs)}
				<button
					type="button"
					class="sub-seg"
					class:active={activeResearch === option.fbs}
					data-testid={`inspector-planet-production-research-${option.slug}`}
					disabled={disabled}
					onclick={() => clickResearch(option.fbs)}
				>
					{i18n.t(option.labelKey)}
				</button>
			{/each}
			{#each localScience as sci (sci.name)}
				<button
					type="button"
					class="sub-seg"
					class:active={activeScience === sci.name}
					data-testid={`inspector-planet-production-science-${sci.name}`}
					disabled={disabled}
					onclick={() => clickScience(sci.name)}
				>
					{sci.name}
				</button>
			{/each}
		</div>
	{/if}

	{#if selectedMain === "ship"}
		<div class="row sub" data-testid="inspector-planet-production-ship-row">
			{#if localShipClass.length === 0}
				<p
					class="empty"
					data-testid="inspector-planet-production-ship-empty"
				>
					{i18n.t("game.inspector.planet.production.ship.no_classes")}
				</p>
			{:else}
				{#each localShipClass as cls (cls.name)}
					<button
						type="button"
						class="sub-seg"
						class:active={activeShip === cls.name}
						data-testid={`inspector-planet-production-ship-${cls.name}`}
						disabled={disabled}
						onclick={() => clickShip(cls.name)}
					>
						{cls.name}
					</button>
				{/each}
			{/if}
		</div>
	{/if}
</section>

<style>
	.production {
		display: flex;
		flex-direction: column;
		gap: 0.4rem;
	}
	.title {
		margin: 0;
		font-size: 0.85rem;
		color: #aab;
		font-weight: 500;
	}
	.row {
		display: flex;
		gap: 0.3rem;
		flex-wrap: wrap;
	}
	.row.sub {
		padding-left: 0.6rem;
	}
	.seg,
	.sub-seg {
		font: inherit;
		font-size: 0.85rem;
		padding: 0.25rem 0.55rem;
		background: transparent;
		color: #aab;
		border: 1px solid #2a3150;
		border-radius: 3px;
		cursor: pointer;
	}
	.seg:not(:disabled):hover,
	.sub-seg:not(:disabled):hover {
		color: #e8eaf6;
		border-color: #6d8cff;
	}
	.seg.active,
	.sub-seg.active {
		color: #e8eaf6;
		border-color: #6d8cff;
		background: rgba(109, 140, 255, 0.15);
	}
	.seg:disabled,
	.sub-seg:disabled {
		cursor: not-allowed;
		opacity: 0.5;
	}
	.empty {
		margin: 0;
		font-size: 0.8rem;
		color: #888;
		font-style: italic;
	}
</style>
