import { Eye, EyeOff } from "lucide-react";
import { useRouter } from "next/router";
import { useState } from "react";
import toast from "react-hot-toast";
import { z } from "zod/v4";
import {
	Form,
	FormControl,
	FormField,
	FormItem,
	FormLabel,
	FormMessage,
} from "~/components/custom_ui/form";
import Input from "~/components/custom_ui/input";
import { LoadingSpinner } from "~/components/spinner";
import { Button } from "~/components/ui/button";
import { Checkbox } from "~/components/ui/checkbox";
import { useStrongPassword } from "~/hooks/useStrongPassword";
import { cn } from "~/lib/utils";
import { useZodForm } from "~/lib/zodForm";
import { useTranslation } from "~/providers/I18nProvider";
import type { ServizioServizioId } from "~/schemas/public/Servizio";
import type { Users } from "~/schemas/public/Users";
import { api } from "~/utils/api";

type FormPwSetupProps = {
	user: Pick<Users, "id" | "nome" | "cognome" | "email" | "telefono">;
	servizioId: ServizioServizioId;
};

export const FormPwSetup = ({ user, servizioId }: FormPwSetupProps) => {
	const router = useRouter();
	const {
		isVisible,
		getStrengthColor,
		passwordRefine,
		getStrengthTxt,
		strengthScore,
		toggleVisibility,
	} = useStrongPassword();

	const Schema = z
		.object({
			password: z.string(),
			checkbox: z.boolean().refine((val) => val === false), // Honeypot field
		})
		.superRefine(({ password }, refinementContext) => {
			passwordRefine({
				password,
				refinementContext,
				path: "password",
			});
		});

	type LoginFormValues = z.infer<typeof Schema>;

	const defaultValues: LoginFormValues = {
		password: "",
		checkbox: false, // Honeypot field
	};
	const { locale, t } = useTranslation();
	z.config(z.locales[locale]());

	const form = useZodForm(Schema, {
		defaultValues: defaultValues,
	});

	const utils = api.useUtils();

	const { mutate, isPending } = api.auth.UpdatePasswordAndLogin.useMutation({
		onSuccess: async () => {
			await utils.auth.getSession.invalidate();

			setAlreadyRequested(true);
			toast.success(t.auth.login.success);
			await router.push(`/servizio/onboard/${servizioId}`);
		},
		onError: () => {
			toast.error(t.auth.login.fail);
		},
	});

	const [altreadyRequested, setAlreadyRequested] = useState(false);
	function onSubmit(fields: LoginFormValues) {
		mutate({
			id: user.id,
			password: fields.password,
		});
	}

	const texts =
		locale === "it"
			? {
					scegli_password: "Scegli la tua password",
					imposta_password: "Imposta una password per accedere al tuo account.",
					salva_password: "Salva la password e prosegui",
				}
			: {
					scegli_password: "Choose your password",
					imposta_password: "Set a password to access your account.",
					salva_password: "Save password and proceed",
				};

	return (
		<div className="mx-auto w-full max-w-3xl space-y-8 px-4 py-8">
			<div className="my-8 space-y-5">
				<h3 className="text-3xl font-bold text-gray-800 sm:text-3xl">
					{texts.scegli_password}
				</h3>
				<p className="text-muted-foreground">{texts.imposta_password}</p>
			</div>

			<Form {...form}>
				<form
					onSubmit={form.handleSubmit(onSubmit)}
					className="space-y-8 px-0.5"
				>
					<FormField
						control={form.control}
						name="password"
						render={({ field }) => (
							<FormItem>
								<div className="flex flex-col gap-x-2">
									<FormLabel htmlFor="password" className="text-neutral-600">
										{t.auth.signup.password}
									</FormLabel>

									<FormMessage
										className={cn(
											"whitespace-pre-wrap",
											getStrengthTxt(strengthScore),
										)}
									/>
								</div>

								<FormControl>
									<div className="relative">
										<Input
											{...field}
											id="password"
											className="pe-9"
											autoComplete="current-password"
											placeholder="Password"
											type={isVisible ? "text" : "password"}
											onChange={async (e) => {
												field.onChange(e);
												await form.trigger("password");
											}}
											aria-invalid={form.getFieldState("password").invalid}
											aria-describedby="password-strength"
										/>
										<button
											className="text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:text-foreground focus-visible:ring-ring/30 absolute end-0 top-1 flex size-9 items-center justify-center rounded-e-lg transition-shadow focus-visible:border focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50"
											type="button"
											onClick={toggleVisibility}
											aria-label={isVisible ? "Hide password" : "Show password"}
											aria-pressed={isVisible}
											aria-controls="password"
										>
											{isVisible ? (
												<EyeOff size={16} strokeWidth={2} aria-hidden="true" />
											) : (
												<Eye size={16} strokeWidth={2} aria-hidden="true" />
											)}
										</button>
										<div
											className="bg-border mt-3 mb-4 h-1 w-full overflow-hidden rounded-full"
											role="progressbar"
											aria-valuenow={strengthScore}
											aria-valuemin={0}
											aria-valuemax={4}
											aria-label="Password strength"
										>
											<div
												className={cn(
													"h-full transition-all duration-500 ease-out",
													getStrengthColor(strengthScore),
												)}
												style={{ width: `${(strengthScore / 4) * 100}%` }}
											/>
										</div>
									</div>
								</FormControl>
							</FormItem>
						)}
					/>
					<FormField
						control={form.control}
						name="checkbox"
						render={({ field }) => (
							<FormItem className="hidden">
								<div className="flex flex-wrap items-center gap-x-2">
									<FormLabel htmlFor="checkbox">Check Me</FormLabel>
									<FormMessage />
								</div>

								<FormControl>
									<Checkbox
										id="checkbox"
										checked={field.value}
										onCheckedChange={field.onChange}
									/>
								</FormControl>
							</FormItem>
						)}
					/>
					<Button
						disabled={isPending || altreadyRequested}
						type="submit"
						className="w-full rounded-lg bg-indigo-600 px-4 py-2 font-medium text-white duration-150 hover:bg-indigo-500 active:bg-indigo-600"
					>
						{isPending ? (
							<div className="flex items-center justify-center">
								<LoadingSpinner size={25} />
							</div>
						) : (
							<span>{texts.salva_password}</span>
						)}
					</Button>
				</form>
			</Form>
		</div>
	);
};
