<script lang="ts">
	import { page } from '$app/stores';
	import { enhance } from '$app/forms';

	type Category = { id: string; name: string; tagType?: string };

	type EditRecipe = {
		id: string;
		name: string;
		serves?: number;
		cookTimeMin?: number;
		effort?: string;
		heroImageUrl?: string;
		ingredients: { name: string; quantity: number; unit: string }[];
		steps: { instruction: string }[];
		tagIds: string[];
	} | null;

	const { recipe, categories, action }: {
		recipe: EditRecipe;
		categories: Category[];
		action: string;
	} = $props();

	const effortOptions = [
		{ label: 'Leicht', value: 'easy' },
		{ label: 'Mittel', value: 'medium' },
		{ label: 'Schwer', value: 'hard' }
	];

	const initial = (() => $state.snapshot(recipe))();

	const TAG_TYPE_LABELS: Record<string, string> = {
		dietary: 'Ernährung',
		cuisine: 'Küche',
		protein: 'Protein',
		other: 'Sonstiges'
	};

	const groupedCategories = $derived(
		Object.entries(
			categories.reduce<Record<string, typeof categories>>((acc, cat) => {
				const type = cat.tagType ?? 'other';
				(acc[type] ??= []).push(cat);
				return acc;
			}, {})
		)
	);

	let name = $state(initial?.name ?? '');
	let serves = $state<number | ''>(initial?.serves ?? '');
	let cookTimeMin = $state<number | ''>(initial?.cookTimeMin ?? '');
	let effort = $state(initial?.effort ?? '');
	let selectedTagIds = $state<string[]>(initial?.tagIds ? [...initial.tagIds] : []);
	let ingredients = $state(
		initial?.ingredients.map((ing) => ({
			name: ing.name,
			quantity: ing.quantity as number | '',
			unit: ing.unit
		})) ?? [{ name: '', quantity: '' as number | '', unit: '' }]
	);
	let steps = $state(initial?.steps.map((s) => s.instruction) ?? ['']);
	let heroImageUrl = $state<string | null>(initial?.heroImageUrl ?? null);
	let imageError = $state<string | null>(null);

	const MAX_IMAGE_BYTES = 5 * 1024 * 1024;
	const ALLOWED_MIME_TYPES = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp'];

	function handleImageChange(e: Event) {
		const file = (e.currentTarget as HTMLInputElement).files?.[0];
		if (!file) return;
		if (file.size > MAX_IMAGE_BYTES) {
			imageError = 'Datei zu groß. Maximal 5 MB erlaubt.';
			(e.currentTarget as HTMLInputElement).value = '';
			return;
		}
		if (!ALLOWED_MIME_TYPES.includes(file.type)) {
			imageError = 'Dateityp nicht unterstützt. Erlaubt: JPEG, PNG, GIF, WebP.';
			(e.currentTarget as HTMLInputElement).value = '';
			return;
		}
		imageError = null;
		const reader = new FileReader();
		reader.onload = () => {
			heroImageUrl = reader.result as string;
		};
		reader.readAsDataURL(file);
	}
</script>

<form method="POST" {action} use:enhance>
	<!-- Error banner -->
	{#if $page.form?.error}
		<div
			role="alert"
			class="mb-[20px] rounded-[var(--radius-md)] bg-[color-mix(in_srgb,var(--color-error),transparent_90%)] px-[12px] py-[10px] text-[12px] text-[var(--color-error)]"
		>
			{$page.form.error}
		</div>
	{/if}

	<!-- Two-column layout -->
	<div class="md:flex md:gap-[32px]">
		<!-- Left column: main form fields -->
		<div class="md:flex-1">
			<!-- Basic info -->
			<div class="mb-[24px]">
				<div class="mb-[16px]">
					<label
						for="name"
						class="mb-[6px] block text-[12px] font-medium text-[var(--color-text)]"
					>
						Name
					</label>
					<input
						id="name"
						name="name"
						type="text"
						bind:value={name}
						required
						class="w-full rounded-[var(--radius-md)] border border-[var(--color-border)] bg-[var(--color-page)] px-[12px] py-[10px] font-[var(--font-sans)] text-[14px] text-[var(--color-text)] outline-none"
					/>
				</div>

				<div class="mb-[16px]">
					<label
						for="serves"
						class="mb-[6px] block text-[12px] font-medium text-[var(--color-text)]"
					>
						Portionen
					</label>
					<input
						id="serves"
						name="serves"
						type="number"
						bind:value={serves}
						class="w-full rounded-[var(--radius-md)] border border-[var(--color-border)] bg-[var(--color-page)] px-[12px] py-[10px] font-[var(--font-sans)] text-[14px] text-[var(--color-text)] outline-none"
					/>
				</div>

				<div class="mb-[16px]">
					<label
						for="cookTimeMin"
						class="mb-[6px] block text-[12px] font-medium text-[var(--color-text)]"
					>
						Kochzeit (min)
					</label>
					<input
						id="cookTimeMin"
						name="cookTimeMin"
						type="number"
						bind:value={cookTimeMin}
						class="w-full rounded-[var(--radius-md)] border border-[var(--color-border)] bg-[var(--color-page)] px-[12px] py-[10px] font-[var(--font-sans)] text-[14px] text-[var(--color-text)] outline-none"
					/>
				</div>
			</div>

			<!-- Effort chips -->
			<div class="mb-[24px]">
				<p class="mb-[12px] text-[13px] font-medium text-[var(--color-text)]">
					Schwierigkeitsgrad
				</p>
				<div class="flex flex-wrap gap-[8px]">
					{#each effortOptions as opt (opt.value)}
						<label
							class={[
								'cursor-pointer rounded-[var(--radius-full)] border px-[12px] py-[6px] text-[13px] font-medium',
								effort === opt.value
									? 'bg-[var(--green-tint)] border-[var(--green-dark)] text-[var(--green-dark)]'
									: 'bg-white border-[var(--color-border)] text-[var(--color-text-muted)]'
							].join(' ')}
						>
							<input
								type="radio"
								name="effort"
								value={opt.value}
								bind:group={effort}
								class="sr-only"
							/>
							{opt.label}
						</label>
					{/each}
				</div>
			</div>

			<!-- Image -->
			<div class="mb-[24px]">
				<p class="mb-[12px] text-[13px] font-medium text-[var(--color-text)]">Bild</p>
				{#if heroImageUrl}
					<img
						src={heroImageUrl}
						alt=""
						class="mb-[8px] max-h-[200px] w-full rounded-[var(--radius-md)] object-cover"
					/>
					<button
						type="button"
						onclick={() => (heroImageUrl = null)}
						class="mb-[8px] text-[12px] text-[var(--color-error)] opacity-60 hover:opacity-100 cursor-pointer"
					>
						Bild entfernen
					</button>
				{/if}
				<label
					class="block w-full cursor-pointer rounded-[var(--radius-md)] border border-[var(--color-border)] bg-[var(--color-page)] px-[12px] py-[10px] text-center text-[13px] text-[var(--color-text-muted)]"
				>
					<input
						type="file"
						accept="image/*"
						onchange={handleImageChange}
						class="sr-only"
					/>
					{heroImageUrl ? 'Bild ändern' : 'Bild hochladen'}
				</label>
				{#if imageError}
					<p class="mt-[6px] text-[12px] text-[var(--color-error)]">{imageError}</p>
				{:else}
					<p class="mt-[6px] text-[11px] text-[var(--color-text-muted)]">Max. 5 MB</p>
				{/if}
				<input type="hidden" name="heroImageUrl" value={heroImageUrl ?? ''} />
			</div>

			<!-- Ingredients -->
			<div class="mb-[24px]">
				<p class="mb-[12px] text-[13px] font-medium text-[var(--color-text)]">Zutaten</p>
				<div class="flex flex-col gap-[8px]">
					{#each ingredients as ing, i (i)}
						<div class="flex items-center gap-[8px]">
							<input
								type="number"
								bind:value={ing.quantity}
								placeholder="Menge"
								class="w-[80px] rounded-[var(--radius-md)] border border-[var(--color-border)] bg-[var(--color-page)] px-[12px] py-[10px] font-[var(--font-sans)] text-[14px] text-[var(--color-text)] outline-none"
							/>
							<input
								type="text"
								bind:value={ing.unit}
								placeholder="Einheit"
								class="w-[80px] rounded-[var(--radius-md)] border border-[var(--color-border)] bg-[var(--color-page)] px-[12px] py-[10px] font-[var(--font-sans)] text-[14px] text-[var(--color-text)] outline-none"
							/>
							<input
								type="text"
								bind:value={ing.name}
								placeholder="Zutat"
								class="flex-1 rounded-[var(--radius-md)] border border-[var(--color-border)] bg-[var(--color-page)] px-[12px] py-[10px] font-[var(--font-sans)] text-[14px] text-[var(--color-text)] outline-none"
							/>
							<button
								type="button"
								onclick={() => (ingredients = ingredients.filter((_, j) => j !== i))}
								class="shrink-0 text-[12px] text-[var(--color-text-muted)] hover:text-[var(--color-error)] cursor-pointer"
							>
								Entfernen
							</button>
						</div>
					{/each}
				</div>
				<button
					type="button"
					onclick={() => (ingredients = [...ingredients, { name: '', quantity: '' as number | '', unit: '' }])}
					class="mt-[12px] text-[13px] font-medium text-[var(--green-dark)] cursor-pointer"
				>
					Zutat hinzufügen
				</button>
			</div>

			<!-- Steps -->
			<div class="mb-[24px]">
				<p class="mb-[12px] text-[13px] font-medium text-[var(--color-text)]">Schritte</p>
				<div class="flex flex-col gap-[12px]">
					{#each steps as _, i (i)}
						<div class="flex items-start gap-[12px]">
							<span
								class="flex h-[28px] w-[28px] shrink-0 items-center justify-center rounded-full bg-[var(--green-tint)] text-[12px] font-medium text-[var(--green-dark)]"
							>
								{i + 1}
							</span>
							<div class="flex flex-1 flex-col gap-[6px]">
								<textarea
									bind:value={steps[i]}
									placeholder="Schritt beschreiben…"
									rows="3"
									class="w-full rounded-[var(--radius-md)] border border-[var(--color-border)] bg-[var(--color-page)] px-[12px] py-[10px] font-[var(--font-sans)] text-[14px] text-[var(--color-text)] outline-none resize-none"
								></textarea>
								<button
									type="button"
									onclick={() => (steps = steps.filter((_, j) => j !== i))}
									class="self-start text-[12px] text-[var(--color-text-muted)] hover:text-[var(--color-error)] cursor-pointer"
								>
									Entfernen
								</button>
							</div>
						</div>
					{/each}
				</div>
				<button
					type="button"
					onclick={() => (steps = [...steps, ''])}
					class="mt-[12px] text-[13px] font-medium text-[var(--green-dark)] cursor-pointer"
				>
					Schritt hinzufügen
				</button>
			</div>
		</div>

		<!-- Right panel: categories -->
		<div class="md:w-[280px] md:flex-shrink-0 mt-[24px] md:mt-0">
			<div
				class="rounded-[var(--radius-md)] border border-[var(--color-border)] bg-[var(--color-surface)] p-[20px]"
			>
				<p class="mb-[16px] text-[13px] font-medium text-[var(--color-text)]">Kategorien</p>
				{#each groupedCategories as [type, tags] (type)}
					<div class="mb-[16px] last:mb-0">
						<p class="mb-[8px] text-[11px] font-medium uppercase tracking-wide text-[var(--color-text-muted)]">
							{TAG_TYPE_LABELS[type] ?? type}
						</p>
						<div class="flex flex-wrap gap-[8px]">
							{#each tags as cat (cat.id)}
								<label
									class={[
										'cursor-pointer rounded-[var(--radius-full)] border px-[12px] py-[6px] text-[13px] font-medium',
										selectedTagIds.includes(cat.id)
											? 'bg-[var(--green-tint)] border-[var(--green-dark)] text-[var(--green-dark)]'
											: 'bg-white border-[var(--color-border)] text-[var(--color-text-muted)]'
									].join(' ')}
								>
									<input
										type="checkbox"
										name="tagIds"
										value={cat.id}
										checked={selectedTagIds.includes(cat.id)}
										onchange={(e) => {
											if (e.currentTarget.checked) {
												selectedTagIds = [...selectedTagIds, cat.id];
											} else {
												selectedTagIds = selectedTagIds.filter((id) => id !== cat.id);
											}
										}}
										class="sr-only"
									/>
									{cat.name}
								</label>
							{/each}
						</div>
					</div>
				{/each}
			</div>
		</div>
	</div>

	<!-- Hidden inputs for form submission -->
	<input type="hidden" name="ingredientsJson" value={JSON.stringify(ingredients)} />
	<input type="hidden" name="stepsJson" value={JSON.stringify(steps)} />

	<!-- Footer -->
	<div class="mt-[32px] flex items-center justify-between">
		<a
			href="/recipes"
			class="text-[13px] font-medium text-[var(--color-text-muted)] hover:text-[var(--color-text)]"
		>
			Abbrechen
		</a>
		<button
			type="submit"
			class="rounded-[var(--radius-md)] bg-[var(--green-dark)] px-[24px] py-[12px] text-[var(--btn-font-size)] font-[var(--btn-font-weight)] tracking-[var(--btn-letter-spacing)] text-white cursor-pointer"
		>
			Speichern
		</button>
	</div>
</form>
