<script lang="ts">
import * as m from '$lib/paraglide/messages.js';
import { slide } from 'svelte/transition';
import { hiddenLayerCount, isDefaultState, type TimelineLayerFilters } from './timelineFilter';

// Presentation-only layer filter for the global /zeitstrahl (#780, REQ-001).
// Holds no timeline data and never navigates or fetches — the route owns the
// $state and derives the filtered view. Three $bindable layer booleans plus an
// onChange notification hook are the whole contract.
let {
	personalOn = $bindable(true),
	historicalOn = $bindable(true),
	lettersOn = $bindable(true),
	onChange
}: {
	personalOn?: boolean;
	historicalOn?: boolean;
	lettersOn?: boolean;
	onChange?: () => void;
} = $props();

let open = $state(false);

// Reuse the reduced-motion guard expression from documents/[id]/+page.svelte:57
// for a new purpose — zeroing the slide duration so the collapsible opens
// instantly when the reader prefers reduced motion (REQ-009).
const prefersReducedMotion = $derived(
	typeof window !== 'undefined' && window.matchMedia('(prefers-reduced-motion: reduce)').matches
);
const slideDuration = $derived(prefersReducedMotion ? 0 : 200);

const filters: TimelineLayerFilters = $derived({ personalOn, historicalOn, lettersOn });
const hiddenCount = $derived(hiddenLayerCount(filters));
const anyLayerOff = $derived(!isDefaultState(filters));

function reset() {
	personalOn = true;
	historicalOn = true;
	lettersOn = true;
	onChange?.();
}
</script>

{#snippet layerToggle(label: string, testid: string, pressed: boolean, toggle: () => void)}
	<button
		type="button"
		data-testid={testid}
		aria-pressed={pressed}
		onclick={toggle}
		class="inline-flex min-h-[44px] items-center gap-2 rounded border px-3 font-sans text-sm transition-colors {pressed
			? 'border-primary bg-primary text-primary-fg'
			: 'border-line bg-muted text-ink-2 hover:bg-line'}"
	>
		<span
			aria-hidden="true"
			class="inline-flex h-4 w-4 items-center justify-center rounded-sm border {pressed
				? 'border-primary-fg bg-primary-fg/20'
				: 'border-ink-3'}"
		>
			{#if pressed}✓{/if}
		</span>
		{label}
	</button>
{/snippet}

<section class="mb-6">
	<!-- Sticky trigger kept in document flow so the hidden-layer count stays
	     visible without clipping timeline content (REQ-007). -->
	<div class="sticky top-16 z-20 bg-canvas py-2">
		<button
			type="button"
			data-testid="timeline-filter-trigger"
			aria-expanded={open}
			aria-controls={open ? 'timeline-filter-panel' : undefined}
			onclick={() => (open = !open)}
			class="inline-flex min-h-[44px] items-center gap-2 rounded border border-line bg-surface px-4 font-sans text-xs font-bold tracking-widest text-ink-2 uppercase transition-colors hover:bg-muted"
		>
			{hiddenCount === 0
				? m.timeline_filter_trigger()
				: m.timeline_filter_trigger_active({ count: hiddenCount })}
		</button>
	</div>

	{#if open}
		<div id="timeline-filter-panel" transition:slide={{ duration: slideDuration }}>
			<fieldset class="mt-2 rounded-sm border border-line bg-surface p-4">
				<legend class="px-1 font-sans text-xs font-bold tracking-widest text-ink-3 uppercase">
					{m.timeline_filter_label_layers()}
				</legend>
				<div class="flex flex-wrap gap-2">
					{@render layerToggle(
						m.timeline_filter_layer_personal(),
						'timeline-filter-personal',
						personalOn,
						() => {
							personalOn = !personalOn;
							onChange?.();
						}
					)}
					{@render layerToggle(
						m.timeline_filter_layer_historical(),
						'timeline-filter-historical',
						historicalOn,
						() => {
							historicalOn = !historicalOn;
							onChange?.();
						}
					)}
					{@render layerToggle(
						m.timeline_filter_layer_letters(),
						'timeline-filter-letters',
						lettersOn,
						() => {
							lettersOn = !lettersOn;
							onChange?.();
						}
					)}
				</div>

				{#if anyLayerOff}
					<button
						type="button"
						data-testid="timeline-filter-reset"
						onclick={reset}
						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>
				{/if}
			</fieldset>
		</div>
	{/if}
</section>
