<script lang="ts">
	import { enhance } from '$app/forms';
	import { dragHandleZone, dragHandle, type DndEvent } from 'svelte-dnd-action';
	import { updateRoutineStep } from '$lib/api';
	import type { GroomingAction, RoutineStep } from '$lib/types';
	import type { ActionData, PageData } from './$types';
	import { m } from '$lib/paraglide/messages.js';
	import { Badge } from '$lib/components/ui/badge';
	import { Button } from '$lib/components/ui/button';
	import { Card, CardContent, CardHeader, CardTitle } from '$lib/components/ui/card';
	import { Input } from '$lib/components/ui/input';
	import { Label } from '$lib/components/ui/label';
	import {
		Select,
		SelectContent,
		SelectGroup,
		SelectGroupHeading,
		SelectItem,
		SelectTrigger
	} from '$lib/components/ui/select';
	import { Separator } from '$lib/components/ui/separator';

	let { data, form }: { data: PageData; form: ActionData } = $props();
	let { routine, products } = $derived(data);

	// ── Steps local state (synced from server data) ───────────────
	let steps = $state<RoutineStep[]>([]);
	$effect(() => {
		steps = [...(routine.steps ?? [])].sort((a, b) => a.order_index - b.order_index);
	});

	const nextOrderIndex = $derived(
		steps.length ? Math.max(...steps.map((s) => s.order_index)) + 1 : 0
	);

	// ── Drag & drop reordering ────────────────────────────────────
	let dndSaving = $state(false);

	function handleConsider(e: CustomEvent<DndEvent<RoutineStep>>) {
		steps = e.detail.items;
	}

	async function handleFinalize(e: CustomEvent<DndEvent<RoutineStep>>) {
		const newItems = e.detail.items;
		// Assign new order_index = position in array, detect which changed
		const updated = newItems.map((s, i) => ({ ...s, order_index: i }));
		const changed = updated.filter((s, i) => s.order_index !== newItems[i].order_index);
		steps = updated;
		if (changed.length) {
			dndSaving = true;
			try {
				await Promise.all(
					changed.map((s) => updateRoutineStep(s.id, { order_index: s.order_index }))
				);
			} finally {
				dndSaving = false;
			}
		}
	}

	// ── Inline editing ────────────────────────────────────────────
	let editingStepId = $state<string | null>(null);
	let editDraft = $state<Partial<RoutineStep>>({});
	let editSaving = $state(false);
	let editError = $state('');

	function startEdit(step: RoutineStep) {
		editingStepId = step.id;
		editDraft = {
			dose: step.dose ?? '',
			region: step.region ?? '',
			product_id: step.product_id,
			action_type: step.action_type,
			action_notes: step.action_notes ?? ''
		};
		editError = '';
	}

	async function saveEdit(step: RoutineStep) {
		editSaving = true;
		editError = '';
		try {
			const payload: Record<string, unknown> = {};
			if (step.product_id !== undefined) {
				payload.product_id = editDraft.product_id;
				payload.dose = editDraft.dose || null;
				payload.region = editDraft.region || null;
			} else {
				payload.action_type = editDraft.action_type;
				payload.action_notes = editDraft.action_notes || null;
			}
			const updatedStep = await updateRoutineStep(step.id, payload);
			steps = steps.map((s) => (s.id === step.id ? { ...s, ...updatedStep } : s));
			editingStepId = null;
		} catch (err) {
			editError = (err as Error).message;
		} finally {
			editSaving = false;
		}
	}

	function cancelEdit() {
		editingStepId = null;
		editDraft = {};
		editError = '';
	}

	// ── Add step form ─────────────────────────────────────────────
	let showStepForm = $state(false);
	let selectedProductId = $state('');

	const GROOMING_ACTIONS: GroomingAction[] = ['shaving_razor', 'shaving_oneblade', 'dermarolling'];

	const CATEGORY_ORDER = [
		'cleanser', 'toner', 'essence', 'serum', 'moisturizer',
		'spf', 'mask', 'exfoliant', 'spot_treatment', 'oil',
		'hair_treatment', 'tool', 'other'
	];

	function formatCategory(cat: string): string {
		return cat.charAt(0).toUpperCase() + cat.slice(1).replace(/_/g, ' ');
	}

	const groupedProducts = $derived.by(() => {
		const groups = new Map<string, typeof products>();
		for (const p of products) {
			const key = p.category ?? 'other';
			if (!groups.has(key)) groups.set(key, []);
			groups.get(key)!.push(p);
		}
		for (const list of groups.values()) {
			list.sort((a, b) => {
				const b_cmp = (a.brand ?? '').localeCompare(b.brand ?? '');
				return b_cmp !== 0 ? b_cmp : a.name.localeCompare(b.name);
			});
		}
		return CATEGORY_ORDER
			.filter((c) => groups.has(c))
			.map((c) => [c, groups.get(c)!] as const);
	});
</script>

<svelte:head><title>Routine {routine.routine_date} {routine.part_of_day.toUpperCase()} — innercontext</title></svelte:head>

<div class="max-w-2xl space-y-6">
	<div class="flex items-center gap-4">
		<a href="/routines" class="text-sm text-muted-foreground hover:underline">{m["routines_backToList"]()}</a>
		<h2 class="text-2xl font-bold tracking-tight">{routine.routine_date}</h2>
		<Badge variant={routine.part_of_day === 'am' ? 'default' : 'secondary'}>
			{routine.part_of_day.toUpperCase()}
		</Badge>
	</div>

	{#if form?.error}
		<div class="rounded-md bg-destructive/10 px-4 py-3 text-sm text-destructive">{form.error}</div>
	{/if}

	{#if routine.notes}
		<p class="text-sm text-muted-foreground">{routine.notes}</p>
	{/if}

	<!-- Steps -->
	<div class="space-y-3">
		<div class="flex items-center justify-between">
			<h3 class="text-lg font-semibold">{m.routines_steps({ count: steps.length })}</h3>
			<Button variant="outline" size="sm" onclick={() => (showStepForm = !showStepForm)}>
				{showStepForm ? m.common_cancel() : m["routines_addStep"]()}
			</Button>
		</div>

		{#if showStepForm}
			<Card>
				<CardHeader><CardTitle class="text-base">{m["routines_addStepTitle"]()}</CardTitle></CardHeader>
				<CardContent>
					<form method="POST" action="?/addStep" use:enhance class="space-y-4">
						<div class="space-y-1">
							<Label>{m.routines_product()}</Label>
							<input type="hidden" name="product_id" value={selectedProductId} />
							<Select type="single" value={selectedProductId} onValueChange={(v) => (selectedProductId = v)}>
								<SelectTrigger>
									{#if selectedProductId}
										{products.find((p) => p.id === selectedProductId)?.name ?? m["routines_selectProduct"]()}
									{:else}
										{m["routines_selectProduct"]()}
									{/if}
								</SelectTrigger>
								<SelectContent>
									{#each groupedProducts as [cat, items]}
										<SelectGroup>
											<SelectGroupHeading>{formatCategory(cat)}</SelectGroupHeading>
											{#each items as p (p.id)}
												<SelectItem value={p.id}>{p.name} · {p.brand}</SelectItem>
											{/each}
										</SelectGroup>
									{/each}
								</SelectContent>
							</Select>
						</div>
						<input type="hidden" name="order_index" value={nextOrderIndex} />
						<div class="grid grid-cols-2 gap-3">
							<div class="space-y-1">
								<Label for="dose">{m.routines_dose()}</Label>
								<Input id="dose" name="dose" placeholder={m["routines_dosePlaceholder"]()} />
							</div>
							<div class="space-y-1">
								<Label for="region">{m.routines_region()}</Label>
								<Input id="region" name="region" placeholder={m["routines_regionPlaceholder"]()} />
							</div>
						</div>
						<Button type="submit" size="sm">{m["routines_addStepBtn"]()}</Button>
					</form>
				</CardContent>
			</Card>
		{/if}

		{#if steps.length}
			<div
				use:dragHandleZone={{ items: steps, flipDurationMs: 200, dragDisabled: !!editingStepId || dndSaving }}
				onconsider={handleConsider}
				onfinalize={handleFinalize}
				class="space-y-2"
			>
				{#each steps as step, i (step.id)}
					<div class="rounded-md border border-border bg-background">
						{#if editingStepId === step.id}
							<!-- ── Edit mode ── -->
							<div class="px-4 py-3 space-y-3">
								{#if step.product_id !== undefined}
									<!-- Product step: change product / dose / region -->
									<div class="space-y-1">
										<Label>{m.routines_product()}</Label>
										<Select
											type="single"
											value={editDraft.product_id ?? ''}
											onValueChange={(v) => (editDraft.product_id = v || undefined)}
										>
											<SelectTrigger>
												{#if editDraft.product_id}
													{products.find((p) => p.id === editDraft.product_id)?.name ?? m["routines_selectProduct"]()}
												{:else}
													{m["routines_selectProduct"]()}
												{/if}
											</SelectTrigger>
											<SelectContent>
												{#each groupedProducts as [cat, items]}
													<SelectGroup>
														<SelectGroupHeading>{formatCategory(cat)}</SelectGroupHeading>
														{#each items as p (p.id)}
															<SelectItem value={p.id}>{p.name} · {p.brand}</SelectItem>
														{/each}
													</SelectGroup>
												{/each}
											</SelectContent>
										</Select>
									</div>
									<div class="grid grid-cols-2 gap-3">
										<div class="space-y-1">
											<Label>{m.routines_dose()}</Label>
											<Input
												value={editDraft.dose ?? ''}
												oninput={(e) => (editDraft.dose = e.currentTarget.value)}
												placeholder={m["routines_dosePlaceholder"]()}
											/>
										</div>
										<div class="space-y-1">
											<Label>{m.routines_region()}</Label>
											<Input
												value={editDraft.region ?? ''}
												oninput={(e) => (editDraft.region = e.currentTarget.value)}
												placeholder={m["routines_regionPlaceholder"]()}
											/>
										</div>
									</div>
								{:else}
									<!-- Action step: change action_type / notes -->
									<div class="space-y-1">
										<Label>Action</Label>
										<Select
											type="single"
											value={editDraft.action_type ?? ''}
											onValueChange={(v) =>
												(editDraft.action_type = (v || undefined) as GroomingAction | undefined)}
										>
											<SelectTrigger>
												{editDraft.action_type?.replace(/_/g, ' ') ?? 'Select action'}
											</SelectTrigger>
											<SelectContent>
												{#each GROOMING_ACTIONS as action (action)}
													<SelectItem value={action}>{action.replace(/_/g, ' ')}</SelectItem>
												{/each}
											</SelectContent>
										</Select>
									</div>
									<div class="space-y-1">
										<Label>Notes</Label>
										<Input
											value={editDraft.action_notes ?? ''}
											oninput={(e) => (editDraft.action_notes = e.currentTarget.value)}
											placeholder="optional notes"
										/>
									</div>
								{/if}

								{#if editError}
									<p class="text-sm text-destructive">{editError}</p>
								{/if}

								<div class="flex gap-2">
									<Button size="sm" onclick={() => saveEdit(step)} disabled={editSaving}>
										{m.common_save()}
									</Button>
									<Button size="sm" variant="outline" onclick={cancelEdit} disabled={editSaving}>
										{m.common_cancel()}
									</Button>
								</div>
							</div>
						{:else}
							<!-- ── View mode ── -->
							<div class="flex items-center gap-1 px-2 py-3">
								<span
									use:dragHandle
									class="cursor-grab select-none px-1 text-muted-foreground/60 hover:text-muted-foreground"
									aria-label="drag to reorder"
								>⋮⋮</span>
								<span class="w-5 shrink-0 text-xs text-muted-foreground">{i + 1}.</span>
								<div class="flex-1 min-w-0 px-1">
									{#if step.product_id}
										{@const product = products.find((p) => p.id === step.product_id)}
										<p class="text-sm font-medium truncate">{product?.name ?? step.product_id}</p>
										{#if product?.brand}<p class="text-xs text-muted-foreground truncate">{product.brand}</p>{/if}
									{:else if step.action_type}
										<p class="text-sm font-medium">{step.action_type.replace(/_/g, ' ')}</p>
									{:else}
										<p class="text-sm text-muted-foreground">{m["routines_unknownStep"]()}</p>
									{/if}
								</div>
								{#if step.dose}
									<span class="shrink-0 text-xs text-muted-foreground">{step.dose}</span>
								{/if}
								<Button
									variant="ghost"
									size="sm"
									class="shrink-0 h-7 w-7 p-0 text-muted-foreground hover:text-foreground"
									onclick={() => startEdit(step)}
									aria-label="edit step"
								>✎</Button>
								<form method="POST" action="?/removeStep" use:enhance>
									<input type="hidden" name="step_id" value={step.id} />
									<Button
										type="submit"
										variant="ghost"
										size="sm"
										class="shrink-0 h-7 w-7 p-0 text-destructive hover:text-destructive"
									>×</Button>
								</form>
							</div>
						{/if}
					</div>
				{/each}
			</div>
		{:else}
			<p class="text-sm text-muted-foreground">{m["routines_noSteps"]()}</p>
		{/if}
	</div>

	<Separator />

	<form
		method="POST"
		action="?/delete"
		use:enhance
		onsubmit={(e) => {
			if (!confirm(m["routines_confirmDelete"]())) e.preventDefault();
		}}
	>
		<Button type="submit" variant="destructive" size="sm">{m["routines_deleteRoutine"]()}</Button>
	</form>
</div>
