<script lang="ts">
	import { page } from '$app/stores';
	import { goto } from '$app/navigation';
	import { Button } from '$lib/components/ui/button/index.js';
	import { Input } from '$lib/components/ui/input/index.js';
	import { Label } from '$lib/components/ui/label/index.js';
	import * as Dialog from '$lib/components/ui/dialog/index.js';
	import * as Card from '$lib/components/ui/card/index.js';
	import { Badge, badgeVariants } from '$lib/components/ui/badge/index.js';
	import type {
		EmployeeRecord,
		EmployeeReportRecord,
		ReportSentiment,
		VoxerLink
	} from './+page.server';
	import * as Select from '$lib/components/ui/select/index.js';
	import {
		utcIsoToLocalDatetimeLocal,
		nowToLocalDatetimeLocal,
		localDatetimeLocalToUtcIso
	} from '$lib/date-utils';
	import ArrowLeftIcon from '@lucide/svelte/icons/arrow-left';
	import LinkIcon from '@lucide/svelte/icons/link';
	import PencilIcon from '@lucide/svelte/icons/pencil';
	import Trash2Icon from '@lucide/svelte/icons/trash-2';
	import PlusIcon from '@lucide/svelte/icons/plus';

	let { data } = $props();
	const employeeId = $derived($page.params.id);

	function formatDate(val: string | undefined): string {
		if (!val) return '—';
		try {
			return new Date(val).toLocaleString(undefined, {
				dateStyle: 'short',
				timeStyle: 'short'
			});
		} catch {
			return val;
		}
	}

	let employee = $state<EmployeeRecord | null>(data?.employee ?? null);
	let reports = $state<EmployeeReportRecord[]>((data?.reports ?? []) as EmployeeReportRecord[]);
	let editMode = $state(false);
	let patchSaving = $state(false);
	let patchError = $state<string | null>(null);
	let openDelete = $state(false);
	let deleteSaving = $state(false);
	let deleteError = $state<string | null>(null);

	// Report CRUD state
	let openCreateReport = $state(false);
	let openEditReport = $state(false);
	let openDeleteReport = $state(false);
	let reportFormText = $state('');
	let reportVoxers = $state<VoxerLink[]>([]);
	const SENTIMENT_OPTIONS: ReportSentiment[] = ['Positive', 'Negative', 'Neutral'];
	let reportCreatedLocal = $state('');
	let reportSentiment = $state<ReportSentiment>('Neutral');
	let editingReport = $state<EmployeeReportRecord | null>(null);
	let deletingReport = $state<EmployeeReportRecord | null>(null);
	let reportSaving = $state(false);
	let reportError = $state<string | null>(null);
	let reportDeleteSaving = $state(false);
	let reportDeleteError = $state<string | null>(null);

	function parseVoxers(report: EmployeeReportRecord): VoxerLink[] {
		const raw = report.voxers;
		if (!raw) return [];
		if (Array.isArray(raw)) return raw as VoxerLink[];
		if (typeof raw === 'string') {
			try {
				const parsed = JSON.parse(raw) as unknown;
				return Array.isArray(parsed) ? (parsed as VoxerLink[]) : [];
			} catch {
				return [];
			}
		}
		return [];
	}

	function nextVoxLabel(voxers: VoxerLink[]): string {
		const n = voxers.length + 1;
		return `Vox ${n}`;
	}

	$effect(() => {
		if (data?.employee) employee = data.employee as EmployeeRecord;
		if (data?.reports) reports = (data.reports as EmployeeReportRecord[]).slice();
	});

	async function loadReports() {
		try {
			const res = await fetch(`/api/employees/${employeeId}/reports`);
			if (!res.ok) throw new Error('Failed to load reports');
			const json = await res.json();
			reports = json.reports ?? [];
		} catch {
			reports = [];
		}
	}

	async function loadEmployee() {
		try {
			const res = await fetch(`/api/employees/${employeeId}`);
			if (!res.ok) {
				const err = await res.json().catch(() => ({}));
				throw new Error((err as { error?: string }).error ?? 'Failed to load');
			}
			const json = await res.json();
			employee = (json.employee ?? null) as EmployeeRecord | null;
		} catch (e) {
			employee = null;
		}
	}

	async function patchField(field: keyof EmployeeRecord, value: string | string[]) {
		if (!employee?.id) return;
		patchSaving = true;
		patchError = null;
		try {
			const res = await fetch(`/api/employees/${employeeId}`, {
				method: 'PATCH',
				headers: { 'Content-Type': 'application/json' },
				body: JSON.stringify({ [field]: value })
			});
			const json = await res.json().catch(() => ({}));
			if (!res.ok) {
				const msg = (json as { error?: string }).error ?? 'Update failed';
				const data = (json as { data?: unknown }).data;
				patchError = data && typeof data === 'object' && data !== null
					? `${msg}: ${JSON.stringify(data)}`
					: msg;
				return;
			}
			employee = (json.employee ?? employee) as EmployeeRecord;
		} catch (e) {
			patchError = e instanceof Error ? e.message : 'Update failed';
		} finally {
			patchSaving = false;
		}
	}

	const SCOPE_OPTIONS = [
		'General',
		'OFFICE',
		'IT',
		'Framing',
		'Insulation',
		'Hanging',
		'Scarp & Paper',
		'Taping',
		'Sand & Mask',
		'WT & Cleanup',
		'Grid & Tile'
	];

	function employeeScopes(): string[] {
		const raw = employee?.Scopes;
		if (Array.isArray(raw)) return raw;
		if (typeof raw === 'string') return raw ? [raw] : [];
		return [];
	}

	function toggleScope(scope: string) {
		if (!employee) return;
		const current = employeeScopes();
		const next = current.includes(scope)
			? current.filter((s) => s !== scope)
			: [...current, scope];
		employee = { ...employee, Scopes: next };
		patchField('Scopes', next);
	}

	async function confirmDelete() {
		deleteSaving = true;
		deleteError = null;
		try {
			const res = await fetch(`/api/employees/${employeeId}`, { method: 'DELETE' });
			if (!res.ok) throw new Error(res.statusText);
			openDelete = false;
			goto('/');
		} catch (e) {
			deleteError = e instanceof Error ? e.message : 'Failed to delete';
		} finally {
			deleteSaving = false;
		}
	}

	function openCreateReportDialog() {
		reportFormText = '';
		reportVoxers = [];
		reportCreatedLocal = nowToLocalDatetimeLocal();
		reportSentiment = 'Neutral';
		reportError = null;
		editingReport = null;
		openCreateReport = true;
	}

	function openEditReportDialog(report: EmployeeReportRecord) {
		editingReport = report;
		reportFormText = report.report ?? '';
		reportVoxers = parseVoxers(report).map((v) => ({ ...v }));
		reportCreatedLocal = utcIsoToLocalDatetimeLocal(report.created);
		reportSentiment = (report.Sentiment === 'Positive' || report.Sentiment === 'Negative' ? report.Sentiment : 'Neutral') as ReportSentiment;
		reportError = null;
		openEditReport = true;
	}

	function addVoxer() {
		reportVoxers = [...reportVoxers, { label: nextVoxLabel(reportVoxers), url: '' }];
	}

	function removeVoxer(i: number) {
		reportVoxers = reportVoxers.filter((_, idx) => idx !== i);
	}

	function openDeleteReportDialog(report: EmployeeReportRecord) {
		deletingReport = report;
		reportDeleteError = null;
		openDeleteReport = true;
	}

	async function submitCreateReport() {
		reportSaving = true;
		reportError = null;
		try {
			const res = await fetch(`/api/employees/${employeeId}/reports`, {
				method: 'POST',
				headers: { 'Content-Type': 'application/json' },
				body: JSON.stringify({
					report: reportFormText,
					voxers: reportVoxers,
					created: localDatetimeLocalToUtcIso(reportCreatedLocal),
					Sentiment: reportSentiment
				})
			});
			if (!res.ok) {
				const err = await res.json().catch(() => ({}));
				throw new Error((err as { error?: string }).error ?? 'Failed to create');
			}
			openCreateReport = false;
			await loadReports();
		} catch (e) {
			reportError = e instanceof Error ? e.message : 'Failed to create report';
		} finally {
			reportSaving = false;
		}
	}

	async function submitEditReport() {
		if (!editingReport) return;
		reportSaving = true;
		reportError = null;
		try {
			const res = await fetch(`/api/employees/${employeeId}/reports/${editingReport.id}`, {
				method: 'PATCH',
				headers: { 'Content-Type': 'application/json' },
				body: JSON.stringify({
					report: reportFormText,
					voxers: reportVoxers,
					created: localDatetimeLocalToUtcIso(reportCreatedLocal),
					Sentiment: reportSentiment
				})
			});
			if (!res.ok) throw new Error('Update failed');
			openEditReport = false;
			editingReport = null;
			await loadReports();
		} catch (e) {
			reportError = e instanceof Error ? e.message : 'Failed to update report';
		} finally {
			reportSaving = false;
		}
	}

	async function confirmDeleteReport() {
		if (!deletingReport) return;
		reportDeleteSaving = true;
		reportDeleteError = null;
		try {
			const res = await fetch(`/api/employees/${employeeId}/reports/${deletingReport.id}`, {
				method: 'DELETE'
			});
			if (!res.ok) throw new Error(res.statusText);
			openDeleteReport = false;
			deletingReport = null;
			await loadReports();
		} catch (e) {
			reportDeleteError = e instanceof Error ? e.message : 'Failed to delete';
		} finally {
			reportDeleteSaving = false;
		}
	}
</script>

<svelte:head>
	<title>
		{employee
			? `${employee.First_Name} ${employee.Last_Name} | HRM`
			: 'Employee | HRM'}
	</title>
</svelte:head>

<main class="flex flex-col gap-6 p-6 md:p-8">
	<div class="flex flex-wrap items-center gap-4">
		<Button
			variant="ghost"
			size="icon"
			href="/"
			class="shrink-0"
			onclick={(e) => {
				if (typeof window !== 'undefined' && window.history.length > 1) {
					e.preventDefault();
					window.history.back();
				}
			}}
		>
			<ArrowLeftIcon class="size-4" />
		</Button>
		<h1 class="text-2xl font-semibold tracking-tight shrink-0 flex items-center gap-2 flex-wrap">
			{employee?.First_Name} {employee?.Last_Name}
			{#if employee?.Type}
				<Badge variant="secondary">{employee.Type}</Badge>
			{/if}
		</h1>
		{#if employee}
			<div class="flex items-center gap-2 ml-auto">
				<Button
					variant={editMode ? 'secondary' : 'outline'}
					size="sm"
					onclick={() => (editMode = !editMode)}
				>
					<PencilIcon class="size-4" />
					{editMode ? 'Done' : 'Edit'}
				</Button>
				<Button variant="outline" size="sm" onclick={() => (openDelete = true)}>
					<Trash2Icon class="size-4" />
					Delete
				</Button>
			</div>
		{/if}
	</div>

	{#if employee}
		{#if patchError}
			<p class="text-destructive text-sm">{patchError}</p>
		{/if}
		<div class="grid gap-6 md:grid-cols-2 md:gap-8">
			<dl class="grid gap-4 sm:grid-cols-2 content-start">
			<div class="flex flex-col gap-1">
				<Label for="emp-first" class="text-muted-foreground text-sm">First name</Label>
				{#if editMode}
					<Input
						id="emp-first"
						value={employee.First_Name ?? ''}
						oninput={(e) => (employee = { ...employee!, First_Name: (e.currentTarget as HTMLInputElement).value })}
						onblur={() => patchField('First_Name', employee?.First_Name ?? '')}
						disabled={patchSaving}
					/>
				{:else}
					<dd>{employee.First_Name || '—'}</dd>
				{/if}
			</div>
			<div class="flex flex-col gap-1">
				<Label for="emp-last" class="text-muted-foreground text-sm">Last name</Label>
				{#if editMode}
					<Input
						id="emp-last"
						value={employee.Last_Name ?? ''}
						oninput={(e) => (employee = { ...employee!, Last_Name: (e.currentTarget as HTMLInputElement).value })}
						onblur={() => patchField('Last_Name', employee?.Last_Name ?? '')}
						disabled={patchSaving}
					/>
				{:else}
					<dd>{employee.Last_Name || '—'}</dd>
				{/if}
			</div>
			<div class="flex flex-col gap-1">
				<Label for="emp-type" class="text-muted-foreground text-sm">Type</Label>
				{#if editMode}
					<Select.Root
						type="single"
						value={employee.Type ?? ''}
						onValueChange={(v) => {
							employee = { ...employee!, Type: v ?? undefined };
							if (v !== undefined) patchField('Type', v ?? '');
						}}
						disabled={patchSaving}
					>
						<Select.Trigger class="w-full" id="emp-type">
							{employee.Type || 'Select type…'}
						</Select.Trigger>
						<Select.Content>
							<Select.Item value="" label="(none)">(none)</Select.Item>
							{#each ['Employee', 'Sub-Contractor', 'Former-Employee', 'Applicant', 'Blacklisted'] as opt}
								<Select.Item value={opt} label={opt}>{opt}</Select.Item>
							{/each}
						</Select.Content>
					</Select.Root>
				{:else}
					<dd>
						{#if employee.Type}
							<Badge variant="secondary">{employee.Type}</Badge>
						{:else}
							—
						{/if}
					</dd>
				{/if}
			</div>
			<div class="flex flex-col gap-1">
				<Label for="emp-status" class="text-muted-foreground text-sm">Status</Label>
				{#if editMode}
					<Input
						id="emp-status"
						value={employee.Status ?? ''}
						oninput={(e) => (employee = { ...employee!, Status: (e.currentTarget as HTMLInputElement).value })}
						onblur={() => patchField('Status', employee?.Status ?? '')}
						disabled={patchSaving}
					/>
				{:else}
					<dd>{employee.Status || '—'}</dd>
				{/if}
			</div>
			<div class="flex flex-col gap-1">
				<Label for="emp-phone" class="text-muted-foreground text-sm">Phone</Label>
				{#if editMode}
					<Input
						id="emp-phone"
						value={employee.Phone_Number ?? ''}
						oninput={(e) => (employee = { ...employee!, Phone_Number: (e.currentTarget as HTMLInputElement).value })}
						onblur={() => patchField('Phone_Number', employee?.Phone_Number ?? '')}
						disabled={patchSaving}
					/>
				{:else}
					<dd>{employee.Phone_Number || '—'}</dd>
				{/if}
			</div>
			<div class="flex flex-col gap-1">
				<Label for="emp-email" class="text-muted-foreground text-sm">Email</Label>
				{#if editMode}
					<Input
						id="emp-email"
						type="email"
						value={employee.Email_Address ?? ''}
						oninput={(e) => (employee = { ...employee!, Email_Address: (e.currentTarget as HTMLInputElement).value })}
						onblur={() => patchField('Email_Address', employee?.Email_Address ?? '')}
						disabled={patchSaving}
					/>
				{:else}
					<dd>
						{#if employee.Email_Address}
							<a href={`mailto:${employee.Email_Address}`} class="text-primary underline underline-offset-4">{employee.Email_Address}</a>
						{:else}
							—
						{/if}
					</dd>
				{/if}
			</div>
			<div class="flex flex-col gap-1">
				<Label for="emp-voxer" class="text-muted-foreground text-sm">Voxer ID</Label>
				{#if editMode}
					<Input
						id="emp-voxer"
						value={employee.Voxer_ID ?? ''}
						oninput={(e) => (employee = { ...employee!, Voxer_ID: (e.currentTarget as HTMLInputElement).value })}
						onblur={() => patchField('Voxer_ID', employee?.Voxer_ID ?? '')}
						disabled={patchSaving}
					/>
				{:else}
					<dd>{employee.Voxer_ID || '—'}</dd>
				{/if}
			</div>
			<div class="flex flex-col gap-1">
				<Label class="text-muted-foreground text-sm">Scopes</Label>
				{#if editMode}
					<div class="border-input bg-background flex min-h-[80px] flex-wrap gap-2 rounded-md border px-3 py-2">
						{#each SCOPE_OPTIONS as scope}
							<label class="flex cursor-pointer items-center gap-2 text-sm">
								<input
									type="checkbox"
									class="border-input size-4 rounded"
									checked={employeeScopes().includes(scope)}
									onchange={() => toggleScope(scope)}
									disabled={patchSaving}
								/>
								{scope}
							</label>
						{/each}
					</div>
				{:else}
					<dd>
						{#if employeeScopes().length > 0}
							<div class="flex flex-wrap gap-1">
								{#each employeeScopes() as scope}
									<Badge variant="secondary">{scope}</Badge>
								{/each}
							</div>
						{:else}
							—
						{/if}
					</dd>
				{/if}
			</div>
		</dl>

			<!-- Notes section -->
			<Card.Root class="h-fit">
				<Card.Content>
					{#if editMode}
						<textarea
							class="border-input bg-background ring-offset-background placeholder:text-muted-foreground min-h-[140px] w-full rounded-md border px-3 py-2 text-sm shadow-xs focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 resize-y"
							placeholder="Rich text notes…"
							value={employee?.Notes ?? ''}
							oninput={(e) =>
								(employee = { ...employee!, Notes: (e.currentTarget as HTMLTextAreaElement).value })}
							onblur={() => patchField('Notes', employee?.Notes ?? '')}
							disabled={patchSaving}
							rows="6"
						/>
					{:else}
						{#if employee.Notes}
							<div
								class="prose prose-sm dark:prose-invert max-w-none text-foreground [&_a]:text-primary [&_a]:underline [&_ul]:list-disc [&_ol]:list-decimal"
							>
								{@html employee.Notes}
							</div>
						{:else}
							<p class="text-muted-foreground text-sm">No notes.</p>
						{/if}
					{/if}
				</Card.Content>
			</Card.Root>
		</div>
		{#if patchSaving}
			<p class="text-muted-foreground text-sm">Saving…</p>
		{/if}

		<!-- Employee reports -->
		<div class="space-y-4">
			<div class="flex items-center justify-between gap-4">
				<h2 class="text-lg font-semibold tracking-tight">Reports</h2>
				<Button size="sm" onclick={openCreateReportDialog}>
					<PlusIcon class="size-4" />
					Add report
				</Button>
			</div>
			{#if reports.length > 0}
				<div class="flex flex-col gap-4">
					{#each reports as report (report.id)}
						<Card.Root class="flex flex-col">
							<Card.Header class="flex flex-row items-start justify-between gap-2 space-y-0 pb-2">
								<div class="flex flex-col gap-0.5">
									<Card.Title class="text-base">Report</Card.Title>
									<p class="text-muted-foreground text-xs">
										Created {formatDate(report.created)} · Updated {formatDate(report.updated)}
										{#if report.Sentiment}
											· <span class="capitalize">{report.Sentiment}</span>
										{/if}
									</p>
								</div>
								<div class="flex shrink-0 gap-1">
									<Button
										variant="ghost"
										size="icon"
										class="size-8"
										onclick={() => openEditReportDialog(report)}
										aria-label="Edit report"
									>
										<PencilIcon class="size-4" />
									</Button>
									<Button
										variant="ghost"
										size="icon"
										class="size-8 text-destructive hover:text-destructive"
										onclick={() => openDeleteReportDialog(report)}
										aria-label="Delete report"
									>
										<Trash2Icon class="size-4" />
									</Button>
								</div>
							</Card.Header>
							<Card.Content class="flex-1 pt-0 space-y-3">
								<p class="text-sm whitespace-pre-wrap">{report.report || '—'}</p>
								{@const voxersList = parseVoxers(report)}
								{#if voxersList.length > 0}
									<div class="flex flex-wrap gap-2">
										{#each voxersList as vox (vox.url + vox.label)}
											<a
												href={vox.url}
												target="_blank"
												rel="noopener noreferrer"
												class={badgeVariants({ variant: 'link' }) + ' cursor-pointer no-underline'}
											>
												<LinkIcon class="mr-1 inline size-3" />
												{vox.label || 'Link'}
											</a>
										{/each}
									</div>
								{/if}
							</Card.Content>
						</Card.Root>
					{/each}
				</div>
			{:else}
				<p class="text-muted-foreground text-sm">No reports yet. Add one to get started.</p>
			{/if}
		</div>
	{:else}
		<p class="text-muted-foreground">Employee not found.</p>
		<Button variant="outline" onclick={loadEmployee}>Retry</Button>
	{/if}
</main>

<!-- Delete confirmation -->
<Dialog.Root bind:open={openDelete}>
	<Dialog.Content>
		<Dialog.Header>
			<Dialog.Title>Delete employee</Dialog.Title>
			<Dialog.Description>
				Are you sure you want to delete
				{#if employee}
					<strong>{employee.First_Name} {employee.Last_Name}</strong>?
				{/if}
				This cannot be undone.
			</Dialog.Description>
		</Dialog.Header>
		{#if deleteError}
			<p class="text-destructive text-sm">{deleteError}</p>
		{/if}
		<Dialog.Footer>
			<Dialog.Close asChild>
				<Button type="button" variant="outline">Cancel</Button>
			</Dialog.Close>
			<Button variant="destructive" disabled={deleteSaving} onclick={confirmDelete}>
				{deleteSaving ? 'Deleting…' : 'Delete'}
			</Button>
		</Dialog.Footer>
	</Dialog.Content>
</Dialog.Root>

<!-- Create report -->
<Dialog.Root bind:open={openCreateReport}>
	<Dialog.Content>
		<Dialog.Header>
			<Dialog.Title>Add report</Dialog.Title>
			<Dialog.Description>Add a new report for this employee.</Dialog.Description>
		</Dialog.Header>
		<form
			onsubmit={(e) => {
				e.preventDefault();
				submitCreateReport();
			}}
			class="grid gap-4 py-4"
		>
			<div class="grid grid-cols-1 gap-4 sm:grid-cols-2 sm:items-end">
				<div class="space-y-2">
					<Label for="new-created">Created (local time)</Label>
					<Input
						id="new-created"
						type="datetime-local"
						bind:value={reportCreatedLocal}
						disabled={reportSaving}
					/>
				</div>
				<div class="space-y-2">
					<Label for="new-sentiment">Sentiment</Label>
					<Select.Root bind:value={reportSentiment} disabled={reportSaving}>
						<Select.Trigger class="w-full" id="new-sentiment">
							{reportSentiment}
						</Select.Trigger>
						<Select.Content>
							{#each SENTIMENT_OPTIONS as opt}
								<Select.Item value={opt} label={opt}>{opt}</Select.Item>
							{/each}
						</Select.Content>
					</Select.Root>
				</div>
			</div>
			<div class="space-y-2">
				<Label for="new-report">Report</Label>
				<textarea
					id="new-report"
					class="border-input bg-background ring-offset-background placeholder:text-muted-foreground flex min-h-[120px] w-full rounded-md border px-3 py-2 text-sm shadow-xs focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
					placeholder="Enter report content…"
					bind:value={reportFormText}
					disabled={reportSaving}
					rows="5"
				/>
			</div>
			<div class="space-y-2">
				<div class="flex items-center justify-between">
					<Label>Voxer links</Label>
					<Button type="button" variant="outline" size="sm" onclick={addVoxer} disabled={reportSaving}>
						<PlusIcon class="size-4" />
						Add link
					</Button>
				</div>
				{#each reportVoxers as vox, i}
					<div class="flex gap-2">
						<Input
							placeholder="Label (e.g. Vox 1)"
							value={vox.label}
							oninput={(e) => {
								reportVoxers = reportVoxers.map((v, idx) =>
									idx === i ? { ...v, label: (e.currentTarget as HTMLInputElement).value } : v
								);
							}}
							class="flex-1"
						/>
						<Input
							placeholder="https://…"
							value={vox.url}
							oninput={(e) => {
								reportVoxers = reportVoxers.map((v, idx) =>
									idx === i ? { ...v, url: (e.currentTarget as HTMLInputElement).value } : v
								);
							}}
							class="flex-[2]"
						/>
						<Button type="button" variant="ghost" size="icon" onclick={() => removeVoxer(i)} aria-label="Remove link">
							<Trash2Icon class="size-4" />
						</Button>
					</div>
				{/each}
			</div>
			{#if reportError}
				<p class="text-destructive text-sm">{reportError}</p>
			{/if}
			<Dialog.Footer>
				<Dialog.Close asChild>
					<Button type="button" variant="outline">Cancel</Button>
				</Dialog.Close>
				<Button type="submit" disabled={reportSaving}>
					{reportSaving ? 'Saving…' : 'Add report'}
				</Button>
			</Dialog.Footer>
		</form>
	</Dialog.Content>
</Dialog.Root>

<!-- Edit report -->
<Dialog.Root bind:open={openEditReport}>
	<Dialog.Content>
		<Dialog.Header>
			<Dialog.Title>Edit report</Dialog.Title>
			<Dialog.Description>Update this report.</Dialog.Description>
		</Dialog.Header>
		<form
			onsubmit={(e) => {
				e.preventDefault();
				submitEditReport();
			}}
			class="grid gap-4 py-4"
		>
			<div class="grid grid-cols-1 gap-4 sm:grid-cols-2 sm:items-end">
				<div class="space-y-2">
					<Label for="edit-created">Created (local time)</Label>
					<Input
						id="edit-created"
						type="datetime-local"
						bind:value={reportCreatedLocal}
						disabled={reportSaving}
					/>
				</div>
				<div class="space-y-2">
					<Label for="edit-sentiment">Sentiment</Label>
					<Select.Root bind:value={reportSentiment} disabled={reportSaving}>
						<Select.Trigger class="w-full" id="edit-sentiment">
							{reportSentiment}
						</Select.Trigger>
						<Select.Content>
							{#each SENTIMENT_OPTIONS as opt}
								<Select.Item value={opt} label={opt}>{opt}</Select.Item>
							{/each}
						</Select.Content>
					</Select.Root>
				</div>
			</div>
			<div class="space-y-2">
				<Label for="edit-report">Report</Label>
				<textarea
					id="edit-report"
					class="border-input bg-background ring-offset-background placeholder:text-muted-foreground flex min-h-[120px] w-full rounded-md border px-3 py-2 text-sm shadow-xs focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
					placeholder="Enter report content…"
					bind:value={reportFormText}
					disabled={reportSaving}
					rows="5"
				/>
			</div>
			<div class="space-y-2">
				<div class="flex items-center justify-between">
					<Label>Voxer links</Label>
					<Button type="button" variant="outline" size="sm" onclick={addVoxer} disabled={reportSaving}>
						<PlusIcon class="size-4" />
						Add link
					</Button>
				</div>
				{#each reportVoxers as vox, i}
					<div class="flex gap-2">
						<Input
							placeholder="Label (e.g. Vox 1)"
							value={vox.label}
							oninput={(e) => {
								reportVoxers = reportVoxers.map((v, idx) =>
									idx === i ? { ...v, label: (e.currentTarget as HTMLInputElement).value } : v
								);
							}}
							class="flex-1"
						/>
						<Input
							placeholder="https://…"
							value={vox.url}
							oninput={(e) => {
								reportVoxers = reportVoxers.map((v, idx) =>
									idx === i ? { ...v, url: (e.currentTarget as HTMLInputElement).value } : v
								);
							}}
							class="flex-[2]"
						/>
						<Button type="button" variant="ghost" size="icon" onclick={() => removeVoxer(i)} aria-label="Remove link">
							<Trash2Icon class="size-4" />
						</Button>
					</div>
				{/each}
			</div>
			{#if reportError}
				<p class="text-destructive text-sm">{reportError}</p>
			{/if}
			<Dialog.Footer>
				<Dialog.Close asChild>
					<Button type="button" variant="outline">Cancel</Button>
				</Dialog.Close>
				<Button type="submit" disabled={reportSaving}>
					{reportSaving ? 'Saving…' : 'Save'}
				</Button>
			</Dialog.Footer>
		</form>
	</Dialog.Content>
</Dialog.Root>

<!-- Delete report confirmation -->
<Dialog.Root bind:open={openDeleteReport}>
	<Dialog.Content>
		<Dialog.Header>
			<Dialog.Title>Delete report</Dialog.Title>
			<Dialog.Description>
				Are you sure you want to delete this report? This cannot be undone.
			</Dialog.Description>
		</Dialog.Header>
		{#if reportDeleteError}
			<p class="text-destructive text-sm">{reportDeleteError}</p>
		{/if}
		<Dialog.Footer>
			<Dialog.Close asChild>
				<Button type="button" variant="outline">Cancel</Button>
			</Dialog.Close>
			<Button variant="destructive" disabled={reportDeleteSaving} onclick={confirmDeleteReport}>
				{reportDeleteSaving ? 'Deleting…' : 'Delete'}
			</Button>
		</Dialog.Footer>
	</Dialog.Content>
</Dialog.Root>
