<script lang="ts">
import { goto } from '$app/navigation';
import { navigating } from '$app/state';
import { untrack } from 'svelte';
import { SvelteURLSearchParams } from 'svelte/reactivity';
import SearchFilterBar from '../SearchFilterBar.svelte';
import DocumentList from '../DocumentList.svelte';
import * as m from '$lib/paraglide/messages.js';

let { data } = $props();

// Local state initialised from server-returned filter values.
// untrack() prevents infinite reactive loops during initialisation.
let q = $state(untrack(() => data.q || ''));
let qFocused = $state(false);
let from = $state(untrack(() => data.from || ''));
let to = $state(untrack(() => data.to || ''));
let senderId = $state(untrack(() => data.senderId || ''));
let receiverId = $state(untrack(() => data.receiverId || ''));
let tagNames = $state<{ name: string; id?: string; color?: string; parentId?: string }[]>(
	untrack(() => (data.tags || []).map((name: string) => ({ name })))
);
let sort = $state(untrack(() => data.sort || 'DATE'));
let dir = $state(untrack(() => data.dir || 'desc'));
let tagQ = $state(untrack(() => data.tagQ || ''));
let tagOperator = $state<'AND' | 'OR'>(untrack(() => (data.tagOp as 'AND' | 'OR') || 'AND'));

function hasAdvancedFilters() {
	return (
		(data.tags?.length ?? 0) > 0 || !!data.senderId || !!data.receiverId || !!data.from || !!data.to
	);
}

let showAdvanced = $state(untrack(hasAdvancedFilters));

let searchTimer: ReturnType<typeof setTimeout>;

function triggerSearch() {
	const params = new SvelteURLSearchParams();
	if (q) params.set('q', q);
	if (from) params.set('from', from);
	if (to) params.set('to', to);
	if (senderId) params.set('senderId', senderId);
	if (receiverId) params.set('receiverId', receiverId);
	tagNames.forEach((tag) => params.append('tag', tag.name));
	if (sort) params.set('sort', sort);
	if (dir) params.set('dir', dir);
	if (tagQ) params.set('tagQ', tagQ);
	if (tagOperator === 'OR') params.set('tagOp', 'OR');
	goto(`/documents?${params.toString()}`, { keepFocus: true, noScroll: true });
}

function handleTextSearch() {
	clearTimeout(searchTimer);
	searchTimer = setTimeout(() => triggerSearch(), 500);
}

function handleImmediateSearch() {
	clearTimeout(searchTimer);
	triggerSearch();
}

// Trigger search reactively when the tag list changes.
let prevTagStr = untrack(() => tagNames.map((t) => t.name).join(','));
$effect(() => {
	const cur = tagNames.map((t) => t.name).join(',');
	if (cur !== prevTagStr) {
		prevTagStr = cur;
		triggerSearch();
	}
});

// Keep local filter state in sync with server data after navigation completes.
// Guard q: skip overwrite while the user is actively typing.
$effect(() => {
	if (!qFocused) q = data.q || '';
	from = data.from || '';
	to = data.to || '';
	senderId = data.senderId || '';
	receiverId = data.receiverId || '';
	tagNames = (data.tags || []).map((name: string) => ({ name }));
	sort = data.sort || 'DATE';
	dir = data.dir || 'desc';
	tagQ = data.tagQ || '';
	tagOperator = (data.tagOp as 'AND' | 'OR') || 'AND';
	if (hasAdvancedFilters()) showAdvanced = true;
});
</script>

<svelte:head>
	<title>{m.nav_documents()} – Familienarchiv</title>
</svelte:head>

<main class="mx-auto max-w-7xl px-4 py-8 font-sans sm:px-6 lg:px-8">
	<h1 class="sr-only">{m.nav_documents()}</h1>

	<SearchFilterBar
		bind:q={q}
		bind:from={from}
		bind:to={to}
		bind:senderId={senderId}
		bind:receiverId={receiverId}
		bind:tagNames={tagNames}
		bind:showAdvanced={showAdvanced}
		bind:sort={sort}
		bind:dir={dir}
		bind:tagQ={tagQ}
		bind:tagOperator={tagOperator}
		isLoading={navigating.to !== null}
		onSearch={handleTextSearch}
		onSearchImmediate={handleImmediateSearch}
		onfocus={() => (qFocused = true)}
		onblur={() => (qFocused = false)}
	/>

	<DocumentList
		items={data.items}
		total={data.total}
		q={data.q}
		canWrite={data.canWrite}
		error={data.error}
		sort={sort}
	/>
</main>
