<script lang="ts">
	import { Button } from '$lib/components/ui/button';
	import * as Tooltip from '$lib/components/ui/tooltip';
	import FlagIcon from 'phosphor-svelte/lib/FlagIcon';
	import ArrowRightIcon from 'phosphor-svelte/lib/ArrowRightIcon';
	import ArrowLeftIcon from 'phosphor-svelte/lib/ArrowLeftIcon';
	import XIcon from 'phosphor-svelte/lib/XIcon';
	import { goto } from '$app/navigation';
	import { page } from '$app/state';
	import {
		addValidation,
		evalUrl,
		nextUnreviewed,
		reviewedKeySet,
		type EvalCandidate
	} from '$lib/eval';
	import { toast } from 'svelte-sonner';
	import EvalFlagDialog from './eval-flag-dialog.svelte';

	interface Props {
		queue: EvalCandidate[];
		index: number;
		matchId: number;
		mapName: string;
		round: number;
	}
	let { queue, index, matchId, mapName, round }: Props = $props();

	let flagOpen = $state(false);
	// Bumped after each review action so the dialog count and the Next-skip
	// logic re-read localStorage without needing a reactive store.
	let reviewBump = $state(0);

	const reviewedCount = $derived.by(() => {
		void reviewBump;
		const reviewed = reviewedKeySet();
		let n = 0;
		for (const c of queue) if (reviewed.has(`${c.matchId}|${c.mapName}|${c.round}`)) n++;
		return n;
	});

	function next() {
		// Hitting Next without flagging implicitly validates the current candidate.
		if (round && index >= 0) {
			addValidation({ matchId, mapName, round });
			reviewBump++;
		}
		const ni = nextUnreviewed(queue, index < 0 ? -1 : index, reviewedKeySet());
		if (ni < 0) {
			toast.success('Evaluation complete', {
				description: `Reviewed ${reviewedCount + 1} / ${queue.length} candidates.`
			});
			return;
		}
		goto(evalUrl(queue[ni], ni));
	}

	function previous() {
		if (index <= 0) return;
		const pi = index - 1;
		goto(evalUrl(queue[pi], pi));
	}

	function exitEval() {
		const url = new URL(page.url);
		url.searchParams.delete('eval');
		url.searchParams.delete('i');
		goto(url.pathname + (url.searchParams.size ? '?' + url.searchParams.toString() : ''));
	}

	const total = $derived(queue.length);
	const positionLabel = $derived(index < 0 ? `— / ${total}` : `${index + 1} / ${total}`);
</script>

<div
	class="border-b border-amber-500/30 bg-amber-500/10 dark:border-amber-500/25 dark:bg-amber-500/[0.07]"
>
	<div class="mx-auto flex h-10 w-full max-w-[1600px] items-center gap-2 px-4 text-xs">
		<span class="font-mono font-semibold tracking-wide text-amber-700 uppercase dark:text-amber-300"
			>Eval</span
		>
		<span class="text-muted-foreground tabular-nums">{positionLabel}</span>
		<span class="text-muted-foreground/60 tabular-nums">·</span>
		<span class="text-muted-foreground tabular-nums">{reviewedCount} reviewed</span>

		<div class="ml-auto flex items-center gap-1">
			<Tooltip.Root>
				<Tooltip.Trigger>
					{#snippet child({ props })}
						<Button
							{...props}
							variant="ghost"
							size="icon-sm"
							onclick={previous}
							disabled={index <= 0}
							aria-label="Previous candidate"
						>
							<ArrowLeftIcon size={14} weight="bold" />
						</Button>
					{/snippet}
				</Tooltip.Trigger>
				<Tooltip.Content side="bottom">Previous candidate</Tooltip.Content>
			</Tooltip.Root>

			<Button variant="outline" size="sm" onclick={() => (flagOpen = true)}>
				<FlagIcon size={14} weight="fill" /> Flag
			</Button>

			<Button onclick={next} size="sm" disabled={total === 0}>
				Next <ArrowRightIcon size={14} weight="bold" />
			</Button>

			<Tooltip.Root>
				<Tooltip.Trigger>
					{#snippet child({ props })}
						<Button
							{...props}
							variant="ghost"
							size="icon-sm"
							onclick={exitEval}
							aria-label="Exit evaluation"
						>
							<XIcon size={14} weight="bold" />
						</Button>
					{/snippet}
				</Tooltip.Trigger>
				<Tooltip.Content side="bottom">Exit evaluation</Tooltip.Content>
			</Tooltip.Root>
		</div>
	</div>
</div>

<EvalFlagDialog
	bind:open={flagOpen}
	{matchId}
	{mapName}
	{round}
	queueLength={total}
	onChange={() => reviewBump++}
/>
