<script lang="ts">
	import { useSearchParams } from "runed/kit";
	import { onMount } from "svelte";
	import { z } from "zod";
	import { browser } from "$app/environment";
	import { invalidate } from "$app/navigation";
	import SongEntry from "$lib/components/SongEntry.svelte";
	import { db as clientDb } from "$lib/db/client-db";
	import { addAllToQueue, playAllNext } from "$lib/player/player.svelte";
	import { trackFromSongRow } from "$lib/player/types";
	import {
		MalAnimeListQuerySchema,
		MalAnimeListStatusEnum,
	} from "$lib/types/mal";
	import type { PageData } from "./$types";

	const ListSearchSchema = MalAnimeListQuerySchema.extend({
		// Allow empty string to mean "All"
		status: MalAnimeListStatusEnum.or(z.literal("")).default(""),
		// URL param `mal` is updated only on Search
		mal: z.string().default(""),
	}).strict();

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

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

	// Local username field that does NOT update the URL as you type.
	let formMal = $state<string>(params.mal);

	// If SSR returned no songRows (because client DB wasn't available),
	// re-run load on the client once the DB is ready by invalidating.
	onMount(() => {
		if (data.songRows.length > 0) return;
		if (!data.username || !data.malResponse) return;

		if (clientDb) {
			void invalidate("clientdb:songs");
			return;
		}
	});

	function songArtistLabel(r: (typeof data.songRows)[number]) {
		return r.artistName ?? r.groupName ?? null;
	}

	function makeMalHref(username: string) {
		return `https://myanimelist.net/profile/${encodeURIComponent(username)}`;
	}

	const tracksFromResults = $derived.by(() =>
		data.songRows
			.map((r) =>
				trackFromSongRow({
					annSongId: r.annSongId,
					animeName: r.animeName,
					type: r.type,
					number: r.number,
					songName: r.songName,
					artistName: songArtistLabel(r),
					fileName: r.fileName,
				}),
			)
			.filter((t) => t !== null),
	);
</script>

<h1 class="text-2xl font-semibold">MAL List → Songs</h1>

<p class="mt-2 text-sm text-muted-foreground">
	{#if !clientDb}
		Loading DB...
	{/if}
</p>

<form
	class="mt-4 flex flex-col gap-2"
	onsubmit={(e) => {
		e.preventDefault();
		params.mal = formMal;
	}}
>
	<div class="flex flex-wrap gap-2">
		<div class="flex flex-col gap-2">
			<label class="text-sm text-muted-foreground" for="mal-user"
				>MAL username</label
			>
			<input
				id="mal-user"
				class="rounded border px-3 py-2 text-sm"
				placeholder="e.g. CaZzzer"
				bind:value={formMal}
				autocomplete="off"
				spellcheck={false}
			/>
		</div>

		<div class="flex flex-col gap-2">
			<label class="text-sm text-muted-foreground" for="mal-status"
				>Status</label
			>
			<select
				id="mal-status"
				class="rounded border px-3 py-2 text-sm"
				bind:value={params.status}
			>
				<option value="">All</option>
				<option value="watching">Watching</option>
				<option value="completed">Completed</option>
				<option value="on_hold">On hold</option>
				<option value="dropped">Dropped</option>
				<option value="plan_to_watch">Plan to watch</option>
			</select>
		</div>

		<div class="flex flex-col justify-end">
			<button
				type="submit"
				class="rounded border px-3 py-2 text-sm"
				disabled={!(formMal ?? "").trim()}
			>
				Search
			</button>
		</div>
	</div>

	<div class="text-sm text-muted-foreground">
		{#if data.username}
			MAL entries: {data.malResponse?.data.length ?? 0} (limited to {data.LIST_QUERY_LIMIT})
			• Songs found: {data.songRows.length}
		{/if}
	</div>

	{#if data.songRows.length > 0}
		<div class="mt-3 flex flex-wrap gap-2">
			<button
				type="button"
				class="rounded border px-3 py-2 text-sm"
				onclick={() => addAllToQueue(tracksFromResults)}
				disabled={tracksFromResults.length === 0}
			>
				Add all to queue
			</button>

			<button
				type="button"
				class="rounded border px-3 py-2 text-sm"
				onclick={() => playAllNext(tracksFromResults)}
				disabled={tracksFromResults.length === 0}
			>
				Play all next
			</button>

			{#if tracksFromResults.length !== data.songRows.length}
				<span class="self-center text-sm text-muted-foreground">
					({tracksFromResults.length} playable)
				</span>
			{/if}
		</div>
	{/if}

	{#if data.username}
		<div class="text-sm">
			<a
				class="hover:underline"
				href={makeMalHref(data.username)}
				target="_blank"
				rel="noreferrer"
			>
				View {data.username} on MAL
			</a>
		</div>
	{/if}
</form>

{#if (formMal ?? "").trim() && data.username && (data.malResponse?.data.length ?? 0) === 0}
	<p class="mt-4 text-sm text-muted-foreground">
		No anime returned from MAL (did you set a restrictive status?).
	</p>
{/if}

{#if (formMal ?? "").trim() && data.username && (data.malResponse?.data.length ?? 0) > 0 && data.songRows.length === 0}
	<p class="mt-4 text-sm text-muted-foreground">
		No songs matched in the local database. This likely means none of the MAL
		anime IDs exist in the AMQ DB.
	</p>
{/if}

{#if data.songRows.length > 0}
	<h2 class="mt-6 text-lg font-semibold">Songs</h2>

	<ul class="mt-3 space-y-2">
		{#each data.songRows as r (String(r.annId) + ":" + String(r.annSongId))}
			<li>
				<SongEntry
					annSongId={r.annSongId}
					animeName={r.animeName}
					type={r.type}
					number={r.number}
					songName={r.songName}
					artistName={songArtistLabel(r)}
					fileName={r.fileName}
					globalPercent={r.globalPercent}
				/>
			</li>
		{/each}
	</ul>
{/if}

{#if browser && data.malResponse?.paging?.next}
	<p class="mt-6 text-sm text-muted-foreground">
		More results exist on MAL, but pagination is not wired yet.
	</p>
{/if}

{#if !browser}
	Loading stuff...
{/if}
