<script lang="ts">
	import { goto, invalidateAll } from '$app/navigation';
	import { enhance } from '$app/forms';
	import { tick } from 'svelte';
	import VarietyScoreCard from '$lib/planner/VarietyScoreCard.svelte';
	import WeekStrip from '$lib/planner/WeekStrip.svelte';
	import DayMealCard from '$lib/planner/DayMealCard.svelte';
	import RecipePicker from '$lib/planner/RecipePicker.svelte';
	import MealActionSheet from '$lib/planner/MealActionSheet.svelte';
	import SwapSuggestionList from '$lib/planner/SwapSuggestionList.svelte';
	import BottomSheet from '$lib/components/BottomSheet.svelte';
	import UndoBar from '$lib/planner/UndoBar.svelte';
	import { prevWeek, nextWeek, getWeekStart, weekDays, formatDayLabel, formatDayAbbr, formatWeekRange, sortEasiestFirst } from '$lib/planner/week';

	let { data, form = null }: { data: { weekPlan: any; varietyScore: any; weekStart: string; recipes: any[] }; form?: any } = $props();

	// Use UTC date string (YYYY-MM-DD) consistently
	const today: string = new Date().toISOString().slice(0, 10);

	let weekStart = $derived(data.weekStart);
	let weekPlan = $derived(data.weekPlan);
	let varietyScore = $derived(data.varietyScore);

	let days = $derived(weekDays(weekStart));
	let slots = $derived(weekPlan?.slots ?? []);
	let slotMap = $derived(Object.fromEntries(slots.map((s: any) => [s.slotDate, s])));

	// Default selected day: today if in this week, else first day
	// We read data.weekStart once synchronously here (before reactivity kicks in) to seed the initial value.
	let selectedDay = $state((() => {
		const init = data.weekStart;
		const d = weekDays(init);
		return d.includes(today) ? today : d[0];
	})());

	// When week changes via navigation, reset selected day
	$effect(() => {
		const newDays = weekDays(weekStart);
		if (!newDays.includes(selectedDay)) {
			selectedDay = newDays.includes(today) ? today : newDays[0];
		}
	});

	let selectedSlot = $derived(slotMap[selectedDay] ?? { id: null, slotDate: selectedDay, recipe: null });
	let remainingSlots = $derived(days.filter((d: string) => d > selectedDay).map((d: string) => slotMap[d] ?? { id: null, slotDate: d, recipe: null }));
	let remainingSlotsWithMeal = $derived(remainingSlots.filter((s: any) => s.recipe));

	let isPlanner = $derived((data as any).benutzer?.rolle === 'planer');

	let weekRange = $derived(formatWeekRange(weekStart));

	// Desktop right panel state machine
	type PanelState =
		| { kind: 'idle' }
		| { kind: 'day-detail'; date: string }
		| { kind: 'recipe-picker'; date: string };

	let panelState = $state<PanelState>({ kind: 'idle' });

	// Mobile bottom sheet for RecipePicker (empty slot) and swap flow
	let pickerOpen = $state(false);
	let actionSheetOpen = $state(false);
	let swapSheetOpen = $state(false);
	let swapLoading = $state(false);

	// Recipes already in any slot this week — used for ⚠ overlap warnings
	let currentWeekRecipeIds = $derived(
		new Set<string>(slots.filter((s: any) => s.recipe?.id).map((s: any) => s.recipe.id))
	);

	// Recipes sorted easiest-first for the swap suggestion list
	let sortedRecipes = $derived(sortEasiestFirst(data.recipes));

	// Hidden form field bindings
	let addPlanId = $state('');
	let addSlotDate = $state('');
	let addRecipeId = $state('');
	let addRecipeName = $state('');
	let updPlanId = $state('');
	let updSlotId = $state('');
	let updRecipeId = $state('');
	let updRecipeName = $state('');
	let delPlanId = $state('');
	let delSlotId = $state('');

	let addSlotFormEl: HTMLFormElement;
	let updateSlotFormEl: HTMLFormElement;
	let deleteSlotFormEl: HTMLFormElement;

	// UndoBar
	let undoVisible = $state(false);
	let undoMessage = $state('');

	function handleSelectDay(day: string) {
		selectedDay = day;
		panelState = { kind: 'day-detail', date: day };
	}

	async function navigateWeek(direction: 'prev' | 'next' | 'today') {
		let newWeekStart: string;
		if (direction === 'prev') newWeekStart = prevWeek(weekStart);
		else if (direction === 'next') newWeekStart = nextWeek(weekStart);
		else newWeekStart = getWeekStart(new Date());

		await goto(`/planner?week=${newWeekStart}`, { invalidateAll: true });
	}

	async function handleRecipePick(recipeId: string, recipeName: string) {
		// Capture date before modifying panel state
		const date = panelState.kind === 'recipe-picker' ? panelState.date : selectedDay;

		// Close pickers
		pickerOpen = false;
		if (panelState.kind === 'recipe-picker') {
			panelState = { kind: 'idle' };
		}

		const existingSlot = slotMap[date];

		if (existingSlot?.id) {
			updPlanId = weekPlan!.id;
			updSlotId = existingSlot.id;
			updRecipeId = recipeId;
			updRecipeName = recipeName;
			await tick();
			updateSlotFormEl.requestSubmit();
		} else {
			addPlanId = weekPlan!.id;
			addSlotDate = date;
			addRecipeId = recipeId;
			addRecipeName = recipeName;
			await tick();
			addSlotFormEl.requestSubmit();
		}
	}

	function handleUndo() {
		undoVisible = false;
		deleteSlotFormEl.requestSubmit();
	}

	async function handleSwapPick(recipeId: string, recipeName: string) {
		swapLoading = true;
		await handleRecipePick(recipeId, recipeName);
		swapSheetOpen = false;
		swapLoading = false;
	}

	function closePanelToIdle() {
		panelState = { kind: 'idle' };
	}

	function closePanelToDayDetail() {
		if (panelState.kind === 'recipe-picker') {
			panelState = { kind: 'day-detail', date: panelState.date };
		} else {
			panelState = { kind: 'idle' };
		}
	}
</script>

<!-- Mobile & Tablet: vertical stack -->
<div class="flex h-full flex-col lg:hidden">
	<!-- Top nav (sticky) -->
	<header class="sticky top-0 z-10 flex items-center justify-between border-b border-[var(--color-border)] bg-[var(--color-page)] px-4 py-3">
		<h1 class="font-[var(--font-display)] text-[20px] font-[300] text-[var(--color-text)]">Diese Woche</h1>
		<div class="flex items-center gap-2">
			<button
				type="button"
				onclick={() => navigateWeek('prev')}
				aria-label="Vorherige Woche"
				class="flex min-h-[40px] min-w-[40px] items-center justify-center rounded-[var(--radius-md)] border border-[var(--color-border)] text-[var(--color-text)] hover:bg-[var(--color-surface)]"
			>
				‹
			</button>
			<button
				type="button"
				onclick={() => navigateWeek('next')}
				aria-label="Nächste Woche"
				class="flex min-h-[40px] min-w-[40px] items-center justify-center rounded-[var(--radius-md)] border border-[var(--color-border)] text-[var(--color-text)] hover:bg-[var(--color-surface)]"
			>
				›
			</button>
			{#if isPlanner}
				<button
					type="button"
					onclick={() => (pickerOpen = true)}
					class="rounded-[var(--radius-md)] bg-[var(--green-dark)] px-3 py-1.5 text-[13px] font-medium tracking-[0.04em] font-[var(--font-sans)] text-white"
				>
					+ Gericht
				</button>
			{/if}
		</div>
	</header>

	<!-- Variety banner: sticky below the top nav so it's always visible (spec requirement) -->
	{#if varietyScore}
		<div class="sticky z-10 px-4 pt-3" style="top: 56px;">
			<VarietyScoreCard
				score={varietyScore.score ?? 0}
				ingredientOverlaps={varietyScore.ingredientOverlaps ?? []}
				showReviewLink={false}
			/>
		</div>
	{/if}

	<!-- Day strip -->
	<div class="px-4 pt-3">
		<WeekStrip
			{weekStart}
			{slots}
			{selectedDay}
			{today}
			onselectDay={handleSelectDay}
		/>
	</div>

	<!-- Selected day card -->
	<div class="px-4 pt-4">
		<p class="mb-2 font-[var(--font-sans)] text-[12px] font-medium uppercase tracking-wide text-[var(--color-text-muted)]">
			{formatDayLabel(selectedDay)}
		</p>
		<DayMealCard
			slot={selectedSlot}
			isToday={selectedDay === today}
			isSelected={true}
			readonly={!isPlanner}
			onactionsheet={isPlanner && selectedSlot.recipe ? () => (actionSheetOpen = true) : undefined}
			onaddrecipe={isPlanner && !selectedSlot.recipe ? () => (pickerOpen = true) : undefined}
		/>
	</div>

	<!-- Remaining days list -->
	{#if remainingSlotsWithMeal.length > 0}
		<div class="px-4 pt-6 pb-4">
			<h2 class="mb-3 font-[var(--font-sans)] text-[12px] font-medium uppercase tracking-wide text-[var(--color-text-muted)]">
				Restliche Woche
			</h2>
			<div class="space-y-2 md:grid md:grid-cols-2 md:gap-2 md:space-y-0">
				{#each remainingSlotsWithMeal as slot (slot.slotDate)}
					<button
						type="button"
						onclick={() => handleSelectDay(slot.slotDate)}
						class="flex w-full items-center gap-3 rounded-[var(--radius-md)] border border-[var(--color-border)] bg-[var(--color-surface)] px-3 py-2 text-left hover:border-[var(--green-light)]"
					>
						<span class="min-w-[36px] font-[var(--font-sans)] text-[12px] text-[var(--color-text-muted)]">
							{formatDayLabel(slot.slotDate).split(',')[0]}
						</span>
						<span class="flex-1 truncate font-[var(--font-sans)] text-[14px] font-medium text-[var(--color-text)]">
							{slot.recipe?.name}
						</span>
						{#if isPlanner}
							<span class="font-[var(--font-sans)] text-[12px] text-[var(--color-text-muted)]">→</span>
						{/if}
					</button>
				{/each}
			</div>
		</div>
	{/if}

	<!-- Empty week state -->
	{#if !weekPlan}
		<div class="flex flex-1 flex-col items-center justify-center px-4 py-8 text-center">
			<p class="font-[var(--font-sans)] text-[14px] text-[var(--color-text-muted)]">Noch kein Wochenplan für diese Woche.</p>
			{#if isPlanner}
				<form method="POST" action="?/createPlan" class="mt-4">
					<input type="hidden" name="weekStart" value={weekStart} />
					<button
						type="submit"
						class="rounded-[var(--radius-md)] bg-[var(--green-dark)] px-4 py-2 text-[13px] font-medium tracking-[0.04em] font-[var(--font-sans)] text-white"
					>
						Wochenplan erstellen
					</button>
				</form>
			{/if}
		</div>
	{/if}

	<!-- Mobile: empty slot → RecipePicker -->
	<BottomSheet open={pickerOpen} onclose={() => (pickerOpen = false)}>
		<RecipePicker
			planId={weekPlan?.id ?? ''}
			date={selectedDay}
			dateLabel={formatDayLabel(selectedDay)}
			currentVarietyScore={varietyScore?.score ?? 0}
			suggestions={[]}
			allRecipes={data.recipes}
			onpick={handleRecipePick}
		/>
	</BottomSheet>

	<!-- Mobile: meal exists → action sheet (Swap / Cook / View / Cancel) -->
	<MealActionSheet
		open={actionSheetOpen}
		slot={selectedSlot}
		onswap={() => { actionSheetOpen = false; swapSheetOpen = true; }}
		oncancel={() => (actionSheetOpen = false)}
	/>

	<!-- Mobile: swap suggestions sheet -->
	<BottomSheet open={swapSheetOpen} onclose={() => (swapSheetOpen = false)} height="70vh">
		{@const replacingMeta = [
			selectedSlot.recipe?.cookTimeMin ? `${selectedSlot.recipe.cookTimeMin} Min` : null,
			selectedSlot.recipe?.effort ?? null
		].filter(Boolean).join(' · ')}
		<div style="padding: 16px;">
			<SwapSuggestionList
				replacingName={selectedSlot.recipe?.name ?? ''}
				replacingMeta={replacingMeta || undefined}
				recipes={sortedRecipes}
				{currentWeekRecipeIds}
				excludeRecipeId={selectedSlot.recipe?.id}
				isLoading={swapLoading}
				onpick={handleSwapPick}
				oncancel={() => (swapSheetOpen = false)}
			/>
		</div>
	</BottomSheet>
</div>

<!-- Desktop: 3-panel layout -->
<div class="hidden h-screen lg:flex lg:flex-col">
	<!-- Topbar -->
	<header class="flex items-center gap-4 border-b border-[var(--color-border)] bg-[var(--color-page)] px-6 py-4">
		<h1 class="font-[var(--font-display)] text-[20px] font-[300] text-[var(--color-text)]">Wochenplaner</h1>
		<div class="flex items-center gap-2">
			<button
				type="button"
				onclick={() => navigateWeek('prev')}
				aria-label="Vorherige Woche"
				class="flex min-h-[40px] min-w-[40px] items-center justify-center rounded-[var(--radius-md)] border border-[var(--color-border)] text-[13px] font-medium tracking-[0.04em] font-[var(--font-sans)] text-[var(--color-text)] hover:bg-[var(--color-surface)]"
			>
				‹
			</button>
			<span class="font-[var(--font-sans)] text-[13px] text-[var(--color-text-muted)]">{weekRange}</span>
			<button
				type="button"
				onclick={() => navigateWeek('next')}
				aria-label="Nächste Woche"
				class="flex min-h-[40px] min-w-[40px] items-center justify-center rounded-[var(--radius-md)] border border-[var(--color-border)] text-[13px] font-medium tracking-[0.04em] font-[var(--font-sans)] text-[var(--color-text)] hover:bg-[var(--color-surface)]"
			>
				›
			</button>
			<button
				type="button"
				onclick={() => navigateWeek('today')}
				class="flex min-h-[40px] items-center rounded-[var(--radius-md)] border border-[var(--color-border)] px-3 text-[13px] font-medium tracking-[0.04em] font-[var(--font-sans)] text-[var(--color-text)] hover:bg-[var(--color-surface)]"
			>
				Heute
			</button>
		</div>
		{#if isPlanner}
			<button
				type="button"
				onclick={() => (panelState = { kind: 'recipe-picker', date: selectedDay })}
				class="ml-auto rounded-[var(--radius-md)] bg-[var(--green-dark)] px-4 py-2 text-[13px] font-medium tracking-[0.04em] font-[var(--font-sans)] text-white"
			>
				+ Gericht hinzufügen
			</button>
		{/if}
	</header>

	<div class="flex flex-1 overflow-hidden">
		<!-- Left sidebar -->
		<aside class="flex w-[224px] flex-shrink-0 flex-col border-r border-[var(--color-border)] bg-[var(--color-surface)] p-4">
			<!-- Variety widget at bottom -->
			{#if varietyScore}
				<div class="mt-auto">
					<VarietyScoreCard
						score={varietyScore.score ?? 0}
						ingredientOverlaps={varietyScore.ingredientOverlaps ?? []}
						showReviewLink={true}
					/>
				</div>
			{/if}
		</aside>

		<!-- Main calendar (only scrollable panel) -->
		<main class="flex-1 overflow-y-auto p-5">
			{#if !weekPlan}
				<div class="flex h-full flex-col items-center justify-center">
					<p class="font-[var(--font-sans)] text-[14px] text-[var(--color-text-muted)]">Noch kein Wochenplan für diese Woche.</p>
					{#if isPlanner}
						<form method="POST" action="?/createPlan" class="mt-4">
							<input type="hidden" name="weekStart" value={weekStart} />
							<button type="submit" class="rounded-[var(--radius-md)] bg-[var(--green-dark)] px-4 py-2 text-[13px] font-medium tracking-[0.04em] font-[var(--font-sans)] text-white">
								Wochenplan erstellen
							</button>
						</form>
					{/if}
				</div>
			{:else}
				<div class="grid grid-cols-7 gap-[8px]">
					{#each days as day (day)}
						{@const slot = slotMap[day] ?? { id: null, slotDate: day, recipe: null }}
						{@const isTodayDay = day === today}
						{@const isSelectedDay = day === selectedDay}
						{@const dateNum = day.slice(-2).replace(/^0/, '')}
						{@const dayAbbr = formatDayAbbr(day, 'narrow')}

						<div class="flex flex-col">
							<!-- Column header: day name + date badge -->
							<div class="mb-2 flex flex-col items-center gap-1">
								<p class="font-[var(--font-sans)] text-[9px] uppercase tracking-wide text-[var(--color-text-muted)]">
									{dayAbbr}
								</p>
								<div
									class="flex h-6 w-6 items-center justify-center rounded-full text-[11px] font-medium
										{isTodayDay ? 'bg-[var(--yellow)] text-white' : ''}
										{isSelectedDay && !isTodayDay ? 'bg-[var(--green-tint)] text-[var(--green-dark)]' : ''}
										{!isTodayDay && !isSelectedDay ? 'bg-transparent text-[var(--color-text)]' : ''}"
								>
									{dateNum}
								</div>
							</div>

							<!-- Meal tile -->
							<button
								type="button"
								onclick={() => {
									handleSelectDay(day);
									if (!slot.recipe && isPlanner) {
										panelState = { kind: 'recipe-picker', date: day };
									}
								}}
								aria-label={slot.recipe ? slot.recipe.name : `Gericht wählen für ${formatDayLabel(day)}`}
								class="flex flex-1 flex-col rounded-[var(--radius-lg)] border p-2 text-left shadow-[var(--shadow-card)] transition-all hover:border-[var(--green-light)] hover:shadow-[var(--shadow-raised)]
									{slot.recipe && !isTodayDay && !isSelectedDay ? 'border-[var(--color-border)] bg-[var(--color-surface)]' : ''}
									{isTodayDay && slot.recipe ? 'border-2 border-[var(--yellow)] bg-[var(--yellow-tint)]' : ''}
									{isSelectedDay && !isTodayDay && slot.recipe ? 'border-2 border-[var(--green)] bg-[var(--green-tint)]' : ''}
									{!slot.recipe ? 'border-dashed border-[var(--color-border)] bg-transparent' : ''}"
							>
								{#if slot.recipe}
									<p class="font-[var(--font-display)] text-[13px] font-[300] leading-tight text-[var(--color-text)]">
										{slot.recipe.name}
									</p>
								{:else}
									<div class="flex flex-1 flex-col items-center justify-center py-4 text-[var(--color-text-muted)]">
										<span class="text-[18px]" aria-hidden="true">+</span>
										<span class="font-[var(--font-sans)] text-[11px]">Gericht wählen</span>
									</div>
								{/if}
							</button>
						</div>
					{/each}
				</div>
			{/if}
		</main>

		<!-- Right detail panel -->
		<aside class="flex w-[280px] flex-shrink-0 flex-col border-l border-[var(--color-border)] bg-[var(--color-page)] p-4">
			{#if panelState.kind === 'idle'}
				<div class="flex flex-1 flex-col items-center justify-center">
					<p class="font-[var(--font-sans)] text-[14px] text-[var(--color-text-muted)]">Kein Tag ausgewählt</p>
				</div>

			{:else if panelState.kind === 'day-detail'}
				{@const detailDate = panelState.date}
				{@const detailSlot = slotMap[detailDate] ?? { id: null, slotDate: detailDate, recipe: null }}

				<!-- Panel header with close button -->
				<div class="mb-3 flex items-start justify-between">
					<p class="font-[var(--font-sans)] text-[12px] font-medium uppercase tracking-wide text-[var(--color-text-muted)]">
						{formatDayLabel(detailDate)} · Abendessen
					</p>
					<button
						type="button"
						onclick={closePanelToIdle}
						aria-label="Panel schließen"
						class="ml-2 flex-shrink-0 text-[18px] leading-none text-[var(--color-text-muted)] hover:text-[var(--color-text)]"
					>
						×
					</button>
				</div>

				{#if detailSlot.recipe}
					<h2 class="font-[var(--font-display)] text-[17px] font-[300] text-[var(--color-text)]">
						{detailSlot.recipe.name}
					</h2>
					{#if detailSlot.recipe.effort || detailSlot.recipe.cookTimeMin}
						<p class="mt-1 font-[var(--font-sans)] text-[13px] text-[var(--color-text-muted)]">
							{[detailSlot.recipe.cookTimeMin ? `${detailSlot.recipe.cookTimeMin} Min` : null, detailSlot.recipe.effort].filter(Boolean).join(' · ')}
						</p>
					{/if}

					<div class="mt-4 space-y-2">
						<a
							href="/recipes/{detailSlot.recipe.id}"
							class="block rounded-[var(--radius-md)] border border-[var(--color-border)] px-3 py-2 text-center text-[13px] font-medium tracking-[0.04em] font-[var(--font-sans)] text-[var(--color-text)] hover:bg-[var(--color-surface)]"
						>
							Rezept ansehen
						</a>
						<a
							href="/recipes/{detailSlot.recipe.id}/cook"
							class="block rounded-[var(--radius-md)] bg-[var(--green-dark)] px-3 py-2 text-center text-[13px] font-medium tracking-[0.04em] font-[var(--font-sans)] text-white"
						>
							Koch-Modus
						</a>
						{#if isPlanner}
							<button
								type="button"
								onclick={() => (panelState = { kind: 'recipe-picker', date: detailDate })}
								class="block w-full rounded-[var(--radius-md)] border border-[var(--color-border)] px-3 py-2 text-center text-[13px] font-medium tracking-[0.04em] font-[var(--font-sans)] text-[var(--color-text)] hover:bg-[var(--color-surface)]"
							>
								Gericht tauschen
							</button>
						{/if}
					</div>
				{:else}
					<p class="font-[var(--font-sans)] text-[14px] text-[var(--color-text-muted)]">Kein Gericht geplant</p>
					{#if isPlanner}
						<button
							type="button"
							onclick={() => (panelState = { kind: 'recipe-picker', date: detailDate })}
							class="mt-3 block w-full rounded-[var(--radius-md)] border border-dashed border-[var(--color-border)] px-3 py-2 text-center text-[13px] font-medium tracking-[0.04em] font-[var(--font-sans)] text-[var(--color-text-muted)]"
						>
							+ Gericht wählen
						</button>
					{/if}
				{/if}

			{:else if panelState.kind === 'recipe-picker'}
				{@const pickerDate = panelState.date}
				{@const pickerSlot = slotMap[pickerDate] ?? null}
				{@const isSwapContext = !!pickerSlot?.recipe}

				<!-- Panel header with back/close button -->
				<div class="mb-3 flex items-center justify-between">
					<p class="font-[var(--font-sans)] text-[12px] font-medium uppercase tracking-wide text-[var(--color-text-muted)]">
						{isSwapContext ? 'Gericht tauschen' : 'Rezept wählen'}
					</p>
					<button
						type="button"
						onclick={closePanelToDayDetail}
						aria-label="Zurück"
						class="ml-2 flex-shrink-0 text-[18px] leading-none text-[var(--color-text-muted)] hover:text-[var(--color-text)]"
					>
						×
					</button>
				</div>

				{#if isSwapContext}
					{@const replacingMeta = [
						pickerSlot.recipe.cookTimeMin ? `${pickerSlot.recipe.cookTimeMin} Min` : null,
						pickerSlot.recipe.effort ?? null
					].filter(Boolean).join(' · ')}
					<div class="flex-1 overflow-y-auto -mx-4 -mb-4 px-4">
						<SwapSuggestionList
							replacingName={pickerSlot.recipe.name}
							replacingMeta={replacingMeta || undefined}
							recipes={sortedRecipes}
							{currentWeekRecipeIds}
							excludeRecipeId={pickerSlot.recipe.id}
							onpick={handleRecipePick}
						/>
					</div>
				{:else}
					<div class="flex-1 overflow-y-auto -mx-4 -mb-4">
						<RecipePicker
							planId={weekPlan?.id ?? ''}
							date={pickerDate}
							dateLabel={formatDayLabel(pickerDate)}
							currentVarietyScore={varietyScore?.score ?? 0}
							suggestions={[]}
							allRecipes={data.recipes}
							onpick={handleRecipePick}
						/>
					</div>
				{/if}
			{/if}
		</aside>
	</div>
</div>

<!-- Hidden forms for slot mutations -->
<div class="hidden">
	<!-- Add slot -->
	<form
		method="POST"
		action="?/addSlot"
		bind:this={addSlotFormEl}
		use:enhance={({ formData }) => {
			formData.set('planId', addPlanId);
			formData.set('slotDate', addSlotDate);
			formData.set('recipeId', addRecipeId);
			return async ({ result, update }) => {
				if (result.type === 'success' && result.data?.success) {
					delPlanId = addPlanId;
					delSlotId = (result.data as any)?.slot?.id ?? '';
					undoMessage = `${addRecipeName} hinzugefügt`;
					undoVisible = true;
				}
				await update({ reset: false });
				await invalidateAll();
			};
		}}
	>
		<input type="hidden" name="planId" value={addPlanId} />
		<input type="hidden" name="slotDate" value={addSlotDate} />
		<input type="hidden" name="recipeId" value={addRecipeId} />
	</form>

	<!-- Update slot -->
	<form
		method="POST"
		action="?/updateSlot"
		bind:this={updateSlotFormEl}
		use:enhance={({ formData }) => {
			formData.set('planId', updPlanId);
			formData.set('slotId', updSlotId);
			formData.set('recipeId', updRecipeId);
			return async ({ result, update }) => {
				if (result.type === 'success' && result.data?.success) {
					delPlanId = updPlanId;
					delSlotId = (result.data as any)?.slot?.id ?? '';
					undoMessage = `${updRecipeName} eingetragen`;
					undoVisible = true;
				}
				await update({ reset: false });
				await invalidateAll();
			};
		}}
	>
		<input type="hidden" name="planId" value={updPlanId} />
		<input type="hidden" name="slotId" value={updSlotId} />
		<input type="hidden" name="recipeId" value={updRecipeId} />
	</form>

	<!-- Delete slot (for undo) -->
	<form
		method="POST"
		action="?/deleteSlot"
		bind:this={deleteSlotFormEl}
		use:enhance={({ formData }) => {
			formData.set('planId', delPlanId);
			formData.set('slotId', delSlotId);
			return async ({ update }) => {
				await update({ reset: false });
				await invalidateAll();
			};
		}}
	>
		<input type="hidden" name="planId" value={delPlanId} />
		<input type="hidden" name="slotId" value={delSlotId} />
	</form>
</div>

<!-- Undo toast -->
<UndoBar
	visible={undoVisible}
	message={undoMessage}
	onundo={handleUndo}
	ondismiss={() => (undoVisible = false)}
/>
