import { useMutation } from "@tanstack/react-query";
import { useState } from "react";
import { toast } from "sonner";
import {
	inputCls,
	validateEmail,
	validatePhone,
	validateTextField,
} from "@/lib/registration";
import { orpc } from "@/utils/orpc";
import { GiftSelector } from "./GiftSelector";

interface PerformerErrors {
	firstName?: string;
	lastName?: string;
	email?: string;
	phone?: string;
	artForm?: string;
	isOver16?: string;
}

interface Props {
	onBack: () => void;
	onSuccess: (token: string, email: string, name: string) => void;
	prefillFirstName?: string;
	prefillLastName?: string;
	prefillEmail?: string;
	isLoggedIn?: boolean;
}

export function PerformerForm({
	onBack,
	onSuccess,
	prefillFirstName = "",
	prefillLastName = "",
	prefillEmail = "",
	isLoggedIn = false,
}: Props) {
	const [data, setData] = useState({
		firstName: prefillFirstName,
		lastName: prefillLastName,
		email: prefillEmail,
		phone: "",
		artForm: "",
		experience: "",
		isOver16: false,
		extraQuestions: "",
	});
	const [giftAmount, setGiftAmount] = useState(0);
	const [errors, setErrors] = useState<PerformerErrors>({});
	const [touched, setTouched] = useState<Record<string, boolean>>({});

	const submitMutation = useMutation({
		...orpc.submitRegistration.mutationOptions(),
		onSuccess: (result) => {
			if (result.managementToken)
				onSuccess(
					result.managementToken,
					data.email.trim(),
					`${data.firstName.trim()} ${data.lastName.trim()}`.trim(),
				);
		},
		onError: (error) => {
			toast.error(`Er is iets misgegaan: ${error.message}`);
		},
	});

	function validate(): boolean {
		const errs: PerformerErrors = {
			firstName: validateTextField(data.firstName, true, "Voornaam"),
			lastName: validateTextField(data.lastName, true, "Achternaam"),
			email: validateEmail(data.email),
			phone: validatePhone(data.phone),
			artForm: !data.artForm.trim() ? "Kunstvorm is verplicht" : undefined,
			isOver16: !data.isOver16
				? "Je moet 16 jaar of ouder zijn om op te treden"
				: undefined,
		};
		setErrors(errs);
		setTouched({
			firstName: true,
			lastName: true,
			email: true,
			phone: true,
			artForm: true,
			isOver16: true,
		});
		return !Object.values(errs).some(Boolean);
	}

	function handleChange(
		e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
	) {
		const { name, value, type } = e.target;
		const newValue =
			type === "checkbox" ? (e.target as HTMLInputElement).checked : value;
		setData((prev) => ({ ...prev, [name]: newValue }));

		if (type !== "checkbox" && touched[name]) {
			const fieldError: Record<string, string | undefined> = {
				firstName: validateTextField(
					name === "firstName" ? value : data.firstName,
					true,
					"Voornaam",
				),
				lastName: validateTextField(
					name === "lastName" ? value : data.lastName,
					true,
					"Achternaam",
				),
				email: validateEmail(name === "email" ? value : data.email),
				phone: validatePhone(name === "phone" ? value : data.phone),
				artForm:
					name === "artForm" && !value.trim()
						? "Kunstvorm is verplicht"
						: undefined,
			};
			setErrors((prev) => ({ ...prev, [name]: fieldError[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),
			artForm: !value.trim() ? "Kunstvorm is verplicht" : undefined,
		};
		setErrors((prev) => ({ ...prev, [name]: errMap[name] }));
	}

	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,
			registrationType: "performer",
			artForm: data.artForm.trim() || undefined,
			experience: data.experience.trim() || undefined,
			isOver16: data.isOver16,
			extraQuestions: data.extraQuestions.trim() || undefined,
			giftAmount,
		});
	}

	return (
		<div>
			{/* 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-amber-400/20 text-amber-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="M12 18.75a6 6 0 006-6v-1.5m-6 7.5a6 6 0 01-6-6v-1.5m6 7.5v3.75m-3.75 0h7.5M12 15.75a3 3 0 01-3-3V4.5a3 3 0 116 0v8.25a3 3 0 01-3 3z"
							/>
						</svg>
					</div>
					<span className="font-['Intro',sans-serif] text-amber-300">
						Ik wil optreden
					</span>
				</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="p-firstName" className="text-white text-xl">
							Voornaam <span className="text-red-300">*</span>
						</label>
						<input
							type="text"
							id="p-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="p-lastName" className="text-white text-xl">
							Achternaam <span className="text-red-300">*</span>
						</label>
						<input
							type="text"
							id="p-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="p-email" className="text-white text-xl">
							E-mail <span className="text-red-300">*</span>
						</label>
						<input
							type="email"
							id="p-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="p-phone" className="text-white text-xl">
							Telefoon
						</label>
						<input
							type="tel"
							id="p-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>

				{/* Performer-specific fields */}
				<div className="border border-amber-400/20 bg-amber-400/5 p-6">
					<p className="mb-5 text-amber-300/80 text-sm uppercase tracking-wider">
						Optreden details
					</p>
					<div className="flex flex-col gap-6">
						<div className="flex flex-col gap-2">
							<label htmlFor="p-artForm" className="text-white text-xl">
								Kunstvorm <span className="text-red-300">*</span>
							</label>
							<input
								type="text"
								id="p-artForm"
								name="artForm"
								value={data.artForm}
								onChange={handleChange}
								onBlur={handleBlur}
								placeholder="Muziek, Theater, Dans, etc."
								autoComplete="off"
								list="artFormSuggestions"
								aria-required="true"
								aria-invalid={touched.artForm && !!errors.artForm}
								className={inputCls(!!touched.artForm && !!errors.artForm)}
							/>
							<datalist id="artFormSuggestions">
								<option value="Muziek" />
								<option value="Theater" />
								<option value="Dans" />
								<option value="Beeldende Kunst" />
								<option value="Woordkunst" />
								<option value="Comedy" />
							</datalist>
							{touched.artForm && errors.artForm && (
								<span className="text-red-300 text-sm" role="alert">
									{errors.artForm}
								</span>
							)}
						</div>

						<div className="flex flex-col gap-2">
							<label htmlFor="p-experience" className="text-white text-xl">
								Ervaring
							</label>
							<input
								type="text"
								id="p-experience"
								name="experience"
								value={data.experience}
								onChange={handleChange}
								onBlur={handleBlur}
								placeholder="Beginner / Gevorderd / Professional"
								autoComplete="off"
								list="experienceSuggestions"
								className={inputCls(false)}
							/>
							<datalist id="experienceSuggestions">
								<option value="Beginner" />
								<option value="Gevorderd" />
								<option value="Professional" />
							</datalist>
						</div>

						{/* Age confirmation */}
						<div>
							<label
								htmlFor="p-isOver16"
								className="flex cursor-pointer items-start gap-4"
							>
								<div className="relative mt-0.5 flex shrink-0">
									<input
										type="checkbox"
										id="p-isOver16"
										name="isOver16"
										checked={data.isOver16}
										onChange={handleChange}
										className="peer sr-only"
									/>
									<div
										className={`h-6 w-6 border-2 bg-transparent transition-colors peer-checked:bg-amber-400 peer-focus:ring-2 peer-focus:ring-amber-400/50 peer-focus:ring-offset-2 peer-focus:ring-offset-[#214e51] ${touched.isOver16 && errors.isOver16 ? "border-red-400" : "border-white/50 peer-checked:border-amber-400"}`}
									/>
									<svg
										className="pointer-events-none absolute top-0 left-0 h-6 w-6 scale-0 text-[#214e51] transition-transform peer-checked:scale-100"
										viewBox="0 0 24 24"
										fill="none"
										stroke="currentColor"
										strokeWidth="3"
										aria-hidden="true"
									>
										<polyline points="20 6 9 17 4 12" />
									</svg>
								</div>
								<div className="flex flex-col gap-1">
									<span className="text-lg text-white">
										Ik ben 16 jaar of ouder{" "}
										<span className="text-red-300">*</span>
									</span>
									<span className="text-sm text-white/60">
										Je moet minimaal 16 jaar oud zijn om op te treden.
									</span>
								</div>
							</label>
							{touched.isOver16 && errors.isOver16 && (
								<span className="mt-2 block text-red-300 text-sm" role="alert">
									{errors.isOver16}
								</span>
							)}
						</div>
					</div>
				</div>

				{/* Extra questions */}
				<div className="flex flex-col gap-2 border border-white/10 p-6">
					<label htmlFor="p-extraQuestions" className="text-white text-xl">
						Vragen of opmerkingen
					</label>
					<textarea
						id="p-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-amber-400 px-12 py-4 font-['Intro',sans-serif] text-[#1a3d40] text-xl transition-all hover:scale-105 hover:bg-amber-300 focus:outline-none focus:ring-2 focus:ring-amber-400/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"
						)}
					</button>
					<a
						href="/contact"
						className="text-sm text-white/60 transition-colors hover:text-white"
					>
						Nog vragen? Neem contact op
					</a>
				</div>
			</form>
		</div>
	);
}
