import { useMutation, useQuery } from "@tanstack/react-query";
import { createFileRoute, Link, useNavigate } from "@tanstack/react-router";
import {
	Check,
	ChevronDown,
	ChevronRight,
	ChevronsUpDown,
	ChevronUp,
	Clipboard,
	ClipboardCheck,
	Download,
	LogOut,
	MessageSquare,
	Search,
	X,
} from "lucide-react";
import { useMemo, useState } from "react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { authClient } from "@/lib/auth-client";
import { orpc } from "@/utils/orpc";

export const Route = createFileRoute("/admin/")({
	component: AdminPage,
});

type Guest = {
	firstName: string;
	lastName: string;
	email?: string;
	phone?: string;
	birthdate?: string;
	postcode?: string;
};

function parseGuests(raw: unknown): Guest[] {
	if (!raw) return [];
	try {
		const parsed = typeof raw === "string" ? JSON.parse(raw) : raw;
		return Array.isArray(parsed) ? parsed : [];
	} catch {
		return [];
	}
}

function StatCard({
	label,
	value,
	sub,
	accent,
}: {
	label: string;
	value: string | number;
	sub?: React.ReactNode;
	accent?: "amber" | "teal" | "pink" | "white";
}) {
	const colorMap = {
		amber: "text-amber-300",
		teal: "text-teal-300",
		pink: "text-pink-300",
		white: "text-white",
	};
	const borderMap = {
		amber: "border-amber-400/20 bg-amber-400/5",
		teal: "border-teal-400/20 bg-teal-400/5",
		pink: "border-pink-400/20 bg-pink-400/5",
		white: "border-white/10 bg-white/5",
	};
	const a = accent ?? "white";
	return (
		<div className={`rounded-xl border p-4 ${borderMap[a]}`}>
			<p className="mb-1 font-mono text-[10px] text-white/40 uppercase tracking-widest">
				{label}
			</p>
			<p className={`font-bold font-mono text-3xl tabular-nums ${colorMap[a]}`}>
				{value}
			</p>
			{sub && <div className="mt-2 space-y-0.5 text-xs">{sub}</div>}
		</div>
	);
}

function PayBadge({
	status,
	paymentAmount,
	isPerformer,
}: {
	status: string | null;
	paymentAmount: number | null;
	isPerformer: boolean;
}) {
	if (isPerformer) return <span className="text-white/25 text-xs">—</span>;
	if (status === "paid")
		return (
			<span className="inline-flex items-center gap-1 rounded-full bg-green-500/15 px-2 py-0.5 font-semibold text-green-400 text-xs">
				<Check className="h-3 w-3" />
				Betaald
			</span>
		);
	if (status === "extra_payment_pending")
		return (
			<span className="inline-flex items-center gap-1 rounded-full bg-orange-500/15 px-2 py-0.5 font-semibold text-orange-400 text-xs">
				<span className="h-1.5 w-1.5 rounded-full bg-orange-400" />€
				{((paymentAmount ?? 0) / 100).toFixed(0)} extra
			</span>
		);
	return (
		<span className="rounded-full bg-yellow-500/15 px-2 py-0.5 font-semibold text-xs text-yellow-400">
			Open
		</span>
	);
}

function AdminPage() {
	const navigate = useNavigate();
	const [search, setSearch] = useState("");
	const [registrationType, setRegistrationType] = useState<
		"performer" | "watcher" | ""
	>("");
	const [artForm, setArtForm] = useState("");
	const [fromDate, setFromDate] = useState("");
	const [toDate, setToDate] = useState("");
	const [page, setPage] = useState(1);
	const pageSize = 20;

	const [copiedId, setCopiedId] = useState<string | null>(null);
	const [expandedRow, setExpandedRow] = useState<string | null>(null);

	const sessionQuery = useQuery({
		queryKey: ["session"],
		queryFn: () => authClient.getSession(),
	});

	const handleCopyManageUrl = (token: string, id: string) => {
		const url = `${window.location.origin}/manage/${token}`;
		navigator.clipboard.writeText(url).then(() => {
			setCopiedId(id);
			toast.success("Beheerlink gekopieerd");
			setTimeout(() => setCopiedId(null), 2000);
		});
	};

	const toggleRow = (id: string) => {
		setExpandedRow((prev) => (prev === id ? null : id));
	};

	type SortKey =
		| "naam"
		| "email"
		| "type"
		| "details"
		| "gasten"
		| "gift"
		| "betaling"
		| "datum";
	type SortDir = "asc" | "desc";
	const [sortKey, setSortKey] = useState<SortKey>("datum");
	const [sortDir, setSortDir] = useState<SortDir>("desc");

	const handleSort = (key: SortKey) => {
		if (sortKey === key) setSortDir((d) => (d === "asc" ? "desc" : "asc"));
		else {
			setSortKey(key);
			setSortDir("asc");
		}
	};

	const statsQuery = useQuery(orpc.getRegistrationStats.queryOptions());
	const registrationsQuery = useQuery(
		orpc.getRegistrations.queryOptions({
			input: {
				search: search || undefined,
				registrationType: registrationType || undefined,
				artForm: artForm || undefined,
				fromDate: fromDate || undefined,
				toDate: toDate || undefined,
				page,
				pageSize,
			},
		}),
	);
	const adminRequestsQuery = useQuery(orpc.getAdminRequests.queryOptions());

	const exportMutation = useMutation({
		...orpc.exportRegistrations.mutationOptions(),
		onSuccess: (data: { csv: string; filename: string }) => {
			const blob = new Blob([data.csv], { type: "text/csv" });
			const url = window.URL.createObjectURL(blob);
			const a = document.createElement("a");
			a.href = url;
			a.download = data.filename;
			document.body.appendChild(a);
			a.click();
			document.body.removeChild(a);
			window.URL.revokeObjectURL(url);
		},
	});

	const approveRequestMutation = useMutation({
		...orpc.approveAdminRequest.mutationOptions(),
		onSuccess: () => {
			toast.success("Admin toegang goedgekeurd");
			adminRequestsQuery.refetch();
		},
		onError: (err) => toast.error(`Fout: ${err.message}`),
	});

	const rejectRequestMutation = useMutation({
		...orpc.rejectAdminRequest.mutationOptions(),
		onSuccess: () => {
			toast.success("Admin toegang geweigerd");
			adminRequestsQuery.refetch();
		},
		onError: (err) => toast.error(`Fout: ${err.message}`),
	});

	const requestAdminMutation = useMutation({
		...orpc.requestAdminAccess.mutationOptions(),
		onSuccess: () => toast.success("Admin toegang aangevraagd!"),
		onError: (err) => toast.error(`Aanvraag mislukt: ${err.message}`),
	});

	const stats = statsQuery.data;
	const registrations = registrationsQuery.data?.data ?? [];
	const pagination = registrationsQuery.data?.pagination;
	const adminRequests = adminRequestsQuery.data ?? [];
	const pendingRequests = adminRequests.filter((r) => r.status === "pending");

	const performerCount =
		stats?.byType.find((t) => t.registrationType === "performer")?.count ?? 0;
	const watcherCount =
		stats?.byType.find((t) => t.registrationType === "watcher")?.count ?? 0;
	const totalGuestCount =
		(stats as { totalGuestCount?: number } | undefined)?.totalGuestCount ?? 0;
	const totalWatcherAttendees = watcherCount + totalGuestCount;
	const totalGiftRevenue = (stats?.totalGiftRevenue as number | undefined) ?? 0;
	const totalDrinkCardValue = registrations
		.filter((r) => r.registrationType === "watcher")
		.reduce((s, r) => s + (r.drinkCardValue ?? 0), 0);

	const sortedRegistrations = useMemo(() => {
		return [...registrations].sort((a, b) => {
			let valA: string | number = 0;
			let valB: string | number = 0;
			switch (sortKey) {
				case "naam":
					valA = `${a.firstName} ${a.lastName}`.toLowerCase();
					valB = `${b.firstName} ${b.lastName}`.toLowerCase();
					break;
				case "email":
					valA = a.email.toLowerCase();
					valB = b.email.toLowerCase();
					break;
				case "type":
					valA = a.registrationType ?? "";
					valB = b.registrationType ?? "";
					break;
				case "details":
					valA =
						(a.registrationType === "performer"
							? a.artForm
							: `€${a.drinkCardValue ?? 5}`) ?? "";
					valB =
						(b.registrationType === "performer"
							? b.artForm
							: `€${b.drinkCardValue ?? 5}`) ?? "";
					break;
				case "gasten":
					valA = parseGuests(a.guests).length;
					valB = parseGuests(b.guests).length;
					break;
				case "gift":
					valA = a.giftAmount ?? 0;
					valB = b.giftAmount ?? 0;
					break;
				case "betaling":
					valA = a.paymentStatus ?? "pending";
					valB = b.paymentStatus ?? "pending";
					break;
				case "datum":
					valA = new Date(a.createdAt).getTime();
					valB = new Date(b.createdAt).getTime();
					break;
			}
			if (valA < valB) return sortDir === "asc" ? -1 : 1;
			if (valA > valB) return sortDir === "asc" ? 1 : -1;
			return 0;
		});
	}, [registrations, sortKey, sortDir]);

	const SortIcon = ({ col }: { col: SortKey }) => {
		if (sortKey !== col)
			return <ChevronsUpDown className="ml-1 inline h-3 w-3 opacity-30" />;
		return sortDir === "asc" ? (
			<ChevronUp className="ml-1 inline h-3 w-3 text-teal-300" />
		) : (
			<ChevronDown className="ml-1 inline h-3 w-3 text-teal-300" />
		);
	};

	const formatCents = (cents: number | null | undefined) => {
		if (!cents || cents <= 0) return null;
		const euros = cents / 100;
		return `€${euros.toFixed(euros % 1 === 0 ? 0 : 2)}`;
	};

	const user = sessionQuery.data?.data?.user as
		| { role?: string; name?: string }
		| undefined;
	const isAdmin = user?.role === "admin";
	const isAuthenticated = !!sessionQuery.data?.data?.user;

	if (sessionQuery.isLoading) {
		return (
			<div className="flex min-h-screen items-center justify-center">
				<p className="font-mono text-sm text-white/40">laden...</p>
			</div>
		);
	}

	if (!isAuthenticated) {
		return (
			<div className="flex min-h-screen items-center justify-center px-4">
				<div className="w-full max-w-sm rounded-2xl border border-white/10 bg-white/5 p-8 text-center">
					<p className="mb-6 font-mono text-sm text-white/60">Login vereist</p>
					<Button
						onClick={() => navigate({ to: "/login" })}
						className="w-full bg-white text-[#214e51] hover:bg-white/90"
					>
						Inloggen
					</Button>
					<Link
						to="/"
						className="mt-4 block text-center text-sm text-white/30 hover:text-white/70"
					>
						← Terug naar website
					</Link>
				</div>
			</div>
		);
	}

	if (!isAdmin) {
		return (
			<div className="flex min-h-screen items-center justify-center px-4">
				<div className="w-full max-w-sm rounded-2xl border border-white/10 bg-white/5 p-8 text-center">
					<p className="mb-2 font-['Intro',sans-serif] text-2xl text-white">
						Geen toegang
					</p>
					<p className="mb-6 text-sm text-white/50">
						Je hebt geen admin rechten
					</p>
					<Button
						onClick={() => requestAdminMutation.mutate(undefined)}
						disabled={requestAdminMutation.isPending}
						className="w-full bg-white text-[#214e51] hover:bg-white/90"
					>
						{requestAdminMutation.isPending ? "Bezig..." : "Vraag toegang aan"}
					</Button>
					<div className="mt-3 flex flex-col gap-2">
						<Button
							onClick={() => navigate({ to: "/account" })}
							variant="outline"
							className="w-full border-white/20 bg-transparent text-white hover:bg-white/10"
						>
							Mijn account
						</Button>
						<Button
							onClick={async () => {
								await authClient.signOut();
								navigate({ to: "/" });
							}}
							variant="outline"
							className="w-full border-white/10 bg-transparent text-white/40 hover:bg-white/5 hover:text-white"
						>
							<LogOut className="mr-2 h-4 w-4" />
							Uitloggen
						</Button>
					</div>
					<Link
						to="/"
						className="mt-4 block text-center text-sm text-white/30 hover:text-white/70"
					>
						← Terug naar website
					</Link>
				</div>
			</div>
		);
	}

	const thCls =
		"px-3 py-3 text-left font-mono text-[10px] uppercase tracking-widest text-white/35 cursor-pointer select-none hover:text-white/70 whitespace-nowrap";

	return (
		<div className="min-h-screen">
			<main className="mx-auto max-w-[1600px] space-y-6 px-5 py-6">
				{/* ── Utility row ── */}
				<div className="flex items-center justify-between">
					<div className="flex items-center gap-3">
						<Link
							to="/"
							className="font-mono text-white/40 text-xs hover:text-white/80"
						>
							← site
						</Link>
						<span className="text-white/15">|</span>
						<span className="font-['Intro',sans-serif] text-lg text-white">
							Admin
						</span>
						{pendingRequests.length > 0 && (
							<span className="rounded-full bg-yellow-500/20 px-2 py-0.5 font-mono text-[10px] text-yellow-400">
								{pendingRequests.length} aanvraag
								{pendingRequests.length !== 1 ? "en" : ""}
							</span>
						)}
					</div>
					<div className="flex items-center gap-2">
						<Link
							to="/admin/drinkkaart"
							className="rounded-lg border border-white/15 px-3 py-1.5 font-mono text-white/60 text-xs transition hover:border-white/30 hover:text-white"
						>
							Drinkkaart
						</Link>
						<button
							type="button"
							onClick={async () => {
								await authClient.signOut();
								navigate({ to: "/" });
							}}
							className="rounded-lg border border-white/10 px-3 py-1.5 font-mono text-white/40 text-xs transition hover:border-white/25 hover:text-white/80"
						>
							<LogOut className="inline h-3 w-3" />
						</button>
					</div>
				</div>
				{/* ── Pending admin requests ── */}
				{pendingRequests.length > 0 && (
					<div className="rounded-xl border border-yellow-500/25 bg-yellow-500/8 p-4">
						<p className="mb-3 font-mono text-[10px] text-yellow-400/70 uppercase tracking-widest">
							Openstaande admin aanvragen ({pendingRequests.length})
						</p>
						<div className="space-y-2">
							{pendingRequests.map((req) => (
								<div
									key={req.id}
									className="flex flex-col gap-3 rounded-lg border border-yellow-500/15 bg-yellow-500/5 px-4 py-3 sm:flex-row sm:items-center sm:justify-between"
								>
									<div>
										<p className="font-medium text-white">{req.userName}</p>
										<p className="text-white/50 text-xs">{req.userEmail}</p>
									</div>
									<div className="flex gap-2">
										<button
											type="button"
											onClick={() =>
												approveRequestMutation.mutate({ requestId: req.id })
											}
											disabled={approveRequestMutation.isPending}
											className="rounded-lg bg-green-600/80 px-4 py-1.5 font-semibold text-white text-xs transition hover:bg-green-600 disabled:opacity-50"
										>
											<Check className="mr-1 inline h-3 w-3" />
											Goedkeuren
										</button>
										<button
											type="button"
											onClick={() =>
												rejectRequestMutation.mutate({ requestId: req.id })
											}
											disabled={rejectRequestMutation.isPending}
											className="rounded-lg border border-red-500/30 px-4 py-1.5 font-semibold text-red-400 text-xs transition hover:bg-red-500/10 disabled:opacity-50"
										>
											<X className="mr-1 inline h-3 w-3" />
											Weigeren
										</button>
									</div>
								</div>
							))}
						</div>
					</div>
				)}

				{/* ── Stats grid ── */}
				<div className="grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-5">
					<StatCard
						label="Totaal inschrijvingen"
						value={stats?.total ?? 0}
						accent="white"
						sub={
							<span className="text-white/35">
								{stats?.today ?? 0} vandaag nieuw
							</span>
						}
					/>
					<StatCard
						label="Artiesten"
						accent="amber"
						value={performerCount}
						sub={stats?.byArtForm.slice(0, 3).map((item) => (
							<div
								key={item.artForm}
								className="flex justify-between text-amber-300/60"
							>
								<span className="truncate">{item.artForm || "Onbekend"}</span>
								<span className="ml-2 shrink-0 font-mono text-amber-300">
									{item.count}
								</span>
							</div>
						))}
					/>
					<StatCard
						label="Bezoekers aanwezig"
						accent="teal"
						value={totalWatcherAttendees}
						sub={
							<>
								<div className="flex justify-between text-teal-300/60">
									<span>Inschrijvingen</span>
									<span className="font-mono text-teal-300">
										{watcherCount}
									</span>
								</div>
								{totalGuestCount > 0 && (
									<div className="flex justify-between text-teal-300/60">
										<span>Gasten</span>
										<span className="font-mono text-teal-300">
											+{totalGuestCount}
										</span>
									</div>
								)}
								<div className="flex justify-between text-teal-300/60">
									<span>Drinkkaart</span>
									<span className="font-mono text-teal-300">
										€{totalDrinkCardValue}
									</span>
								</div>
							</>
						}
					/>
					<StatCard
						label="Gifts totaal"
						accent="pink"
						value={`€${Math.round(totalGiftRevenue / 100)}`}
						sub={
							<span className="text-pink-300/50">Vrijwillige bijdragen</span>
						}
					/>
					<StatCard
						label="Vandaag"
						accent="white"
						value={stats?.today ?? 0}
						sub={<span className="text-white/35">Nieuwe registraties</span>}
					/>
				</div>

				{/* ── Filters + export row ── */}
				<div className="rounded-xl border border-white/8 bg-white/3 p-4">
					<div className="grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-6">
						{/* Search */}
						<div className="lg:col-span-2">
							<div className="relative">
								<Search className="absolute top-1/2 left-3 h-3.5 w-3.5 -translate-y-1/2 text-white/30" />
								<Input
									placeholder="Naam of e-mail zoeken…"
									value={search}
									onChange={(e) => {
										setSearch(e.target.value);
										setPage(1);
									}}
									className="border-white/15 bg-white/8 pl-9 font-mono text-sm text-white placeholder:text-white/25 focus-visible:ring-teal-500/40"
								/>
							</div>
						</div>
						{/* Type */}
						<div>
							<select
								value={registrationType}
								onChange={(e) => {
									setRegistrationType(
										e.target.value as "performer" | "watcher" | "",
									);
									setPage(1);
								}}
								className="w-full rounded-md border border-white/15 bg-white/8 px-3 py-2 font-mono text-sm text-white focus:outline-none focus:ring-2 focus:ring-teal-500/40"
							>
								<option value="" className="bg-[#0d1f20]">
									Alle types
								</option>
								<option value="performer" className="bg-[#0d1f20]">
									Artiesten
								</option>
								<option value="watcher" className="bg-[#0d1f20]">
									Bezoekers
								</option>
							</select>
						</div>
						{/* Art form */}
						<div>
							<Input
								placeholder="Kunstvorm…"
								value={artForm}
								onChange={(e) => {
									setArtForm(e.target.value);
									setPage(1);
								}}
								className="border-white/15 bg-white/8 font-mono text-sm text-white placeholder:text-white/25 focus-visible:ring-teal-500/40"
							/>
						</div>
						{/* Date from */}
						<div>
							<Input
								type="date"
								value={fromDate}
								onChange={(e) => {
									setFromDate(e.target.value);
									setPage(1);
								}}
								className="border-white/15 bg-white/8 font-mono text-sm text-white [color-scheme:dark] focus-visible:ring-teal-500/40"
							/>
						</div>
						{/* Date to + export */}
						<div className="flex gap-2">
							<Input
								type="date"
								value={toDate}
								onChange={(e) => {
									setToDate(e.target.value);
									setPage(1);
								}}
								className="min-w-0 flex-1 border-white/15 bg-white/8 font-mono text-sm text-white [color-scheme:dark] focus-visible:ring-teal-500/40"
							/>
							<button
								type="button"
								onClick={() => exportMutation.mutate(undefined)}
								disabled={exportMutation.isPending}
								title="Exporteer CSV"
								className="shrink-0 rounded-md border border-white/15 bg-white/8 px-3 text-white/60 transition hover:border-teal-400/40 hover:bg-teal-400/10 hover:text-teal-300 disabled:opacity-40"
							>
								<Download className="h-4 w-4" />
							</button>
						</div>
					</div>
					<p className="mt-3 font-mono text-[11px] text-white/30">
						{pagination?.total ?? 0} registraties
						{totalGuestCount > 0 && (
							<span className="ml-2 text-teal-400/60">
								· {totalWatcherAttendees + performerCount} aanwezigen totaal
								(incl. {totalGuestCount} gasten)
							</span>
						)}
					</p>
				</div>

				{/* ── Table ── */}
				<div className="overflow-hidden rounded-xl border border-white/8 bg-white/3">
					{/* Desktop table */}
					<div className="hidden overflow-x-auto lg:block">
						<table className="w-full border-collapse">
							<thead>
								<tr className="border-white/8 border-b">
									<th className={thCls} style={{ width: "2.5rem" }} />
									<th className={thCls} onClick={() => handleSort("naam")}>
										Naam <SortIcon col="naam" />
									</th>
									<th className={thCls} onClick={() => handleSort("email")}>
										Email <SortIcon col="email" />
									</th>
									<th className={`${thCls} hidden xl:table-cell`}>Telefoon</th>
									<th className={`${thCls} hidden xl:table-cell`}>
										Geboortedatum
									</th>
									<th className={`${thCls} hidden xl:table-cell`}>Postcode</th>
									<th className={thCls} onClick={() => handleSort("type")}>
										Type <SortIcon col="type" />
									</th>
									<th className={thCls} onClick={() => handleSort("details")}>
										Details <SortIcon col="details" />
									</th>
									<th className={thCls} onClick={() => handleSort("gasten")}>
										Gasten <SortIcon col="gasten" />
									</th>
									<th className={thCls}>Notities</th>
									<th className={thCls} onClick={() => handleSort("gift")}>
										Gift <SortIcon col="gift" />
									</th>
									<th className={thCls} onClick={() => handleSort("betaling")}>
										Betaling <SortIcon col="betaling" />
									</th>
									<th className={thCls} onClick={() => handleSort("datum")}>
										Datum <SortIcon col="datum" />
									</th>
									<th className={thCls}>Link</th>
								</tr>
							</thead>
							<tbody>
								{registrationsQuery.isLoading ? (
									<tr>
										<td
											colSpan={14}
											className="px-4 py-12 text-center font-mono text-sm text-white/30"
										>
											laden...
										</td>
									</tr>
								) : sortedRegistrations.length === 0 ? (
									<tr>
										<td
											colSpan={14}
											className="px-4 py-12 text-center font-mono text-sm text-white/30"
										>
											Geen registraties gevonden
										</td>
									</tr>
								) : (
									sortedRegistrations.map((reg) => {
										const isPerformer = reg.registrationType === "performer";
										const guests = parseGuests(reg.guests);
										const guestCount = guests.length;
										const isExpanded = expandedRow === reg.id;
										const hasNotes = !!reg.extraQuestions?.trim();
										const hasExtra = guestCount > 0 || hasNotes;

										const detailLabel = isPerformer
											? reg.artForm || "—"
											: `€${reg.drinkCardValue ?? 5} drinkkaart`;

										const dateLabel = (() => {
											try {
												return new Date(reg.createdAt).toLocaleDateString(
													"nl-BE",
													{ day: "2-digit", month: "2-digit", year: "numeric" },
												);
											} catch {
												return "—";
											}
										})();

										const giftFmt = formatCents(reg.giftAmount);

										return (
											<>
												<tr
													key={reg.id}
													onClick={() => hasExtra && toggleRow(reg.id)}
													className={`border-white/5 border-b transition-colors ${hasExtra ? "cursor-pointer" : ""} ${isExpanded ? "bg-white/5" : "hover:bg-white/3"}`}
												>
													{/* Expand toggle */}
													<td className="py-3 pr-1 pl-3 text-center">
														{hasExtra ? (
															isExpanded ? (
																<ChevronDown className="h-3.5 w-3.5 text-white/40" />
															) : (
																<ChevronRight className="h-3.5 w-3.5 text-white/25" />
															)
														) : null}
													</td>
													<td className="px-3 py-3 font-medium text-white">
														{reg.firstName} {reg.lastName}
													</td>
													<td className="px-3 py-3 font-mono text-white/60 text-xs">
														{reg.email}
													</td>
													<td className="hidden px-3 py-3 font-mono text-white/45 text-xs xl:table-cell">
														{reg.phone || "—"}
													</td>
													<td className="hidden px-3 py-3 font-mono text-white/45 text-xs xl:table-cell">
														{reg.birthdate || "—"}
													</td>
													<td className="hidden px-3 py-3 font-mono text-white/45 text-xs xl:table-cell">
														{reg.postcode || "—"}
													</td>
													<td className="px-3 py-3">
														<span
															className={`rounded-full px-2 py-0.5 font-mono font-semibold text-[10px] uppercase tracking-wide ${isPerformer ? "bg-amber-400/12 text-amber-300" : "bg-teal-400/12 text-teal-300"}`}
														>
															{isPerformer ? "Artiest" : "Bezoeker"}
														</span>
													</td>
													<td className="px-3 py-3 font-mono text-white/60 text-xs">
														{detailLabel}
													</td>
													<td className="px-3 py-3 font-mono text-xs">
														{guestCount > 0 ? (
															<span className="text-teal-300">
																{guestCount}×
															</span>
														) : (
															<span className="text-white/20">—</span>
														)}
													</td>
													<td className="px-3 py-3">
														{hasNotes ? (
															<MessageSquare className="h-3.5 w-3.5 text-white/40" />
														) : (
															<span className="text-white/15 text-xs">—</span>
														)}
													</td>
													<td className="px-3 py-3 font-mono text-pink-300/70 text-xs">
														{giftFmt ?? (
															<span className="text-white/20">—</span>
														)}
													</td>
													<td className="px-3 py-3">
														<PayBadge
															status={reg.paymentStatus ?? null}
															paymentAmount={reg.paymentAmount ?? null}
															isPerformer={isPerformer}
														/>
													</td>
													<td className="px-3 py-3 font-mono text-white/40 text-xs tabular-nums">
														{dateLabel}
													</td>
													<td
														className="px-3 py-3"
														onClick={(e) => e.stopPropagation()}
														onKeyDown={(e) => e.stopPropagation()}
													>
														{reg.managementToken ? (
															<button
																type="button"
																title="Kopieer beheerlink"
																onClick={() =>
																	handleCopyManageUrl(
																		reg.managementToken as string,
																		reg.id,
																	)
																}
																className="rounded p-1 text-white/30 transition hover:bg-white/10 hover:text-white"
															>
																{copiedId === reg.id ? (
																	<ClipboardCheck className="h-3.5 w-3.5 text-green-400" />
																) : (
																	<Clipboard className="h-3.5 w-3.5" />
																)}
															</button>
														) : (
															<span className="text-white/15">—</span>
														)}
													</td>
												</tr>

												{/* Expanded detail row */}
												{isExpanded && (
													<tr
														key={`${reg.id}-detail`}
														className="border-white/5 border-b bg-white/5"
													>
														<td colSpan={14} className="px-6 pt-3 pb-5">
															<div className="grid gap-4 sm:grid-cols-2">
																{/* Guests */}
																{guestCount > 0 && (
																	<div>
																		<p className="mb-2 font-mono text-[10px] text-teal-400/60 uppercase tracking-widest">
																			Gasten ({guestCount})
																		</p>
																		<div className="space-y-1.5">
																			{guests.map((g, i) => (
																				<div
																					// biome-ignore lint/suspicious/noArrayIndexKey: stable order
																					key={i}
																					className="flex flex-wrap items-baseline gap-x-3 gap-y-0.5 rounded-lg border border-teal-400/10 bg-teal-400/5 px-3 py-2 text-sm"
																				>
																					<span className="font-mono text-[10px] text-white/30">
																						{i + 1}.
																					</span>
																					<span className="font-medium text-white">
																						{g.firstName} {g.lastName}
																					</span>
																					{g.email && (
																						<span className="font-mono text-white/50 text-xs">
																							{g.email}
																						</span>
																					)}
																					{g.phone && (
																						<span className="font-mono text-white/40 text-xs">
																							{g.phone}
																						</span>
																					)}
																					{g.birthdate && (
																						<span className="font-mono text-white/35 text-xs">
																							{g.birthdate}
																						</span>
																					)}
																					{g.postcode && (
																						<span className="font-mono text-white/35 text-xs">
																							{g.postcode}
																						</span>
																					)}
																					{!g.email && !g.phone && (
																						<span className="font-mono text-white/25 text-xs italic">
																							geen contactgegevens
																						</span>
																					)}
																				</div>
																			))}
																		</div>
																	</div>
																)}

																{/* Registrant birthdate + postcode */}
																{hasNotes && (
																	<div>
																		<p className="mb-2 font-mono text-[10px] text-white/40 uppercase tracking-widest">
																			Vragen / opmerkingen
																		</p>
																		<div className="rounded-lg border border-white/8 bg-white/5 px-4 py-3 text-sm text-white/80 leading-relaxed">
																			{reg.extraQuestions}
																		</div>
																	</div>
																)}

																{/* Performer extras */}
																{isPerformer &&
																	(reg.experience || reg.artForm) && (
																		<div>
																			<p className="mb-2 font-mono text-[10px] text-amber-400/60 uppercase tracking-widest">
																				Optreden details
																			</p>
																			<div className="rounded-lg border border-amber-400/10 bg-amber-400/5 px-4 py-3 text-sm text-white/80">
																				{reg.artForm && (
																					<p>
																						<span className="text-amber-300/60">
																							Kunstvorm:{" "}
																						</span>
																						{reg.artForm}
																					</p>
																				)}
																				{reg.experience && (
																					<p>
																						<span className="text-amber-300/60">
																							Ervaring:{" "}
																						</span>
																						{reg.experience}
																					</p>
																				)}
																				<p>
																					<span className="text-amber-300/60">
																						16+:{" "}
																					</span>
																					{reg.isOver16 ? "ja" : "nee"}
																				</p>
																			</div>
																		</div>
																	)}
															</div>
														</td>
													</tr>
												)}
											</>
										);
									})
								)}
							</tbody>
						</table>
					</div>

					{/* Mobile cards */}
					<div className="divide-y divide-white/5 lg:hidden">
						{registrationsQuery.isLoading ? (
							<div className="py-10 text-center font-mono text-sm text-white/30">
								laden...
							</div>
						) : sortedRegistrations.length === 0 ? (
							<div className="py-10 text-center font-mono text-sm text-white/30">
								Geen registraties
							</div>
						) : (
							sortedRegistrations.map((reg) => {
								const isPerformer = reg.registrationType === "performer";
								const guests = parseGuests(reg.guests);
								const guestCount = guests.length;
								const isExpanded = expandedRow === reg.id;
								const hasNotes = !!reg.extraQuestions?.trim();
								const hasExtra = guestCount > 0 || hasNotes;
								const giftFmt = formatCents(reg.giftAmount);

								return (
									<div key={reg.id}>
										{hasExtra ? (
											<button
												type="button"
												className={`w-full p-4 text-left transition-colors ${isExpanded ? "bg-white/5" : ""}`}
												onClick={() => toggleRow(reg.id)}
											>
												<div className="flex items-start justify-between gap-3">
													<div className="min-w-0 flex-1">
														<div className="flex items-center gap-2">
															{isExpanded ? (
																<ChevronDown className="h-3.5 w-3.5 shrink-0 text-white/40" />
															) : (
																<ChevronRight className="h-3.5 w-3.5 shrink-0 text-white/25" />
															)}
															<span className="truncate font-medium text-white">
																{reg.firstName} {reg.lastName}
															</span>
														</div>
														<p className="mt-0.5 truncate font-mono text-white/50 text-xs">
															{reg.email}
														</p>
														{reg.phone && (
															<p className="font-mono text-white/35 text-xs">
																{reg.phone}
															</p>
														)}
														{reg.birthdate && (
															<p className="font-mono text-white/30 text-xs">
																{reg.birthdate}
																{reg.postcode && ` · ${reg.postcode}`}
															</p>
														)}
													</div>
													<div className="flex shrink-0 flex-col items-end gap-1.5">
														<span
															className={`rounded-full px-2 py-0.5 font-mono font-semibold text-[10px] uppercase ${isPerformer ? "bg-amber-400/12 text-amber-300" : "bg-teal-400/12 text-teal-300"}`}
														>
															{isPerformer ? "Artiest" : "Bezoeker"}
														</span>
														<PayBadge
															status={reg.paymentStatus ?? null}
															paymentAmount={reg.paymentAmount ?? null}
															isPerformer={isPerformer}
														/>
														{reg.managementToken && (
															<button
																type="button"
																onClick={(e) => {
																	e.stopPropagation();
																	handleCopyManageUrl(
																		reg.managementToken as string,
																		reg.id,
																	);
																}}
																className="rounded p-1 text-white/30 hover:text-white"
															>
																{copiedId === reg.id ? (
																	<ClipboardCheck className="h-4 w-4 text-green-400" />
																) : (
																	<Clipboard className="h-4 w-4" />
																)}
															</button>
														)}
													</div>
												</div>
												<div className="mt-2 flex flex-wrap gap-x-3 gap-y-1 font-mono text-white/50 text-xs">
													{isPerformer ? (
														<span>{reg.artForm || "—"}</span>
													) : (
														<span>€{reg.drinkCardValue ?? 5} drinkkaart</span>
													)}
													{guestCount > 0 && (
														<span className="text-teal-300">
															{guestCount} gast{guestCount !== 1 ? "en" : ""}
														</span>
													)}
													{giftFmt && (
														<span className="text-pink-300/70">
															gift {giftFmt}
														</span>
													)}
													{hasNotes && (
														<span className="text-white/35">
															<MessageSquare className="mr-0.5 inline h-3 w-3" />
															notitie
														</span>
													)}
													<span className="text-white/30">
														{(() => {
															try {
																return new Date(
																	reg.createdAt,
																).toLocaleDateString("nl-BE", {
																	day: "2-digit",
																	month: "2-digit",
																	year: "2-digit",
																});
															} catch {
																return "—";
															}
														})()}
													</span>
												</div>
											</button>
										) : (
											<div className="p-4">
												<div className="flex items-start justify-between gap-3">
													<div className="min-w-0 flex-1">
														<span className="truncate font-medium text-white">
															{reg.firstName} {reg.lastName}
														</span>
														<p className="mt-0.5 truncate font-mono text-white/50 text-xs">
															{reg.email}
														</p>
														{reg.phone && (
															<p className="font-mono text-white/35 text-xs">
																{reg.phone}
															</p>
														)}
														{reg.birthdate && (
															<p className="font-mono text-white/30 text-xs">
																{reg.birthdate}
																{reg.postcode && ` · ${reg.postcode}`}
															</p>
														)}
													</div>
													<div className="flex shrink-0 flex-col items-end gap-1.5">
														<span
															className={`rounded-full px-2 py-0.5 font-mono font-semibold text-[10px] uppercase ${isPerformer ? "bg-amber-400/12 text-amber-300" : "bg-teal-400/12 text-teal-300"}`}
														>
															{isPerformer ? "Artiest" : "Bezoeker"}
														</span>
														<PayBadge
															status={reg.paymentStatus ?? null}
															paymentAmount={reg.paymentAmount ?? null}
															isPerformer={isPerformer}
														/>
														{reg.managementToken && (
															<button
																type="button"
																onClick={() =>
																	handleCopyManageUrl(
																		reg.managementToken as string,
																		reg.id,
																	)
																}
																className="rounded p-1 text-white/30 hover:text-white"
															>
																{copiedId === reg.id ? (
																	<ClipboardCheck className="h-4 w-4 text-green-400" />
																) : (
																	<Clipboard className="h-4 w-4" />
																)}
															</button>
														)}
													</div>
												</div>
												<div className="mt-2 flex flex-wrap gap-x-3 gap-y-1 font-mono text-white/50 text-xs">
													{isPerformer ? (
														<span>{reg.artForm || "—"}</span>
													) : (
														<span>€{reg.drinkCardValue ?? 5} drinkkaart</span>
													)}
													{giftFmt && (
														<span className="text-pink-300/70">
															gift {giftFmt}
														</span>
													)}
													<span className="text-white/30">
														{(() => {
															try {
																return new Date(
																	reg.createdAt,
																).toLocaleDateString("nl-BE", {
																	day: "2-digit",
																	month: "2-digit",
																	year: "2-digit",
																});
															} catch {
																return "—";
															}
														})()}
													</span>
												</div>
											</div>
										)}

										{/* Mobile expanded */}
										{isExpanded && (
											<div className="space-y-4 border-white/5 border-t bg-white/4 px-4 pt-3 pb-4">
												{guestCount > 0 && (
													<div>
														<p className="mb-2 font-mono text-[10px] text-teal-400/60 uppercase tracking-widest">
															Gasten
														</p>
														<div className="space-y-2">
															{guests.map((g, i) => (
																<div
																	// biome-ignore lint/suspicious/noArrayIndexKey: stable order
																	key={i}
																	className="rounded-lg border border-teal-400/10 bg-teal-400/5 px-3 py-2 text-sm"
																>
																	<p className="font-medium text-white">
																		{i + 1}. {g.firstName} {g.lastName}
																	</p>
																	{g.email && (
																		<p className="font-mono text-white/50 text-xs">
																			{g.email}
																		</p>
																	)}
																	{g.phone && (
																		<p className="font-mono text-white/40 text-xs">
																			{g.phone}
																		</p>
																	)}
																	{(g.birthdate || g.postcode) && (
																		<p className="font-mono text-white/30 text-xs">
																			{g.birthdate}
																			{g.birthdate && g.postcode && " · "}
																			{g.postcode}
																		</p>
																	)}
																</div>
															))}
														</div>
													</div>
												)}
												{hasNotes && (
													<div>
														<p className="mb-2 font-mono text-[10px] text-white/40 uppercase tracking-widest">
															Vragen / opmerkingen
														</p>
														<p className="rounded-lg border border-white/8 bg-white/5 px-4 py-3 text-sm text-white/80 leading-relaxed">
															{reg.extraQuestions}
														</p>
													</div>
												)}
												{isPerformer && (reg.experience || reg.artForm) && (
													<div>
														<p className="mb-2 font-mono text-[10px] text-amber-400/60 uppercase tracking-widest">
															Optreden details
														</p>
														<div className="rounded-lg border border-amber-400/10 bg-amber-400/5 px-3 py-2 text-sm text-white/80">
															{reg.artForm && (
																<p>
																	<span className="text-amber-300/60">
																		Kunstvorm:{" "}
																	</span>
																	{reg.artForm}
																</p>
															)}
															{reg.experience && (
																<p>
																	<span className="text-amber-300/60">
																		Ervaring:{" "}
																	</span>
																	{reg.experience}
																</p>
															)}
															<p>
																<span className="text-amber-300/60">16+: </span>
																{reg.isOver16 ? "ja" : "nee"}
															</p>
														</div>
													</div>
												)}
											</div>
										)}
									</div>
								);
							})
						)}
					</div>
				</div>
				{pagination && pagination.totalPages > 1 && (
					<div className="flex items-center justify-center gap-3">
						<button
							type="button"
							onClick={() => setPage((p) => Math.max(1, p - 1))}
							disabled={page === 1}
							className="rounded-lg border border-white/15 bg-white/5 px-4 py-1.5 font-mono text-white/60 text-xs transition hover:border-white/30 hover:text-white disabled:opacity-30"
						>
							← vorige
						</button>
						<span className="font-mono text-white/40 text-xs">
							{page} / {pagination.totalPages}
						</span>
						<button
							type="button"
							onClick={() =>
								setPage((p) => Math.min(pagination?.totalPages ?? p, p + 1))
							}
							disabled={page === pagination.totalPages}
							className="rounded-lg border border-white/15 bg-white/5 px-4 py-1.5 font-mono text-white/60 text-xs transition hover:border-white/30 hover:text-white disabled:opacity-30"
						>
							volgende →
						</button>
					</div>
				)}
			</main>
		</div>
	);
}
