<!--
Phase 23 turn-report active view.

Composes the table of contents (`report/report-toc.svelte`) and the
twenty section components that render each `GameReport` array. Each
section is its own component under `lib/active-view/report/` — the
data shapes are too varied for one generic table, and the
component-per-section seam matches Phase 23's targeted-test contract.

Active-section highlighting and scroll save/restore land here:
- `IntersectionObserver` rooted on the active-view-host element
  (`bind:this` in `+layout.svelte`, plumbed through
  `ACTIVE_VIEW_HOST_CONTEXT_KEY`) watches every `<section
  id="report-<slug>">` and updates a local `activeSlug` rune.
- The matching `+page.svelte` exports a SvelteKit `Snapshot` that
  captures and restores `host.element.scrollTop`, so navigating to
  /map and back lands on the same scroll position. The save lives in
  `+page.svelte` because SvelteKit binds snapshots per route.

The 20-section list lives here as a single source of truth so the
TOC and the body iterate the same data.
-->
<script lang="ts">
	import { onMount } from "svelte";
	import { page } from "$app/state";

	import ReportToc, {
		type TocEntry,
	} from "./report/report-toc.svelte";
	import SectionGalaxySummary from "./report/section-galaxy-summary.svelte";
	import SectionVotes from "./report/section-votes.svelte";
	import SectionPlayerStatus from "./report/section-player-status.svelte";
	import SectionMySciences from "./report/section-my-sciences.svelte";
	import SectionForeignSciences from "./report/section-foreign-sciences.svelte";
	import SectionMyShipClasses from "./report/section-my-ship-classes.svelte";
	import SectionForeignShipClasses from "./report/section-foreign-ship-classes.svelte";
	import SectionBattles from "./report/section-battles.svelte";
	import SectionBombings from "./report/section-bombings.svelte";
	import SectionApproachingGroups from "./report/section-approaching-groups.svelte";
	import SectionMyPlanets from "./report/section-my-planets.svelte";
	import SectionShipsInProduction from "./report/section-ships-in-production.svelte";
	import SectionCargoRoutes from "./report/section-cargo-routes.svelte";
	import SectionForeignPlanets from "./report/section-foreign-planets.svelte";
	import SectionUninhabitedPlanets from "./report/section-uninhabited-planets.svelte";
	import SectionUnknownPlanets from "./report/section-unknown-planets.svelte";
	import SectionMyFleets from "./report/section-my-fleets.svelte";
	import SectionMyShipGroups from "./report/section-my-ship-groups.svelte";
	import SectionForeignShipGroups from "./report/section-foreign-ship-groups.svelte";
	import SectionUnidentifiedGroups from "./report/section-unidentified-groups.svelte";

	const ENTRIES: readonly TocEntry[] = [
		{ slug: "galaxy-summary", titleKey: "game.report.section.galaxy_summary.title" },
		{ slug: "votes", titleKey: "game.report.section.votes.title" },
		{ slug: "player-status", titleKey: "game.report.section.player_status.title" },
		{ slug: "my-sciences", titleKey: "game.report.section.my_sciences.title" },
		{ slug: "foreign-sciences", titleKey: "game.report.section.foreign_sciences.title" },
		{ slug: "my-ship-classes", titleKey: "game.report.section.my_ship_classes.title" },
		{ slug: "foreign-ship-classes", titleKey: "game.report.section.foreign_ship_classes.title" },
		{ slug: "battles", titleKey: "game.report.section.battles.title" },
		{ slug: "bombings", titleKey: "game.report.section.bombings.title" },
		{ slug: "approaching-groups", titleKey: "game.report.section.approaching_groups.title" },
		{ slug: "my-planets", titleKey: "game.report.section.my_planets.title" },
		{ slug: "ships-in-production", titleKey: "game.report.section.ships_in_production.title" },
		{ slug: "cargo-routes", titleKey: "game.report.section.cargo_routes.title" },
		{ slug: "foreign-planets", titleKey: "game.report.section.foreign_planets.title" },
		{ slug: "uninhabited-planets", titleKey: "game.report.section.uninhabited_planets.title" },
		{ slug: "unknown-planets", titleKey: "game.report.section.unknown_planets.title" },
		{ slug: "my-fleets", titleKey: "game.report.section.my_fleets.title" },
		{ slug: "my-ship-groups", titleKey: "game.report.section.my_ship_groups.title" },
		{ slug: "foreign-ship-groups", titleKey: "game.report.section.foreign_ship_groups.title" },
		{ slug: "unidentified-groups", titleKey: "game.report.section.unidentified_groups.title" },
	];

	const gameId = $derived(page.params.id ?? "");

	let activeSlug = $state<string>(ENTRIES[0]?.slug ?? "");
	let bodyEl: HTMLDivElement | null = $state(null);

	// `IntersectionObserver` rooted on the viewport (`root: null`)
	// lets the TOC highlight follow the section currently in the
	// upper portion of the visible area. The in-game shell layout
	// expands the active-view-host to fit content rather than
	// constraining it, so the document body scrolls — not the host.
	// Targeting the viewport with a top-skewed `rootMargin` advances
	// the highlight as a section enters the upper third of what the
	// reader sees, without coupling to the layout's internal sizing.
	onMount(() => {
		if (typeof IntersectionObserver === "undefined") return;
		const body = bodyEl;
		if (body === null) return;
		const targets = body.querySelectorAll<HTMLElement>("section[id^='report-']");
		if (targets.length === 0) return;
		const observer = new IntersectionObserver(
			(entries) => {
				let pick: { slug: string; ratio: number } | null = null;
				for (const entry of entries) {
					if (!entry.isIntersecting) continue;
					const slug = entry.target.id.replace(/^report-/, "");
					if (pick === null || entry.intersectionRatio > pick.ratio) {
						pick = { slug, ratio: entry.intersectionRatio };
					}
				}
				if (pick !== null) {
					activeSlug = pick.slug;
				}
			},
			{
				root: null,
				rootMargin: "-30% 0px -60% 0px",
				threshold: [0, 0.25, 0.5, 0.75, 1],
			},
		);
		targets.forEach((t) => observer.observe(t));
		return () => observer.disconnect();
	});
</script>

<div class="report-view" data-testid="active-view-report">
	<ReportToc entries={ENTRIES} {activeSlug} {gameId} />

	<div class="report-body" bind:this={bodyEl}>
		<SectionGalaxySummary />
		<SectionVotes />
		<SectionPlayerStatus />
		<SectionMySciences />
		<SectionForeignSciences />
		<SectionMyShipClasses />
		<SectionForeignShipClasses />
		<SectionBattles />
		<SectionBombings />
		<SectionApproachingGroups />
		<SectionMyPlanets />
		<SectionShipsInProduction />
		<SectionCargoRoutes />
		<SectionForeignPlanets />
		<SectionUninhabitedPlanets />
		<SectionUnknownPlanets />
		<SectionMyFleets />
		<SectionMyShipGroups />
		<SectionForeignShipGroups />
		<SectionUnidentifiedGroups />
	</div>
</div>

<style>
	.report-view {
		display: grid;
		grid-template-columns: 14rem 1fr;
		gap: 1.25rem;
		padding: 1rem 1.25rem 2rem;
		font-family: system-ui, sans-serif;
	}
	.report-view > :global(.report-toc) {
		position: sticky;
		top: 0;
		align-self: start;
		padding: 0.5rem 0;
		max-height: calc(100vh - 4rem);
		overflow-y: auto;
	}
	.report-body {
		min-width: 0;
		display: flex;
		flex-direction: column;
		gap: 1.75rem;
	}
	@media (max-width: 767.98px) {
		.report-view {
			grid-template-columns: 1fr;
			padding: 0.75rem;
			gap: 0.75rem;
		}
		.report-view > :global(.report-toc) {
			position: sticky;
			top: 0;
			background: #0a0e1a;
			padding: 0.5rem 0;
			z-index: 5;
		}
	}
</style>
