import { useMutation, useQuery } from "@tanstack/react-query";
import {
	createFileRoute,
	Link,
	redirect,
	useNavigate,
} from "@tanstack/react-router";
import { Check, Download, LogOut, Search, Users, X } from "lucide-react";
import { useState } from "react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import {
	Card,
	CardContent,
	CardDescription,
	CardHeader,
	CardTitle,
} from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { authClient } from "@/lib/auth-client";
import { orpc } from "@/utils/orpc";

export const Route = createFileRoute("/admin")({
	component: AdminPage,
	beforeLoad: async () => {
		const session = await authClient.getSession();
		if (!session.data?.user) {
			throw redirect({ to: "/login" });
		}
		const user = session.data.user as { role?: string };
		if (user.role !== "admin") {
			throw redirect({ to: "/login" });
		}
	},
});

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 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: (error) => {
			toast.error(`Fout: ${error.message}`);
		},
	});

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

	const handleSignOut = async () => {
		await authClient.signOut();
		navigate({ to: "/" });
	};

	const handleExport = () => {
		exportMutation.mutate(undefined);
	};

	const handleApprove = (requestId: string) => {
		approveRequestMutation.mutate({ requestId });
	};

	const handleReject = (requestId: string) => {
		rejectRequestMutation.mutate({ requestId });
	};

	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;

	// Calculate total attendees including guests
	const totalRegistrations = registrationsQuery.data?.data ?? [];
	const watcherWithGuests = totalRegistrations.filter(
		(r) => r.registrationType === "watcher" && r.guests,
	);
	const totalGuestCount = watcherWithGuests.reduce((sum, r) => {
		try {
			const guests = JSON.parse(r.guests as string);
			return sum + (Array.isArray(guests) ? guests.length : 0);
		} catch {
			return sum;
		}
	}, 0);
	const totalWatcherAttendees = watcherCount + totalGuestCount;
	const totalDrinkCardValue = totalRegistrations
		.filter((r) => r.registrationType === "watcher")
		.reduce((sum, r) => sum + (r.drinkCardValue ?? 0), 0);

	return (
		<div className="min-h-screen bg-[#214e51]">
			{/* Header */}
			<header className="border-white/10 border-b bg-[#214e51]/95 px-8 py-6">
				<div className="mx-auto flex max-w-7xl items-center justify-between">
					<div className="flex items-center gap-4">
						<Link to="/" className="text-white hover:opacity-80">
							← Terug naar website
						</Link>
						<h1 className="font-['Intro',sans-serif] text-3xl text-white">
							Admin Dashboard
						</h1>
					</div>
					<Button
						onClick={handleSignOut}
						variant="outline"
						className="border-white/30 bg-transparent text-white hover:bg-white/10"
					>
						<LogOut className="mr-2 h-4 w-4" />
						Uitloggen
					</Button>
				</div>
			</header>

			{/* Main Content */}
			<main className="mx-auto max-w-7xl p-8">
				{/* Pending Admin Requests */}
				{pendingRequests.length > 0 && (
					<Card className="mb-6 border-yellow-500/30 bg-yellow-500/10">
						<CardHeader>
							<CardTitle className="font-['Intro',sans-serif] text-xl text-yellow-200">
								Openstaande Admin Aanvragen ({pendingRequests.length})
							</CardTitle>
							<CardDescription className="text-yellow-200/60">
								Gebruikers die admin toegang hebben aangevraagd
							</CardDescription>
						</CardHeader>
						<CardContent>
							<div className="space-y-3">
								{pendingRequests.map((request) => (
									<div
										key={request.id}
										className="flex items-center justify-between rounded-lg border border-yellow-500/20 bg-yellow-500/5 p-4"
									>
										<div>
											<p className="font-medium text-white">
												{request.userName}
											</p>
											<p className="text-sm text-white/60">
												{request.userEmail}
											</p>
											<p className="text-white/40 text-xs">
												Aangevraagd:{" "}
												{new Date(request.requestedAt).toLocaleDateString(
													"nl-BE",
												)}
											</p>
										</div>
										<div className="flex gap-2">
											<Button
												onClick={() => handleApprove(request.id)}
												disabled={approveRequestMutation.isPending}
												size="sm"
												className="bg-green-600 text-white hover:bg-green-700"
											>
												<Check className="mr-1 h-4 w-4" />
												Goedkeuren
											</Button>
											<Button
												onClick={() => handleReject(request.id)}
												disabled={rejectRequestMutation.isPending}
												size="sm"
												variant="outline"
												className="border-red-500/30 text-red-400 hover:bg-red-500/10"
											>
												<X className="mr-1 h-4 w-4" />
												Weigeren
											</Button>
										</div>
									</div>
								))}
							</div>
						</CardContent>
					</Card>
				)}

				{/* Stats Cards */}
				<div className="mb-8 grid grid-cols-1 gap-6 md:grid-cols-4">
					<Card className="border-white/10 bg-white/5">
						<CardHeader className="pb-2">
							<CardDescription className="text-white/60">
								Totaal inschrijvingen
							</CardDescription>
							<CardTitle className="font-['Intro',sans-serif] text-4xl text-white">
								{stats?.total ?? 0}
							</CardTitle>
						</CardHeader>
						<CardContent>
							<Users className="h-5 w-5 text-white/40" />
						</CardContent>
					</Card>

					<Card className="border-white/10 bg-white/5">
						<CardHeader className="pb-2">
							<CardDescription className="text-white/60">
								Vandaag ingeschreven
							</CardDescription>
							<CardTitle className="font-['Intro',sans-serif] text-4xl text-white">
								{stats?.today ?? 0}
							</CardTitle>
						</CardHeader>
						<CardContent>
							<span className="text-sm text-white/40">
								Nieuwe registraties vandaag
							</span>
						</CardContent>
					</Card>

					<Card className="border-amber-400/20 bg-amber-400/5">
						<CardHeader className="pb-2">
							<CardDescription className="text-amber-300/70">
								Artiesten
							</CardDescription>
							<CardTitle className="font-['Intro',sans-serif] text-4xl text-amber-300">
								{performerCount}
							</CardTitle>
						</CardHeader>
						<CardContent>
							<div className="space-y-1">
								{stats?.byArtForm.slice(0, 4).map((item) => (
									<div
										key={item.artForm}
										className="flex items-center justify-between text-xs"
									>
										<span className="text-amber-300/70">
											{item.artForm || "Onbekend"}
										</span>
										<span className="text-amber-300">{item.count}</span>
									</div>
								))}
							</div>
						</CardContent>
					</Card>

					<Card className="border-teal-400/20 bg-teal-400/5">
						<CardHeader className="pb-2">
							<CardDescription className="text-teal-300/70">
								Bezoekers
							</CardDescription>
							<CardTitle className="font-['Intro',sans-serif] text-4xl text-teal-300">
								{watcherCount}
							</CardTitle>
						</CardHeader>
						<CardContent>
							<div className="space-y-1 text-xs">
								{totalGuestCount > 0 && (
									<div className="flex items-center justify-between">
										<span className="text-teal-300/70">Inclusief gasten</span>
										<span className="text-teal-300">+{totalGuestCount}</span>
									</div>
								)}
								<div className="flex items-center justify-between">
									<span className="text-teal-300/70">Totaal aanwezig</span>
									<span className="font-semibold text-teal-300">
										{totalWatcherAttendees}
									</span>
								</div>
								<div className="flex items-center justify-between">
									<span className="text-teal-300/70">Drinkkaart</span>
									<span className="text-teal-300">€{totalDrinkCardValue}</span>
								</div>
							</div>
						</CardContent>
					</Card>
				</div>

				{/* Filters */}
				<Card className="mb-6 border-white/10 bg-white/5">
					<CardHeader>
						<CardTitle className="font-['Intro',sans-serif] text-white text-xl">
							Filters
						</CardTitle>
					</CardHeader>
					<CardContent>
						<div className="grid grid-cols-1 gap-4 md:grid-cols-5">
							<div>
								<label
									htmlFor="search"
									className="mb-2 block text-sm text-white/60"
								>
									Zoeken
								</label>
								<div className="relative">
									<Search className="absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-white/40" />
									<Input
										id="search"
										placeholder="Naam of email..."
										value={search}
										onChange={(e) => setSearch(e.target.value)}
										className="border-white/20 bg-white/10 pl-10 text-white placeholder:text-white/40"
									/>
								</div>
							</div>

							<div>
								<label
									htmlFor="typeFilter"
									className="mb-2 block text-sm text-white/60"
								>
									Type
								</label>
								<select
									id="typeFilter"
									value={registrationType}
									onChange={(e) =>
										setRegistrationType(
											e.target.value as "performer" | "watcher" | "",
										)
									}
									className="w-full rounded-md border border-white/20 bg-white/10 px-3 py-2 text-white focus:outline-none focus:ring-2 focus:ring-white/20"
								>
									<option value="" className="bg-[#214e51]">
										Alle types
									</option>
									<option value="performer" className="bg-[#214e51]">
										Artiesten
									</option>
									<option value="watcher" className="bg-[#214e51]">
										Bezoekers
									</option>
								</select>
							</div>

							<div>
								<label
									htmlFor="artForm"
									className="mb-2 block text-sm text-white/60"
								>
									Kunstvorm
								</label>
								<Input
									id="artForm"
									placeholder="Filter op kunstvorm..."
									value={artForm}
									onChange={(e) => setArtForm(e.target.value)}
									className="border-white/20 bg-white/10 text-white placeholder:text-white/40"
								/>
							</div>

							<div>
								<label
									htmlFor="fromDate"
									className="mb-2 block text-sm text-white/60"
								>
									Vanaf
								</label>
								<Input
									id="fromDate"
									type="date"
									value={fromDate}
									onChange={(e) => setFromDate(e.target.value)}
									className="border-white/20 bg-white/10 text-white [color-scheme:dark]"
								/>
							</div>

							<div>
								<label
									htmlFor="toDate"
									className="mb-2 block text-sm text-white/60"
								>
									Tot
								</label>
								<Input
									id="toDate"
									type="date"
									value={toDate}
									onChange={(e) => setToDate(e.target.value)}
									className="border-white/20 bg-white/10 text-white [color-scheme:dark]"
								/>
							</div>
						</div>
					</CardContent>
				</Card>

				{/* Export Button */}
				<div className="mb-6 flex items-center justify-between">
					<p className="text-white/60">
						{pagination?.total ?? 0} registraties gevonden
					</p>
					<Button
						onClick={handleExport}
						disabled={exportMutation.isPending}
						className="bg-white text-[#214e51] hover:bg-white/90"
					>
						<Download className="mr-2 h-4 w-4" />
						{exportMutation.isPending ? "Exporteren..." : "Exporteer CSV"}
					</Button>
				</div>

				{/* Registrations Table */}
				<Card className="border-white/10 bg-white/5">
					<CardContent className="p-0">
						<div className="overflow-x-auto">
							<table className="w-full">
								<thead>
									<tr className="border-white/10 border-b">
										<th className="px-6 py-4 text-left font-medium text-sm text-white/60">
											Naam
										</th>
										<th className="px-6 py-4 text-left font-medium text-sm text-white/60">
											Email
										</th>
										<th className="px-6 py-4 text-left font-medium text-sm text-white/60">
											Telefoon
										</th>
										<th className="px-6 py-4 text-left font-medium text-sm text-white/60">
											Type
										</th>
										<th className="px-6 py-4 text-left font-medium text-sm text-white/60">
											Kunstvorm / Drinkkaart
										</th>
										<th className="px-6 py-4 text-left font-medium text-sm text-white/60">
											Gezelschap
										</th>
										<th className="px-6 py-4 text-left font-medium text-sm text-white/60">
											Ervaring
										</th>
										<th className="px-6 py-4 text-left font-medium text-sm text-white/60">
											16+
										</th>
										<th className="px-6 py-4 text-left font-medium text-sm text-white/60">
											Betaald
										</th>
										<th className="px-6 py-4 text-left font-medium text-sm text-white/60">
											Betaald
										</th>
										<th className="px-6 py-4 text-left font-medium text-sm text-white/60">
											Datum
										</th>
									</tr>
								</thead>
								<tbody>
									{registrationsQuery.isLoading ? (
										<tr>
											<td
												colSpan={10}
												className="px-6 py-8 text-center text-white/60"
											>
												Laden...
											</td>
										</tr>
									) : registrations.length === 0 ? (
										<tr>
											<td
												colSpan={10}
												className="px-6 py-8 text-center text-white/60"
											>
												Geen registraties gevonden
											</td>
										</tr>
									) : (
										registrations.map((reg) => {
											const isPerformer = reg.registrationType === "performer";
											return (
												<tr
													key={reg.id}
													className="border-white/5 border-b hover:bg-white/5"
												>
													<td className="px-6 py-4 text-white">
														{reg.firstName} {reg.lastName}
													</td>
													<td className="px-6 py-4 text-white/80">
														{reg.email}
													</td>
													<td className="px-6 py-4 text-white/80">
														{reg.phone || "-"}
													</td>
													<td className="px-6 py-4">
														<span
															className={`inline-flex items-center rounded-full px-2.5 py-0.5 font-semibold text-xs ${isPerformer ? "bg-amber-400/15 text-amber-300" : "bg-teal-400/15 text-teal-300"}`}
														>
															{isPerformer ? "Artiest" : "Bezoeker"}
														</span>
													</td>
													<td className="px-6 py-4 text-white/80">
														{isPerformer
															? reg.artForm || "-"
															: `€${reg.drinkCardValue ?? 5} drinkkaart`}
													</td>
													<td className="px-6 py-4 text-white/80">
														{isPerformer
															? "-"
															: (() => {
																	if (!reg.guests) return "-";
																	try {
																		const guests = JSON.parse(
																			reg.guests as string,
																		);
																		const count = Array.isArray(guests)
																			? guests.length
																			: 0;
																		return count > 0
																			? `${count} gast${count === 1 ? "" : "en"}`
																			: "-";
																	} catch {
																		return "-";
																	}
																})()}
													</td>
													<td className="px-6 py-4 text-white/80">
														{isPerformer ? reg.experience || "-" : "-"}
													</td>
													<td className="px-6 py-4 text-white/80">
														{isPerformer ? (
															reg.isOver16 ? (
																<span className="text-green-400">✓</span>
															) : (
																<span className="text-red-400">✗</span>
															)
														) : (
															"-"
														)}
													</td>
													<td className="px-6 py-4">
														{isPerformer ? (
															<span className="text-white/40">-</span>
														) : reg.paymentStatus === "paid" ? (
															<span className="inline-flex items-center gap-1 text-green-400 text-sm">
																<svg
																	className="h-4 w-4"
																	fill="none"
																	viewBox="0 0 24 24"
																	stroke="currentColor"
																	strokeWidth={2}
																>
																	<title>Betaald icoon</title>
																	<path
																		strokeLinecap="round"
																		strokeLinejoin="round"
																		d="M5 13l4 4L19 7"
																	/>
																</svg>
																Betaald
															</span>
														) : (
															<span className="inline-flex items-center gap-1 text-sm text-yellow-400">
																<svg
																	className="h-4 w-4"
																	fill="none"
																	viewBox="0 0 24 24"
																	stroke="currentColor"
																	strokeWidth={2}
																>
																	<title>In afwachting icoon</title>
																	<path
																		strokeLinecap="round"
																		strokeLinejoin="round"
																		d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"
																	/>
																</svg>
																Open
															</span>
														)}
													</td>
													<td className="px-6 py-4 text-white/60">
														{new Date(reg.createdAt).toLocaleDateString(
															"nl-BE",
														)}
													</td>
												</tr>
											);
										})
									)}
								</tbody>
							</table>
						</div>
					</CardContent>
				</Card>

				{/* Pagination */}
				{pagination && pagination.totalPages > 1 && (
					<div className="mt-6 flex items-center justify-center gap-2">
						<Button
							onClick={() => setPage((p) => Math.max(1, p - 1))}
							disabled={page === 1}
							variant="outline"
							className="border-white/20 bg-transparent text-white hover:bg-white/10 disabled:opacity-50"
						>
							Vorige
						</Button>
						<span className="mx-4 text-white">
							Pagina {page} van {pagination.totalPages}
						</span>
						<Button
							onClick={() =>
								setPage((p) => Math.min(pagination.totalPages, p + 1))
							}
							disabled={page === pagination.totalPages}
							variant="outline"
							className="border-white/20 bg-transparent text-white hover:bg-white/10 disabled:opacity-50"
						>
							Volgende
						</Button>
					</div>
				)}
			</main>
		</div>
	);
}
