import { useMutation } from "@tanstack/react-query";
import { useState } from "react";
import { toast } from "sonner";
import { authClient } from "@/lib/auth-client";
import {
	calculateDrinkCard,
	type GuestEntry,
	type GuestErrors,
	inputCls,
	validateEmail,
	validateGuests,
	validatePhone,
	validateTextField,
} from "@/lib/registration";
import { client, orpc } from "@/utils/orpc";
import { GiftSelector } from "./GiftSelector";
import { GuestList } from "./GuestList";

interface WatcherErrors {
	firstName?: string;
	lastName?: string;
	email?: string;
	phone?: string;
	postcode?: string;
	birthdate?: string;
}

interface Props {
	onBack: () => void;
	prefillFirstName?: string;
	prefillLastName?: string;
	prefillEmail?: string;
	isLoggedIn?: boolean;
}

// ── Account creation modal shown after successful registration ─────────────

interface AccountModalProps {
	prefillName: string;
	prefillEmail: string;
	onDone: () => void;
}

function AccountModal({
	prefillName,
	prefillEmail,
	onDone,
}: AccountModalProps) {
	const [name, setName] = useState(prefillName);
	const [email] = useState(prefillEmail); // email is fixed (tied to registration)
	const [password, setPassword] = useState("");
	const [confirmPassword, setConfirmPassword] = useState("");
	const [passwordError, setPasswordError] = useState<string | undefined>();

	const signupMutation = useMutation({
		mutationFn: async () => {
			if (password.length < 8)
				throw new Error("Wachtwoord moet minstens 8 tekens zijn");
			if (password !== confirmPassword)
				throw new Error("Wachtwoorden komen niet overeen");
			const result = await authClient.signUp.email({ email, password, name });
			if (result.error) throw new Error(result.error.message);
			return result.data;
		},
		onSuccess: () => {
			toast.success(
				"Account aangemaakt! Je wordt nu doorgestuurd naar betaling.",
			);
			onDone();
		},
		onError: (error) => {
			toast.error(`Account aanmaken mislukt: ${error.message}`);
		},
	});

	const handlePasswordChange = (val: string) => {
		setPassword(val);
		if (passwordError) setPasswordError(undefined);
	};

	const handleConfirmChange = (val: string) => {
		setConfirmPassword(val);
		if (passwordError) setPasswordError(undefined);
	};

	const handleSignup = (e: React.FormEvent) => {
		e.preventDefault();
		if (password.length < 8) {
			setPasswordError("Wachtwoord moet minstens 8 tekens zijn");
			return;
		}
		if (password !== confirmPassword) {
			setPasswordError("Wachtwoorden komen niet overeen");
			return;
		}
		signupMutation.mutate();
	};

	// Receive the checkout URL from parent by exposing a setter via ref pattern
	// (simpler: the parent renders the modal and passes a prop)

	return (
		<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 px-4">
			<div className="w-full max-w-md rounded-2xl border border-white/10 bg-[#1a3d40] p-8 shadow-2xl">
				{/* Header */}
				<div className="mb-6 flex items-start gap-4">
					<div className="flex h-12 w-12 shrink-0 items-center justify-center rounded-full bg-teal-400/20 text-teal-300 text-xl">
						✓
					</div>
					<div>
						<h2 className="font-['Intro',sans-serif] text-2xl text-white">
							Inschrijving gelukt!
						</h2>
						<p className="mt-1 text-sm text-white/60">
							Maak een gratis account aan om je Drinkkaart bij te houden.
						</p>
					</div>
				</div>

				{/* Value prop */}
				<div className="mb-6 rounded-lg border border-teal-400/20 bg-teal-400/10 p-4">
					<ul className="space-y-1.5 text-sm text-white/80">
						<li className="flex items-center gap-2">
							<span className="text-teal-300">✓</span>
							Zie je drinkkaart-saldo en QR-code
						</li>
						<li className="flex items-center gap-2">
							<span className="text-teal-300">✓</span>
							Laad je kaart op vóór het evenement
						</li>
						<li className="flex items-center gap-2">
							<span className="text-teal-300">✓</span>
							Beheer je inschrijving op één plek
						</li>
					</ul>
				</div>

				{/* Signup form */}
				<form onSubmit={handleSignup} className="space-y-4">
					{/* Name */}
					<div>
						<label
							className="mb-1.5 block text-sm text-white/60"
							htmlFor="modal-name"
						>
							Naam
						</label>
						<input
							id="modal-name"
							type="text"
							value={name}
							onChange={(e) => setName(e.target.value)}
							required
							className="w-full rounded-lg border border-white/20 bg-white/10 px-3 py-2 text-white placeholder:text-white/30 focus:border-teal-400/60 focus:outline-none"
						/>
					</div>

					{/* Email (read-only) */}
					<div>
						<label
							className="mb-1.5 block text-sm text-white/60"
							htmlFor="modal-email"
						>
							Email
						</label>
						<input
							id="modal-email"
							type="email"
							value={email}
							readOnly
							className="w-full cursor-not-allowed rounded-lg border border-white/10 bg-white/5 px-3 py-2 text-white/60"
						/>
					</div>

					{/* Password */}
					<div>
						<label
							className="mb-1.5 block text-sm text-white/60"
							htmlFor="modal-password"
						>
							Wachtwoord
						</label>
						<input
							id="modal-password"
							type="password"
							placeholder="Minstens 8 tekens"
							value={password}
							onChange={(e) => handlePasswordChange(e.target.value)}
							required
							minLength={8}
							className="w-full rounded-lg border border-white/20 bg-white/10 px-3 py-2 text-white placeholder:text-white/30 focus:border-teal-400/60 focus:outline-none"
						/>
					</div>

					{/* Confirm password */}
					<div>
						<label
							className="mb-1.5 block text-sm text-white/60"
							htmlFor="modal-confirm"
						>
							Bevestig wachtwoord
						</label>
						<input
							id="modal-confirm"
							type="password"
							placeholder="Herhaal je wachtwoord"
							value={confirmPassword}
							onChange={(e) => handleConfirmChange(e.target.value)}
							required
							className="w-full rounded-lg border border-white/20 bg-white/10 px-3 py-2 text-white placeholder:text-white/30 focus:border-teal-400/60 focus:outline-none"
						/>
					</div>

					{passwordError && (
						<p className="text-red-300 text-sm">{passwordError}</p>
					)}

					<button
						type="submit"
						disabled={signupMutation.isPending}
						className="w-full rounded-lg bg-white py-3 font-['Intro',sans-serif] text-[#214e51] transition-all hover:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-50"
					>
						{signupMutation.isPending
							? "Bezig..."
							: "Account aanmaken & betalen"}
					</button>
				</form>

				{/* Skip */}
				<button
					type="button"
					onClick={onDone}
					className="mt-4 w-full text-center text-sm text-white/40 transition-colors hover:text-white/70"
				>
					Overslaan, verder naar betaling →
				</button>
			</div>
		</div>
	);
}

// ── Main watcher form ──────────────────────────────────────────────────────

export function WatcherForm({
	onBack,
	prefillFirstName = "",
	prefillLastName = "",
	prefillEmail = "",
	isLoggedIn = false,
}: Props) {
	const [data, setData] = useState({
		firstName: prefillFirstName,
		lastName: prefillLastName,
		email: prefillEmail,
		phone: "",
		postcode: "",
		birthdate: "",
		extraQuestions: "",
	});
	const [errors, setErrors] = useState<WatcherErrors>({});
	const [touched, setTouched] = useState<Record<string, boolean>>({});
	const [guests, setGuests] = useState<GuestEntry[]>([]);
	const [guestErrors, setGuestErrors] = useState<GuestErrors[]>([]);
	const [giftAmount, setGiftAmount] = useState(0);

	// Modal state: shown after successful registration while we fetch checkout URL
	const [modalState, setModalState] = useState<{
		prefillName: string;
		prefillEmail: string;
		checkoutUrl: string;
	} | null>(null);

	const submitMutation = useMutation({
		...orpc.submitRegistration.mutationOptions(),
		onSuccess: async (result) => {
			if (!result.managementToken) return;
			try {
				const redirectUrl = isLoggedIn
					? `${window.location.origin}/account?topup=success`
					: undefined;
				const checkout = await client.getCheckoutUrl({
					token: result.managementToken,
					redirectUrl,
				});
				if (isLoggedIn) {
					// Already logged in — skip the account-creation modal, go straight to checkout
					window.location.href = checkout.checkoutUrl;
				} else {
					// Show the account-creation modal before redirecting to checkout
					setModalState({
						prefillName:
							`${data.firstName.trim()} ${data.lastName.trim()}`.trim(),
						prefillEmail: data.email.trim(),
						checkoutUrl: checkout.checkoutUrl,
					});
				}
			} catch (error) {
				console.error("Checkout error:", error);
				toast.error("Er is iets misgegaan bij het aanmaken van de betaling");
			}
		},
		onError: (error) => {
			toast.error(`Er is iets misgegaan: ${error.message}`);
		},
	});

	function validate(): boolean {
		const fieldErrs: WatcherErrors = {
			firstName: validateTextField(data.firstName, true, "Voornaam"),
			lastName: validateTextField(data.lastName, true, "Achternaam"),
			email: validateEmail(data.email),
			phone: validatePhone(data.phone),
			postcode: !data.postcode.trim() ? "Postcode is verplicht" : undefined,
			birthdate: !data.birthdate ? "Geboortedatum is verplicht" : undefined,
		};
		setErrors(fieldErrs);
		setTouched({
			firstName: true,
			lastName: true,
			email: true,
			phone: true,
			postcode: true,
			birthdate: true,
		});
		const { errors: gErrs, valid: gValid } = validateGuests(guests);
		setGuestErrors(gErrs);
		return !Object.values(fieldErrs).some(Boolean) && gValid;
	}

	function handleChange(
		e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
	) {
		const { name, value } = e.target;
		setData((prev) => ({ ...prev, [name]: value }));
		if (touched[name]) {
			const errMap: Record<string, string | undefined> = {
				firstName: validateTextField(value, true, "Voornaam"),
				lastName: validateTextField(value, true, "Achternaam"),
				email: validateEmail(value),
				phone: validatePhone(value),
				postcode:
					name === "postcode" && !value.trim()
						? "Postcode is verplicht"
						: undefined,
				birthdate:
					name === "birthdate" && !value
						? "Geboortedatum is verplicht"
						: undefined,
			};
			setErrors((prev) => ({ ...prev, [name]: errMap[name] }));
		}
	}

	function handleBlur(
		e: React.FocusEvent<HTMLInputElement | HTMLTextAreaElement>,
	) {
		const { name, value } = e.target;
		setTouched((prev) => ({ ...prev, [name]: true }));
		const errMap: Record<string, string | undefined> = {
			firstName: validateTextField(value, true, "Voornaam"),
			lastName: validateTextField(value, true, "Achternaam"),
			email: validateEmail(value),
			phone: validatePhone(value),
			postcode:
				name === "postcode" && !value.trim()
					? "Postcode is verplicht"
					: undefined,
			birthdate:
				name === "birthdate" && !value
					? "Geboortedatum is verplicht"
					: undefined,
		};
		setErrors((prev) => ({ ...prev, [name]: errMap[name] }));
	}

	function handleGuestChange(
		index: number,
		field: keyof GuestEntry,
		value: string,
	) {
		setGuests((prev) => {
			const next = [...prev];
			next[index] = { ...next[index], [field]: value } as GuestEntry;
			return next;
		});
	}

	function handleAddGuest() {
		if (guests.length >= 9) return;
		setGuests((prev) => [
			...prev,
			{
				firstName: "",
				lastName: "",
				email: "",
				phone: "",
				birthdate: "",
				postcode: "",
			},
		]);
		setGuestErrors((prev) => [...prev, {}]);
	}

	function handleRemoveGuest(index: number) {
		setGuests((prev) => prev.filter((_, i) => i !== index));
		setGuestErrors((prev) => prev.filter((_, i) => i !== index));
	}

	function handleSubmit(e: React.FormEvent) {
		e.preventDefault();
		if (!validate()) {
			toast.error("Controleer je invoer");
			return;
		}
		submitMutation.mutate({
			firstName: data.firstName.trim(),
			lastName: data.lastName.trim(),
			email: data.email.trim(),
			phone: data.phone.trim() || undefined,
			postcode: data.postcode.trim(),
			birthdate: data.birthdate,
			registrationType: "watcher",
			guests: guests.map((g) => ({
				firstName: g.firstName.trim(),
				lastName: g.lastName.trim(),
				email: g.email.trim() || undefined,
				phone: g.phone.trim() || undefined,
				birthdate: g.birthdate.trim(),
				postcode: g.postcode.trim(),
			})),
			extraQuestions: data.extraQuestions.trim() || undefined,
			giftAmount,
		});
	}

	const totalPrice = calculateDrinkCard(guests.length);

	return (
		<div>
			{/* Account-creation interstitial modal */}
			{modalState && (
				<AccountModal
					prefillName={modalState.prefillName}
					prefillEmail={modalState.prefillEmail}
					onDone={() => {
						const url = modalState.checkoutUrl;
						setModalState(null);
						window.location.href = url;
					}}
				/>
			)}

			{/* Back + type header */}
			<div className="mb-8 flex items-center gap-4">
				<button
					type="button"
					onClick={onBack}
					className="flex items-center gap-2 text-white/60 transition-colors hover:text-white"
				>
					<svg
						className="h-4 w-4"
						fill="none"
						viewBox="0 0 24 24"
						stroke="currentColor"
						strokeWidth={2}
						aria-hidden="true"
					>
						<path
							strokeLinecap="round"
							strokeLinejoin="round"
							d="M10.5 19.5L3 12m0 0l7.5-7.5M3 12h18"
						/>
					</svg>
					Terug
				</button>
				<div className="h-px flex-1 bg-white/10" />
				<div className="flex items-center gap-2">
					<div className="flex h-8 w-8 items-center justify-center rounded-full bg-teal-400/20 text-teal-300">
						<svg
							className="h-4 w-4"
							fill="none"
							viewBox="0 0 24 24"
							stroke="currentColor"
							strokeWidth={1.5}
							aria-hidden="true"
						>
							<path
								strokeLinecap="round"
								strokeLinejoin="round"
								d="M16.5 6v.75m0 3v.75m0 3v.75m0 3V18m-9-5.25h5.25M7.5 15h3M3.375 5.25c-.621 0-1.125.504-1.125 1.125v3.026a2.999 2.999 0 010 5.198v3.026c0 .621.504 1.125 1.125 1.125h17.25c.621 0 1.125-.504 1.125-1.125v-3.026a2.999 2.999 0 010-5.198V6.375c0-.621-.504-1.125-1.125-1.125H3.375z"
							/>
						</svg>
					</div>
					<span className="font-['Intro',sans-serif] text-teal-300">
						Ik wil komen kijken
					</span>
				</div>
			</div>

			{/* Live price callout */}
			<div className="mb-8 flex items-center gap-4 rounded-lg border border-teal-400/30 bg-teal-400/10 p-5">
				<div className="flex h-12 w-12 shrink-0 items-center justify-center rounded-full bg-teal-400/20 font-bold text-teal-300 text-xl">
					€{totalPrice}
				</div>
				<div>
					<p className="font-semibold text-white">Drinkkaart inbegrepen</p>
					<p className="text-sm text-white/70">
						Je betaald bij registratie
						<strong className="text-teal-300">€5</strong> (+ €2 per
						medebezoeker) dat gaat naar je drinkkaart.
						{guests.length > 0 && (
							<span className="ml-1 font-semibold text-teal-300">
								Totaal: €{totalPrice} voor {1 + guests.length} personen.
							</span>
						)}
					</p>
				</div>
			</div>

			<form onSubmit={handleSubmit} className="flex flex-col gap-6" noValidate>
				{/* Name row */}
				<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
					<div className="flex flex-col gap-2">
						<label htmlFor="w-firstName" className="text-white text-xl">
							Voornaam <span className="text-red-300">*</span>
						</label>
						<input
							type="text"
							id="w-firstName"
							name="firstName"
							value={data.firstName}
							onChange={handleChange}
							onBlur={handleBlur}
							placeholder="Jouw voornaam"
							autoComplete="given-name"
							aria-required="true"
							aria-invalid={touched.firstName && !!errors.firstName}
							className={inputCls(!!touched.firstName && !!errors.firstName)}
						/>
						{touched.firstName && errors.firstName && (
							<span className="text-red-300 text-sm" role="alert">
								{errors.firstName}
							</span>
						)}
					</div>
					<div className="flex flex-col gap-2">
						<label htmlFor="w-lastName" className="text-white text-xl">
							Achternaam <span className="text-red-300">*</span>
						</label>
						<input
							type="text"
							id="w-lastName"
							name="lastName"
							value={data.lastName}
							onChange={handleChange}
							onBlur={handleBlur}
							placeholder="Jouw achternaam"
							autoComplete="family-name"
							aria-required="true"
							aria-invalid={touched.lastName && !!errors.lastName}
							className={inputCls(!!touched.lastName && !!errors.lastName)}
						/>
						{touched.lastName && errors.lastName && (
							<span className="text-red-300 text-sm" role="alert">
								{errors.lastName}
							</span>
						)}
					</div>
				</div>

				{/* Contact row */}
				<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
					<div className="flex flex-col gap-2">
						<label htmlFor="w-email" className="text-white text-xl">
							E-mail <span className="text-red-300">*</span>
						</label>
						<input
							type="email"
							id="w-email"
							name="email"
							value={data.email}
							onChange={isLoggedIn ? undefined : handleChange}
							onBlur={isLoggedIn ? undefined : handleBlur}
							readOnly={isLoggedIn}
							placeholder="jouw@email.be"
							autoComplete="email"
							inputMode="email"
							aria-required="true"
							aria-invalid={touched.email && !!errors.email}
							className={`${inputCls(!!touched.email && !!errors.email)}${isLoggedIn ? "cursor-not-allowed opacity-60" : ""}`}
						/>
						{touched.email && errors.email && (
							<span className="text-red-300 text-sm" role="alert">
								{errors.email}
							</span>
						)}
					</div>
					<div className="flex flex-col gap-2">
						<label htmlFor="w-phone" className="text-white text-xl">
							Telefoon
						</label>
						<input
							type="tel"
							id="w-phone"
							name="phone"
							value={data.phone}
							onChange={handleChange}
							onBlur={handleBlur}
							placeholder="06-12345678"
							autoComplete="tel"
							inputMode="tel"
							aria-invalid={touched.phone && !!errors.phone}
							className={inputCls(!!touched.phone && !!errors.phone)}
						/>
						{touched.phone && errors.phone && (
							<span className="text-red-300 text-sm" role="alert">
								{errors.phone}
							</span>
						)}
					</div>
				</div>

				{/* Postcode + Birthdate row */}
				<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
					<div className="flex flex-col gap-2">
						<label htmlFor="w-postcode" className="text-white text-xl">
							Postcode <span className="text-red-300">*</span>
						</label>
						<input
							type="text"
							id="w-postcode"
							name="postcode"
							value={data.postcode}
							onChange={handleChange}
							onBlur={handleBlur}
							placeholder="1234 AB"
							autoComplete="postal-code"
							aria-required="true"
							aria-invalid={touched.postcode && !!errors.postcode}
							className={inputCls(!!touched.postcode && !!errors.postcode)}
						/>
						{touched.postcode && errors.postcode && (
							<span className="text-red-300 text-sm" role="alert">
								{errors.postcode}
							</span>
						)}
					</div>
					<div className="flex flex-col gap-2">
						<label htmlFor="w-birthdate" className="text-white text-xl">
							Geboortedatum <span className="text-red-300">*</span>
						</label>
						<input
							type="date"
							id="w-birthdate"
							name="birthdate"
							value={data.birthdate}
							onChange={handleChange}
							onBlur={handleBlur}
							autoComplete="bday"
							aria-invalid={touched.birthdate && !!errors.birthdate}
							className={`${inputCls(!!touched.birthdate && !!errors.birthdate)} [color-scheme:dark]`}
						/>
						{touched.birthdate && errors.birthdate && (
							<span className="text-red-300 text-sm" role="alert">
								{errors.birthdate}
							</span>
						)}
					</div>
				</div>

				{/* Guests */}
				<GuestList
					guests={guests}
					errors={guestErrors}
					onChange={handleGuestChange}
					onAdd={handleAddGuest}
					onRemove={handleRemoveGuest}
				/>

				{/* Extra questions */}
				<div className="flex flex-col gap-2 border border-white/10 p-6">
					<label htmlFor="w-extraQuestions" className="text-white text-xl">
						Vragen of opmerkingen
					</label>
					<textarea
						id="w-extraQuestions"
						name="extraQuestions"
						value={data.extraQuestions}
						onChange={handleChange}
						onBlur={handleBlur}
						placeholder="Heb je nog vragen of iets dat we moeten weten?"
						rows={3}
						autoComplete="off"
						className="resize-none bg-transparent text-lg text-white transition-all placeholder:text-white/40 focus:outline-none"
					/>
				</div>

				{/* Gift selector */}
				<div className="border border-white/10 p-6">
					<h3 className="mb-4 font-['Intro',sans-serif] text-white text-xl">
						Vrijwillige Gift
					</h3>
					<GiftSelector value={giftAmount} onChange={setGiftAmount} />
				</div>

				<div className="flex flex-col items-center gap-4 pt-4">
					<button
						type="submit"
						disabled={submitMutation.isPending}
						aria-busy={submitMutation.isPending}
						className="bg-white px-12 py-4 font-['Intro',sans-serif] text-[#214e51] text-xl transition-all hover:scale-105 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-white/50 focus:ring-offset-2 focus:ring-offset-[#214e51] disabled:cursor-not-allowed disabled:opacity-50 md:text-2xl"
					>
						{submitMutation.isPending ? (
							<span className="flex items-center gap-2">
								<svg
									className="h-5 w-5 animate-spin"
									xmlns="http://www.w3.org/2000/svg"
									fill="none"
									viewBox="0 0 24 24"
									aria-label="Laden"
								>
									<circle
										className="opacity-25"
										cx="12"
										cy="12"
										r="10"
										stroke="currentColor"
										strokeWidth="4"
									/>
									<path
										className="opacity-75"
										fill="currentColor"
										d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
									/>
								</svg>
								Bezig...
							</span>
						) : (
							"Bevestigen & betalen"
						)}
					</button>
					<a
						href="/contact"
						className="text-sm text-white/60 transition-colors hover:text-white"
					>
						Nog vragen? Neem contact op
					</a>
				</div>
			</form>
		</div>
	);
}
