<script lang="ts">
	import { page } from '$app/state';
	import { goto } from '$app/navigation';
	import { createQuery, useQueryClient } from '@tanstack/svelte-query';
	import { listProducts, getProductByBarcode } from '$lib/api/products';
	import { createEntry } from '$lib/api/entries';
	import type { Product } from '$lib/types/api';
	import TopBar from '$lib/components/ui/TopBar.svelte';
	import Sheet from '$lib/components/ui/Sheet.svelte';
	import BarcodeScanner from '$lib/components/ui/BarcodeScanner.svelte';
	import { kcal, g } from '$lib/utils/format';

	const date = $derived(page.params.date);
	const mealId = $derived(Number(page.url.searchParams.get('meal_id')));
	const queryClient = useQueryClient();

	let q = $state('');
	let debouncedQ = $state('');
	let debounceTimer: ReturnType<typeof setTimeout>;

	let selectedProduct = $state<Product | null>(null);
	let grams = $state(100);
	let submitting = $state(false);

	let scannerOpen = $state(false);
	let scanLoading = $state(false);
	let scanError = $state<string | null>(null);

	function handleSearch(value: string) {
		q = value;
		clearTimeout(debounceTimer);
		debounceTimer = setTimeout(() => { debouncedQ = value; }, 300);
	}

	const productsQuery = createQuery(() => ({
		queryKey: ['products', debouncedQ],
		queryFn: () => listProducts(debouncedQ, 30),
		staleTime: 0
	}));

	function selectProduct(product: Product) {
		selectedProduct = product;
		grams = 100;
	}

	async function handleBarcodeDetected(barcode: string) {
		scannerOpen = false;
		scanLoading = true;
		scanError = null;
		try {
			const product = await getProductByBarcode(barcode);
			selectProduct(product);
		} catch (err: any) {
			if (err?.status === 404) {
				goto(`/products/new?barcode=${encodeURIComponent(barcode)}`);
			} else {
				scanError = 'Could not look up barcode. Try searching manually.';
			}
		} finally {
			scanLoading = false;
		}
	}

	async function handleAddEntry() {
		if (!selectedProduct || !mealId) return;
		submitting = true;
		try {
			await createEntry(mealId, selectedProduct.id, grams);
			await queryClient.invalidateQueries({ queryKey: ['diary', date] });
			goto(`/diary/${date}`);
		} finally {
			submitting = false;
		}
	}

	const preview = $derived(selectedProduct ? {
		calories: Math.round(selectedProduct.calories * grams / 100),
		protein: Math.round(selectedProduct.protein * grams / 100 * 10) / 10,
		carb: Math.round(selectedProduct.carb * grams / 100 * 10) / 10,
		fat: Math.round(selectedProduct.fat * grams / 100 * 10) / 10,
	} : null);
</script>

{#if scannerOpen}
	<BarcodeScanner
		ondetect={handleBarcodeDetected}
		onclose={() => scannerOpen = false}
	/>
{/if}

<div class="flex flex-col h-screen">
	<TopBar title="Add food" back="/diary/{date}" />

	<!-- Search bar -->
	<div class="px-4 py-3 border-b border-zinc-800 bg-zinc-950">
		<div class="flex gap-2">
			<div class="relative flex-1">
				<svg class="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-zinc-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
					<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
				</svg>
				<input
					type="search"
					placeholder="Search foods…"
					value={q}
					oninput={(e) => handleSearch(e.currentTarget.value)}
					autofocus
					class="w-full bg-zinc-900 border border-zinc-700 rounded-xl pl-9 pr-4 py-2.5 text-sm text-zinc-100 placeholder-zinc-500 focus:outline-none focus:border-green-500 transition-colors"
				/>
			</div>

			<!-- Barcode scan button -->
			<button
				onclick={() => { scanError = null; scannerOpen = true; }}
				disabled={scanLoading}
				class="w-11 h-11 flex items-center justify-center rounded-xl bg-zinc-900 border border-zinc-700 text-zinc-400 hover:text-green-400 hover:border-green-500 disabled:opacity-50 transition-colors shrink-0"
				aria-label="Scan barcode"
			>
				{#if scanLoading}
					<svg class="w-5 h-5 animate-spin" fill="none" stroke="currentColor" viewBox="0 0 24 24">
						<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
					</svg>
				{:else}
					<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
						<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v1m0 14v1M4 12h1m14 0h1M6.343 6.343l.707.707m9.9 9.9.707.707M6.343 17.657l.707-.707m9.9-9.9.707-.707M12 8a4 4 0 100 8 4 4 0 000-8z" />
					</svg>
				{/if}
			</button>
		</div>

		{#if scanError}
			<p class="text-xs text-red-400 mt-2 px-1">{scanError}</p>
		{/if}
	</div>

	<!-- Results -->
	<main class="flex-1 overflow-y-auto">
		{#if productsQuery.isPending}
			<div class="space-y-px mt-2 px-4">
				{#each Array(6) as _}
					<div class="h-14 bg-zinc-900 rounded-xl animate-pulse mb-2"></div>
				{/each}
			</div>
		{:else if productsQuery.data?.products.length === 0}
			<div class="text-center text-zinc-500 mt-16 px-6">
				<p class="text-base">No products found</p>
				<p class="text-sm mt-1">Try a different name or</p>
				<a href="/products/new?name={encodeURIComponent(q)}" class="mt-3 inline-block text-green-500 text-sm">
					Create "{q || 'new product'}"
				</a>
			</div>
		{:else}
			<ul class="divide-y divide-zinc-800/50">
				{#each productsQuery.data?.products ?? [] as product (product.id)}
					<li>
						<button
							onclick={() => selectProduct(product)}
							class="w-full flex items-center justify-between px-4 py-3.5 hover:bg-zinc-900 transition-colors text-left"
						>
							<div class="min-w-0">
								<p class="font-medium text-sm truncate capitalize">{product.name}</p>
								<p class="text-xs text-zinc-500 mt-0.5">
									{kcal(product.calories)} kcal · P {g(product.protein)}g · C {g(product.carb)}g · F {g(product.fat)}g
									<span class="text-zinc-600">per 100g</span>
								</p>
							</div>
							<svg class="w-4 h-4 text-zinc-600 ml-3 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
								<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4" />
							</svg>
						</button>
					</li>
				{/each}
			</ul>
		{/if}
	</main>

	<!-- Grams sheet -->
	<Sheet
		open={selectedProduct !== null}
		onclose={() => selectedProduct = null}
		title={selectedProduct?.name ?? ''}
	>
		{#if selectedProduct}
			{#if preview}
				<div class="grid grid-cols-4 gap-2 mb-5">
					{#each [
						{ label: 'kcal', value: preview.calories },
						{ label: 'protein', value: preview.protein + 'g' },
						{ label: 'carbs', value: preview.carb + 'g' },
						{ label: 'fat', value: preview.fat + 'g' },
					] as m}
						<div class="bg-zinc-800 rounded-xl p-2.5 text-center">
							<p class="text-base font-semibold">{m.value}</p>
							<p class="text-xs text-zinc-500 mt-0.5">{m.label}</p>
						</div>
					{/each}
				</div>
			{/if}

			<label class="block text-sm text-zinc-400 mb-2">Grams</label>
			<div class="flex items-center gap-3 mb-5">
				<button
					onclick={() => grams = Math.max(1, grams - 10)}
					class="w-11 h-11 rounded-xl bg-zinc-800 hover:bg-zinc-700 transition-colors text-lg font-medium flex items-center justify-center"
				>−</button>
				<input
					type="number"
					bind:value={grams}
					min="1"
					max="5000"
					class="flex-1 bg-zinc-800 border border-zinc-700 rounded-xl px-4 py-2.5 text-center text-xl font-semibold focus:outline-none focus:border-green-500 transition-colors"
				/>
				<button
					onclick={() => grams = grams + 10}
					class="w-11 h-11 rounded-xl bg-zinc-800 hover:bg-zinc-700 transition-colors text-lg font-medium flex items-center justify-center"
				>+</button>
			</div>

			<button
				onclick={handleAddEntry}
				disabled={submitting || grams < 1}
				class="w-full bg-green-600 hover:bg-green-500 disabled:opacity-50 rounded-xl py-3 font-semibold transition-colors"
			>
				{submitting ? 'Adding…' : 'Add to meal'}
			</button>
		{/if}
	</Sheet>
</div>
