<script lang="ts">
	import { useSearchParams } from "runed/kit";
	import { onMount } from "svelte";
	import { browser } from "$app/environment";
	import { invalidate } from "$app/navigation";
	import SongEntry from "$lib/components/SongEntry.svelte";
	import { Button } from "$lib/components/ui/button";
	import { Input } from "$lib/components/ui/input";
	import { Label } from "$lib/components/ui/label";
	import {
		NativeSelect,
		NativeSelectOption,
	} from "$lib/components/ui/native-select";
	import { db as clientDb } from "$lib/db/client-db";
	import { addAllToQueue, playAllNext } from "$lib/player/player.svelte";
	import { trackFromSongRow } from "$lib/player/types";
	import type { PageData } from "./$types";
	import { SearchParamsSchemaClient } from "./schema";

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

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

	// 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 (clientDb) {
			void invalidate("clientdb:songs");
			return;
		}
	});

	function songArtistLabel(r: (typeof data.songRows)[number]) {
		// Use animeMainName as the primary anime name for display
		return r.artistName ?? r.groupName ?? null;
	}

	const tracksFromResults = $derived.by(() =>
		data.songRows
			.map((r) =>
				trackFromSongRow({
					annSongId: r.annSongId,
					animeName: r.animeMainName, // Use animeMainName from the query result
					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">Songs Search</h1>

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

<form class="mt-4 flex flex-col gap-4">
	<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
		<div class="flex flex-col gap-2">
			<Label for="anime-name">Anime Name</Label>
			<Input
				id="anime-name"
				placeholder="e.g. Bakemonogatari"
				bind:value={params.anime}
				autocomplete="off"
				spellcheck={false}
			/>
		</div>
		<div class="flex flex-col gap-2">
			<Label for="song-name">Song Name</Label>
			<Input
				id="song-name"
				placeholder="e.g. Renai Circulation"
				bind:value={params.song}
				autocomplete="off"
				spellcheck={false}
			/>
		</div>

		<div class="flex flex-col gap-2">
			<Label for="artist-name">Artist Name</Label>
			<Input
				id="artist-name"
				placeholder="e.g. Kana Hanazawa"
				bind:value={params.artist}
				autocomplete="off"
				spellcheck={false}
			/>
		</div>

		<div class="flex flex-col gap-2">
			<Label for="global-percent-min">Global Percent Range</Label>
			<div class="flex gap-2">
				<Input
					id="global-percent-min"
					type="number"
					min="0"
					max="100"
					class="w-1/2"
					placeholder="Min (0-100)"
					bind:value={params.gpm}
				/>
				<Input
					id="global-percent-max"
					type="number"
					min="0"
					max="100"
					class="w-1/2"
					placeholder="Max (0-100)"
					bind:value={params.gpx}
				/>
			</div>
		</div>
		<div class="flex flex-col gap-2">
			<Label for="song-type">Song Type</Label>
			<NativeSelect id="song-type" bind:value={params.songType}>
				<NativeSelectOption value="0">All</NativeSelectOption>
				<NativeSelectOption value="1">OP</NativeSelectOption>
				<NativeSelectOption value="2">ED</NativeSelectOption>
				<NativeSelectOption value="3">INS</NativeSelectOption>
			</NativeSelect>
		</div>
		<div class="flex flex-col gap-2">
			<Label for="songs-limit">Limit</Label>
			<Input
				id="songs-limit"
				type="number"
				min="20"
				max="200"
				step="20"
				class="w-1/2"
				bind:value={params.songsLimit}
			/>
		</div>
	</div>
</form>

{#if data.songRows.length > 0}
	<div class="mt-6 flex flex-col gap-2">
		<div class="flex flex-wrap gap-2">
			<Button
				variant="outline"
				class="cursor-pointer"
				onclick={() => addAllToQueue(tracksFromResults)}
				disabled={tracksFromResults.length === 0}
			>
				Add all to queue
			</Button>

			<Button
				variant="outline"
				class="cursor-pointer"
				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>

		<div class="flex items-center gap-4">
			<h2 class="text-lg font-semibold">Songs</h2>
			<span>{data.songRows.length}</span>
		</div>

		<ul class="space-y-2">
			{#each data.songRows as r (r.annSongId)}
				<li>
					<SongEntry
						annSongId={r.annSongId}
						animeName={r.animeMainName}
						type={r.type}
						number={r.number}
						songName={r.songName}
						artistName={songArtistLabel(r)}
						fileName={r.fileName}
					/>
				</li>
			{/each}
		</ul>
	</div>
{:else if Object.values(params).some((val) => (Array.isArray(val) && val.length > 0) || (typeof val === "string" && val.trim() !== "") || typeof val === "number")}
	<p class="mt-4 text-sm text-muted-foreground">
		No songs found matching your criteria.
	</p>
{:else}
	<p class="mt-4 text-sm text-muted-foreground">
		Use the filters above to search for songs.
	</p>
{/if}

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