import { useMutation, useQuery } from "@tanstack/react-query";
import { createFileRoute, Link, useNavigate } from "@tanstack/react-router";
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 { REGISTRATION_OPENS_AT } from "@/lib/opening";
import { useRegistrationOpen } from "@/lib/useRegistrationOpen";
import { orpc } from "@/utils/orpc";

export const Route = createFileRoute("/login")({
	validateSearch: (search: Record<string, unknown>) => {
		const signup =
			search.signup === "1" || search.signup === "true" ? "1" : undefined;
		const email = typeof search.email === "string" ? search.email : undefined;
		// Only return defined keys so redirects without search still typecheck
		return {
			...(signup !== undefined && { signup }),
			...(email !== undefined && { email }),
		} as { signup?: "1"; email?: string };
	},
	component: LoginPage,
});

function LoginPage() {
	const navigate = useNavigate();
	const search = Route.useSearch();
	const { isOpen } = useRegistrationOpen();
	const [isSignup, setIsSignup] = useState(() => search.signup === "1");
	const [email, setEmail] = useState(() => search.email ?? "");
	const [password, setPassword] = useState("");
	const [name, setName] = useState("");

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

	const loginMutation = useMutation({
		mutationFn: async ({
			email,
			password,
		}: {
			email: string;
			password: string;
		}) => {
			const result = await authClient.signIn.email({
				email,
				password,
			});
			if (result.error) {
				throw new Error(result.error.message);
			}
			return result.data;
		},
		onSuccess: () => {
			toast.success("Succesvol ingelogd!");
			authClient.getSession().then((session) => {
				const user = session.data?.user as { role?: string } | undefined;
				if (user?.role === "admin") {
					navigate({ to: "/admin" });
				} else {
					navigate({ to: "/account" });
				}
			});
		},
		onError: (error) => {
			toast.error(`Login mislukt: ${error.message}`);
		},
	});

	const signupMutation = useMutation({
		mutationFn: async ({
			email,
			password,
			name,
		}: {
			email: string;
			password: string;
			name: string;
		}) => {
			const result = await authClient.signUp.email({
				email,
				password,
				name,
			});
			if (result.error) {
				throw new Error(result.error.message);
			}
			return result.data;
		},
		onSuccess: () => {
			navigate({ to: "/account", search: { welkom: "1" } });
		},
		onError: (error) => {
			toast.error(`Registratie mislukt: ${error.message}`);
		},
	});

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

	const handleSubmit = (e: React.FormEvent) => {
		e.preventDefault();
		if (isSignup) {
			signupMutation.mutate({ email, password, name });
		} else {
			loginMutation.mutate({ email, password });
		}
	};

	const handleRequestAdmin = () => {
		requestAdminMutation.mutate(undefined);
	};

	// If already logged in, redirect to appropriate page
	if (sessionQuery.data?.data?.user) {
		const user = sessionQuery.data.data.user as { role?: string };
		if (user.role === "admin") {
			navigate({ to: "/admin" });
		} else {
			navigate({ to: "/account" });
		}
		return null;
	}

	const isLoggedIn = !!sessionQuery.data?.data?.user;
	const user = sessionQuery.data?.data?.user as
		| { role?: string; name?: string }
		| undefined;

	return (
		<div className="flex min-h-[calc(100dvh-2.75rem)] items-center justify-center overflow-y-auto px-4 py-8 sm:min-h-[calc(100dvh-3.5rem)]">
			<Card className="my-auto w-full max-w-md border-white/10 bg-white/5">
				<CardHeader className="text-center">
					<CardTitle className="font-['Intro',sans-serif] text-3xl text-white">
						{isLoggedIn
							? `Welkom, ${user?.name}`
							: isSignup
								? "Account Aanmaken"
								: "Inloggen"}
					</CardTitle>
					<CardDescription className="text-white/60">
						{isLoggedIn
							? "Je bent al ingelogd"
							: isSignup
								? "Maak een gratis account aan voor je Drinkkaart en inschrijving"
								: "Log in om je account te bekijken"}
					</CardDescription>
				</CardHeader>
				<CardContent>
					{isLoggedIn ? (
						<div className="space-y-4">
							{/* Primary CTA: go to account */}
							<Button
								onClick={() => navigate({ to: "/account" })}
								className="w-full bg-white text-[#214e51] hover:bg-white/90"
							>
								Ga naar mijn account
							</Button>

							{/* Secondary: request admin access */}
							<div className="rounded-lg border border-white/10 bg-white/5 p-4">
								<p className="mb-3 text-center text-sm text-white/60">
									Admin-toegang aanvragen?
								</p>
								<Button
									onClick={handleRequestAdmin}
									disabled={requestAdminMutation.isPending}
									variant="outline"
									className="w-full border-white/20 bg-transparent text-white hover:bg-white/10"
								>
									{requestAdminMutation.isPending
										? "Bezig..."
										: "Vraag Admin Toegang Aan"}
								</Button>
							</div>

							<Button
								onClick={() =>
									authClient.signOut().then(() => navigate({ to: "/" }))
								}
								variant="outline"
								className="w-full border-white/20 bg-transparent text-white/60 hover:bg-white/10 hover:text-white"
							>
								Uitloggen
							</Button>
							<Link
								to="/"
								className="block text-center text-sm text-white/40 hover:text-white"
							>
								← Terug naar website
							</Link>
						</div>
					) : isSignup && !isOpen ? (
						/* Signup is closed until registration opens */
						<div className="space-y-4">
							<div className="rounded-lg border border-white/10 bg-white/5 p-5 text-center">
								<p className="mb-1 font-['Intro',sans-serif] text-white">
									Registratie nog niet open
								</p>
								<p className="text-sm text-white/60">
									Accounts aanmaken kan vanaf{" "}
									<span className="text-teal-300">
										{REGISTRATION_OPENS_AT.toLocaleDateString("nl-BE", {
											weekday: "long",
											day: "numeric",
											month: "long",
										})}{" "}
										om{" "}
										{REGISTRATION_OPENS_AT.toLocaleTimeString("nl-BE", {
											hour: "2-digit",
											minute: "2-digit",
										})}
									</span>
									.
								</p>
							</div>
							<div className="flex flex-col gap-2 text-center">
								<button
									type="button"
									onClick={() => setIsSignup(false)}
									className="text-sm text-white/60 hover:text-white"
								>
									Al een account? Log in
								</button>
								<Link to="/" className="text-sm text-white/60 hover:text-white">
									← Terug naar website
								</Link>
							</div>
						</div>
					) : (
						<form onSubmit={handleSubmit} className="space-y-4">
							{isSignup && (
								<div>
									<label
										htmlFor="name"
										className="mb-2 block text-sm text-white/60"
									>
										Naam
									</label>
									<Input
										id="name"
										type="text"
										placeholder="Jouw naam"
										value={name}
										onChange={(e) => setName(e.target.value)}
										required
										className="border-white/20 bg-white/10 text-white placeholder:text-white/40"
									/>
								</div>
							)}
							<div>
								<label
									htmlFor="email"
									className="mb-2 block text-sm text-white/60"
								>
									Email
								</label>
								<Input
									id="email"
									type="email"
									placeholder="jouw@email.be"
									value={email}
									onChange={(e) => setEmail(e.target.value)}
									required
									className="border-white/20 bg-white/10 text-white placeholder:text-white/40"
								/>
							</div>
							<div>
								<label
									htmlFor="password"
									className="mb-2 block text-sm text-white/60"
								>
									Wachtwoord
								</label>
								<Input
									id="password"
									type="password"
									placeholder="••••••••"
									value={password}
									onChange={(e) => setPassword(e.target.value)}
									required
									className="border-white/20 bg-white/10 text-white placeholder:text-white/40"
								/>
							</div>
							{!isSignup && (
								<div className="text-right">
									<Link
										to="/forgot-password"
										className="text-sm text-white/50 hover:text-white"
									>
										Wachtwoord vergeten?
									</Link>
								</div>
							)}
							<Button
								type="submit"
								disabled={loginMutation.isPending || signupMutation.isPending}
								className="w-full bg-white text-[#214e51] hover:bg-white/90"
							>
								{loginMutation.isPending || signupMutation.isPending
									? "Bezig..."
									: isSignup
										? "Account Aanmaken"
										: "Inloggen"}
							</Button>
							<div className="flex flex-col gap-2 text-center">
								{/* Only show signup toggle when registration is open */}
								{isOpen && (
									<button
										type="button"
										onClick={() => setIsSignup(!isSignup)}
										className="text-sm text-white/60 hover:text-white"
									>
										{isSignup
											? "Al een account? Log in"
											: "Nog geen account? Registreer"}
									</button>
								)}
								{!isOpen && isSignup === false && (
									<button
										type="button"
										onClick={() => setIsSignup(true)}
										className="cursor-not-allowed text-sm text-white/30"
										disabled
										title={`Registratie opent op ${REGISTRATION_OPENS_AT.toLocaleString("nl-BE", { day: "numeric", month: "long", hour: "2-digit", minute: "2-digit" })}`}
									>
										Nog geen account? (opent{" "}
										{REGISTRATION_OPENS_AT.toLocaleString("nl-BE", {
											day: "numeric",
											month: "long",
										})}
										)
									</button>
								)}
								<Link to="/" className="text-sm text-white/60 hover:text-white">
									← Terug naar website
								</Link>
							</div>
						</form>
					)}
				</CardContent>
			</Card>
		</div>
	);
}
