<script lang="ts">
import * as m from '$lib/paraglide/messages.js';
import TimelineView from '$lib/timeline/TimelineView.svelte';
import TimelineFilters from '$lib/timeline/TimelineFilters.svelte';
import { timelineMeta } from '$lib/timeline/timelineMeta';
import { filterTimeline } from '$lib/timeline/timelineFilter';
import type { PageData } from './$types';

let { data }: { data: PageData } = $props();

const hasContent = $derived(data.timeline.years.length > 0 || data.timeline.undated.length > 0);

// Layer-filter state (#780). Layer hiding is client-side only — the whole
// timeline is loaded once by #779's SSR load and we derive a filtered view of
// it here; there is no goto, no URL param, and no extra fetch.
let personalOn = $state(true);
let historicalOn = $state(true);
let lettersOn = $state(true);

const filteredTimeline = $derived(
	filterTimeline(data.timeline, { personalOn, historicalOn, lettersOn })
);
const filteredEmpty = $derived(
	filteredTimeline.years.length === 0 && filteredTimeline.undated.length === 0
);

// Meta-line figures track the *filtered* view, so the header counts always
// match what is actually on screen once layers are toggled off (#780 — this
// closes the prior D1 limitation, where the counts stayed on the full timeline).
const meta = $derived(timelineMeta(filteredTimeline));

function resetFilters() {
	personalOn = true;
	historicalOn = true;
	lettersOn = true;
}

// Compose the sub-line from segments joined by " · " so the range drops out
// cleanly when there are no year bands; the whole line is absent when the
// timeline is empty (REQ-002). Counts come from the route alone, never from
// TimelineView.
const metaLine = $derived.by(() => {
	const segments: string[] = [];
	if (meta.firstYear !== null && meta.lastYear !== null) {
		segments.push(`${meta.firstYear}–${meta.lastYear}`);
	}
	// A zero-count segment ("0 Briefe") reads as a data error — drop it; a count
	// of one takes the singular key ("1 Brief"), per the project plural convention.
	if (meta.letterCount > 0) {
		segments.push(
			meta.letterCount === 1
				? m.timeline_letters_count_singular()
				: m.timeline_letters_count({ count: meta.letterCount })
		);
	}
	if (meta.eventCount > 0) {
		segments.push(
			meta.eventCount === 1
				? m.timeline_events_count_singular()
				: m.timeline_events_count({ count: meta.eventCount })
		);
	}
	// REQ-011: the toggle-free chronological view carries no grouping segment.
	return segments.join(' · ');
});
</script>

<svelte:head>
	<title>{m.timeline_heading()}</title>
</svelte:head>

<div class="mx-auto max-w-5xl px-4 py-8">
	<!-- The .tl-canvas sheet: a padded canvas surface for the timeline. The outer
	     border is intentionally omitted (the page is already bg-canvas), per the
	     review of REQ-001 — the sheet reads through its padding, not a frame line. -->
	<div data-testid="timeline-canvas" class="rounded-[10px] bg-canvas p-6">
		<!-- Wrapping header so the CTA drops below the heading at narrow widths
		     (≤360px) instead of overflowing — #842 REQ-001. -->
		<header class="flex flex-wrap items-center justify-between gap-3">
			<h1 class="font-serif text-2xl font-bold text-brand-navy">{m.timeline_heading()}</h1>
			{#if data.canWrite}
				<a
					data-testid="timeline-add-event"
					href="/zeitstrahl/events/new"
					class="inline-flex h-11 items-center rounded bg-primary px-4 font-sans text-sm font-medium text-primary-fg hover:opacity-90 focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
				>
					{m.timeline_add_event()}
				</a>
			{/if}
		</header>
		{#if hasContent}
			<p data-testid="timeline-meta" class="mt-1 mb-6 font-sans text-xs text-ink-3">{metaLine}</p>
			<TimelineFilters
				bind:personalOn={personalOn}
				bind:historicalOn={historicalOn}
				bind:lettersOn={lettersOn}
			/>
		{/if}
		{#if hasContent && filteredEmpty}
			<!-- Filtered-empty: a calm message + one-click reset below the still-open
			     filter bar — never a blank page, and never the generic "no events"
			     state (which would imply the archive itself is empty). REQ-006. -->
			<div data-testid="timeline-filter-empty" class="py-12 text-center">
				<p class="font-serif text-base text-ink-2">{m.timeline_filter_empty_state()}</p>
				<button
					type="button"
					data-testid="timeline-filter-empty-reset"
					onclick={resetFilters}
					class="mt-3 inline-flex min-h-[44px] items-center font-sans text-sm text-primary underline-offset-2 hover:underline"
				>
					{m.timeline_filter_reset()}
				</button>
			</div>
		{:else}
			<TimelineView timeline={filteredTimeline} canWrite={data.canWrite} />
		{/if}
	</div>
</div>
