<script lang="ts">
	import { Debounced } from "runed";
	import { useSearchParams } from "runed/kit";
	import { onMount } from "svelte";
	import {
		ensureSeeded,
		getAnimeList,
		getClientDb,
		searchAnimeByName,
	} from "$lib/db/client-db";
	import { AmqBrowseSearchSchema } from "$lib/types/search/amq-browse";
	import { seasonName } from "$lib/utils/amq";

	const params = useSearchParams(AmqBrowseSearchSchema, {
		pushHistory: false,
		showDefaults: false,
	});

	let status = $state<"idle" | "loading" | "ready" | "error">("idle");
	let error = $state<string | null>(null);

	let isSearching = $state(false);

	// Debounce the actual DB query updates (separate from URL debounce)
	const debouncedQuery = new Debounced(() => params.q, 250);

	type AnimeItem = Awaited<ReturnType<typeof getAnimeList>>[number];
	let anime = $state<AnimeItem[]>([]);

	async function loadListFor(query: string) {
		const q = query.trim();

		try {
			isSearching = true;

			const { db } = getClientDb();

			if (!q) {
				anime = await getAnimeList(db, 20);
			} else {
				anime = await searchAnimeByName(db, q, 20);
			}
		} finally {
			isSearching = false;
		}
	}

	function animeHref(annId: number) {
		return `/anime/${annId}`;
	}

	async function loadInitial() {
		status = "loading";
		error = null;

		try {
			await ensureSeeded();
			await loadListFor(params.q);
			status = "ready";
		} catch (e) {
			error = e instanceof Error ? e.message : String(e);
			status = "error";
		}
	}

	onMount(() => {
		void loadInitial();
	});

	// React to debounced query changes (URL updates + user typing)
	$effect(() => {
		if (status !== "ready") return;

		// Track debounced query to avoid hammering the DB while typing
		const q = debouncedQuery.current;

		void (async () => {
			try {
				await loadListFor(q);
			} catch (e) {
				error = e instanceof Error ? e.message : String(e);
				status = "error";
			}
		})();
	});
</script>

<h1 class="text-2xl font-semibold">AMQ Browser</h1>

{#if status === "loading"}
	<p class="mt-3 text-sm text-muted-foreground">Loading client database…</p>
{:else if status === "error"}
	<p class="mt-3 text-sm text-red-600">Error: {error}</p>
{:else if status === "ready"}
	<div class="mt-3 flex flex-col gap-2">
		<label class="text-sm text-muted-foreground" for="anime-search">
			Search anime
		</label>
		<input
			id="anime-search"
			class="rounded border px-3 py-2 text-sm"
			placeholder="Type to search by name…"
			value={params.q}
			oninput={(e) => (params.q = (e.currentTarget as HTMLInputElement).value)}
			autocomplete="off"
			spellcheck={false}
		/>
		<p class="text-sm text-muted-foreground">
			{#if isSearching}
				Searching…
			{:else}
				Showing {anime.length} anime
			{/if}
		</p>
	</div>

	<ul class="mt-4 space-y-2">
		{#each anime as a (a.annId)}
			<li class="rounded border px-3 py-2">
				<a class="font-medium hover:underline" href={animeHref(a.annId)}>
					{a.mainName}
				</a>
				<div class="text-sm text-muted-foreground">
					{a.year}
					{seasonName(a.seasonId)} • ANN {a.annId} • MAL {a.malId}
				</div>
			</li>
		{/each}
	</ul>
{/if}
