<script lang="ts">
	import { get, post } from '$lib/api/client.ts';
	import type { QueueItem, Food } from '$lib/api/types.ts';

	let queue = $state<QueueItem[]>([]);
	let loading = $state(true);
	let tab = $state<'queue' | 'merge'>('queue');

	let mergeSourceQuery = $state('');
	let mergeTargetQuery = $state('');
	let mergeSource = $state<Food | null>(null);
	let mergeTarget = $state<Food | null>(null);
	let mergeSourceResults = $state<Food[]>([]);
	let mergeTargetResults = $state<Food[]>([]);
	let merging = $state(false);

	$effect(() => { loadQueue(); });

	async function loadQueue() {
		loading = true;
		try { queue = await get<QueueItem[]>('/api/resolution-queue'); }
		catch {} finally { loading = false; }
	}

	function parseCandidates(json: string | undefined): Array<{ food_id: string; name: string; score: number }> {
		if (!json) return [];
		try { return JSON.parse(json); } catch { return []; }
	}

	async function resolveItem(queueId: string, action: string, foodId?: string) {
		await post(`/api/resolution-queue/${queueId}/resolve`, { action, food_id: foodId });
		loadQueue();
	}

	async function searchMerge(query: string, which: 'source' | 'target') {
		if (!query.trim()) return;
		const results = await get<Food[]>(`/api/foods/search?q=${encodeURIComponent(query)}&limit=5`);
		if (which === 'source') mergeSourceResults = results;
		else mergeTargetResults = results;
	}

	async function doMerge() {
		if (!mergeSource || !mergeTarget) return;
		if (!confirm(`Merge "${mergeSource.name}" into "${mergeTarget.name}"? Source will be archived.`)) return;
		merging = true;
		try {
			await post('/api/foods/merge', { source_id: mergeSource.id, target_id: mergeTarget.id });
			mergeSource = null; mergeTarget = null;
			mergeSourceQuery = ''; mergeTargetQuery = '';
			alert('Merged successfully');
		} catch {} finally { merging = false; }
	}
</script>

<div class="max-w-3xl mx-auto px-4 py-6">
	<div class="mb-6">
		<h1 class="text-3xl font-bold">Admin</h1>
		<p class="text-base-content/50 text-sm mt-0.5">Review queue and manage duplicates</p>
	</div>

	<div role="tablist" class="tabs tabs-boxed mb-6">
		<button role="tab" class="tab gap-2" class:tab-active={tab === 'queue'} onclick={() => tab = 'queue'}>
			Review Queue
			{#if queue.length > 0}<span class="badge badge-sm badge-warning">{queue.length}</span>{/if}
		</button>
		<button role="tab" class="tab" class:tab-active={tab === 'merge'} onclick={() => tab = 'merge'}>Merge Foods</button>
	</div>

	{#if tab === 'queue'}
		{#if loading}
			<div class="flex justify-center py-12"><span class="loading loading-spinner loading-lg text-primary"></span></div>
		{:else if queue.length === 0}
			<div class="text-center py-16">
				<div class="p-4 rounded-2xl bg-success/15 inline-block mb-4">
				<svg xmlns="http://www.w3.org/2000/svg" class="h-10 w-10 text-success" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg>
			</div>
				<div class="text-base-content/50">No items to review</div>
				<div class="text-sm text-base-content/30 mt-1">All caught up!</div>
			</div>
		{:else}
			<div class="space-y-3">
				{#each queue as item}
					{@const candidates = parseCandidates(item.candidates_json)}
					<div class="rounded-xl border border-warning/20 bg-gradient-to-br from-warning/5 to-warning/0 p-5 shadow-sm card-hover">
						<div class="flex justify-between items-start mb-3">
							<div>
								<div class="font-bold text-lg">"{item.raw_text}"</div>
								<div class="flex gap-2 mt-1 text-xs text-base-content/40">
									{#if item.source}<span class="badge badge-xs badge-ghost">{item.source}</span>{/if}
									<span>confidence: {(item.confidence * 100).toFixed(0)}%</span>
									{#if item.meal_type}<span>{item.meal_type}</span>{/if}
									{#if item.entry_date}<span>{item.entry_date}</span>{/if}
								</div>
							</div>
							<button class="btn btn-ghost btn-sm" onclick={() => resolveItem(item.id, 'dismissed')}>Dismiss</button>
						</div>

						{#if candidates.length > 0}
							<div class="text-xs text-base-content/50 font-medium uppercase tracking-wide mb-2">Match to existing</div>
							<div class="space-y-1.5">
								{#each candidates as c}
									<button
										class="btn btn-sm btn-outline w-full justify-between"
										onclick={() => resolveItem(item.id, 'matched', c.food_id)}
									>
										<span>{c.name}</span>
										<span class="badge badge-sm badge-ghost">{(c.score * 100).toFixed(0)}%</span>
									</button>
								{/each}
							</div>
						{:else}
							<div class="text-sm text-base-content/30">No candidates — create a new food manually from the Foods page</div>
						{/if}
					</div>
				{/each}
			</div>
		{/if}

	{:else}
		<div class="rounded-xl border border-base-300 bg-base-200/50 p-6 shadow-md">
			<div class="flex items-center gap-3 mb-4">
				<div class="p-2 rounded-xl bg-secondary/15">
					<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-secondary" viewBox="0 0 20 20" fill="currentColor"><path d="M8 5a1 1 0 100 2h5.586l-1.293 1.293a1 1 0 001.414 1.414l3-3a1 1 0 000-1.414l-3-3a1 1 0 10-1.414 1.414L13.586 5H8zM12 15a1 1 0 100-2H6.414l1.293-1.293a1 1 0 10-1.414-1.414l-3 3a1 1 0 000 1.414l3 3a1 1 0 001.414-1.414L6.414 15H12z"/></svg>
				</div>
				<div>
					<h2 class="font-bold text-lg">Merge Duplicate Foods</h2>
					<p class="text-xs text-base-content/40">Source gets archived. Entries and aliases move to target.</p>
				</div>
			</div>

			<div class="grid grid-cols-1 sm:grid-cols-2 gap-6">
				<div>
					<div class="text-xs text-error font-medium uppercase tracking-wide mb-2">Source (will be archived)</div>
					<div class="flex gap-1 mb-2">
						<input class="input input-bordered input-sm flex-1" placeholder="Search..." bind:value={mergeSourceQuery} />
						<button class="btn btn-sm btn-ghost" onclick={() => searchMerge(mergeSourceQuery, 'source')}>Go</button>
					</div>
					{#if mergeSource}
						<div class="rounded-lg border border-error/30 bg-error/5 p-3 text-sm font-medium">{mergeSource.name}</div>
					{/if}
					{#each mergeSourceResults as f}
						<button class="btn btn-sm btn-ghost w-full justify-start mt-1 text-left" onclick={() => { mergeSource = f; mergeSourceResults = []; }}>
							{f.name}
						</button>
					{/each}
				</div>

				<div>
					<div class="text-xs text-success font-medium uppercase tracking-wide mb-2">Target (will keep)</div>
					<div class="flex gap-1 mb-2">
						<input class="input input-bordered input-sm flex-1" placeholder="Search..." bind:value={mergeTargetQuery} />
						<button class="btn btn-sm btn-ghost" onclick={() => searchMerge(mergeTargetQuery, 'target')}>Go</button>
					</div>
					{#if mergeTarget}
						<div class="rounded-lg border border-success/30 bg-success/5 p-3 text-sm font-medium">{mergeTarget.name}</div>
					{/if}
					{#each mergeTargetResults as f}
						<button class="btn btn-sm btn-ghost w-full justify-start mt-1 text-left" onclick={() => { mergeTarget = f; mergeTargetResults = []; }}>
							{f.name}
						</button>
					{/each}
				</div>
			</div>

			<button class="btn btn-warning w-full mt-6 gap-2" onclick={doMerge} disabled={!mergeSource || !mergeTarget || merging}>
				{#if merging}<span class="loading loading-spinner loading-sm"></span>{/if}
				Merge Foods
			</button>
		</div>
	{/if}
</div>
