import { format } from "date-fns";
import { it } from "date-fns/locale";
import { CalendarIcon, Check, SlidersHorizontal } from "lucide-react";
import { useState } from "react";
import toast from "react-hot-toast";
import { z } from "zod/v4";
import { Counter } from "~/components/counter";
import {
	Credenza,
	CredenzaBody,
	CredenzaContent,
	CredenzaDescription,
	CredenzaHeader,
	CredenzaTitle,
	CredenzaTrigger,
} from "~/components/custom_ui/credenza";
import {
	Form,
	FormControl,
	FormDescription,
	FormField,
	FormItem,
	FormLabel,
	FormMessage,
} from "~/components/custom_ui/form";
import { MultiSelect, UnpackOptions } from "~/components/custom_ui/multiselect";
import { Badge } from "~/components/ui/badge";
import { Button } from "~/components/ui/button";
import { Calendar } from "~/components/ui/calendar";
import {
	Dialog,
	DialogContent,
	DialogDescription,
	DialogHeader,
	DialogTitle,
	DialogTrigger,
} from "~/components/ui/dialog";
import { Label } from "~/components/ui/label";
import {
	Popover,
	PopoverContent,
	PopoverTrigger,
} from "~/components/ui/popover";
import { Slider } from "~/components/ui/slider";
import { Switch } from "~/components/ui/switch";
import { FieldResetButton } from "~/forms/comps";
import { cn } from "~/lib/utils";
import { useZodForm } from "~/lib/zodForm";
import { useTranslation } from "~/providers/I18nProvider";
import { useServizio } from "~/providers/ServizioProvider";
import type { Servizio } from "~/schemas/public/Servizio";
import TipologiaPosizioneEnum from "~/schemas/public/TipologiaPosizioneEnum";
import type { UsersId } from "~/schemas/public/Users";
import { api } from "~/utils/api";
import { DEFAULT_SERVIZIO_INTERRUZIONE_DURATION_DAYS } from "~/utils/config";

const Schema = z
	.object({
		animali: z.boolean(),
		arredato: z.boolean(),
		ascensore: z.boolean(),
		budget: z.number(),
		entromese: z.number().nullable(),
		fumatori: z.boolean(),
		giardino: z.boolean(),
		motivazione_transitorio: z.string().nullable(),
		n_adulti: z.number().min(1),
		n_minori: z.number(),
		parcheggio: z.boolean(),
		permanenza: z.number().nullable(),
		pianoterra: z.boolean(),
		reddito: z.string().nullable(),
		terrazzo: z.boolean(),
		tipologia: z.enum(TipologiaPosizioneEnum),
		scadenza_motivazione_transitoria: z.date().nullable(),
		skipPayment: z.boolean(),
		skipControlloDoc: z.boolean(),
		skipDocMotivazione: z.boolean(),
		interruzioneDays: z.number().min(0),
		acceptedInterr: z.boolean(),
	})
	.superRefine(({ n_adulti }, refinementContext) => {
		if (n_adulti <= 0) {
			refinementContext.issues.push({
				code: "custom",
				input: "",
				message: "Inserisci il numero di persone",
				path: ["npersone"],
			});
		}
	});

type FormValues = z.infer<typeof Schema>;

const FormServizio = ({
	initialData,
	onSubmit,
	isLimited,
	setOpen,
}: {
	initialData: Servizio | undefined;
	onSubmit: (fields: FormValues) => void;
	isLimited: boolean;
	setOpen?: (open: boolean) => void;
}) => {
	// This can come from your database or API.
	let defaultValues: FormValues;

	if (initialData) {
		defaultValues = {
			...initialData,
		};
	} else {
		defaultValues = {
			animali: false,
			arredato: false,
			ascensore: false,
			budget: 0,
			entromese: null,
			fumatori: false,
			giardino: false,
			motivazione_transitorio: "",
			n_adulti: 1,
			n_minori: 0,
			parcheggio: false,
			permanenza: null,
			pianoterra: false,
			reddito: "",
			terrazzo: false,
			tipologia: TipologiaPosizioneEnum.Transitorio,
			scadenza_motivazione_transitoria: null,
			skipPayment: false,
			skipControlloDoc: true,
			skipDocMotivazione: true,
			interruzioneDays: DEFAULT_SERVIZIO_INTERRUZIONE_DURATION_DAYS, // default value for interruzioneDays
			acceptedInterr: false,
		};
	}
	const { locale, t } = useTranslation();

	z.config(z.locales[locale]());

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

	type altrePrefMappingType = [
		["animali", string],
		["fumatori", string],
		["giardino", string],
		["parcheggio", string],
		["terrazzo", string],
		["ascensore", string],
		["pianoterra", string],
	];
	const altrePrefMapping = t.altriParamsMapping as altrePrefMappingType;
	const tipologia = form.watch("tipologia");
	return (
		<Form {...form}>
			<form className="space-y-8 px-0.5" onSubmit={form.handleSubmit(onSubmit)}>
				<FormField
					control={form.control}
					name="tipologia"
					render={({ field }) => (
						<FormItem>
							<div className="flex flex-wrap items-center gap-x-2">
								<FormLabel htmlFor="select-tipologia">Tipologia</FormLabel>
								<FormMessage />
							</div>

							{isLimited ? (
								<div className="space-y-0">
									<p className="font-semibold text-lg">{field.value}</p>
									<p className="text-muted-foreground text-sm">
										La tipologia non può essere modificata. Contatta il supporto
										se necessario.
									</p>
								</div>
							) : (
								<MultiSelect
									defaultValue={
										field.value === TipologiaPosizioneEnum.Transitorio
											? {
													label: "Transitorio",
													value: TipologiaPosizioneEnum.Transitorio,
												}
											: {
													label: "Stabile",
													value: TipologiaPosizioneEnum.Stabile,
												}
									}
									elementId="select-tipologia"
									elementName="tipologia"
									isMulti={false}
									onValueChange={(value) => {
										field.onChange(value.value);
										form.setValue("motivazione_transitorio", null);
										form.setValue("reddito", null);
									}}
									options={[
										{
											label: "Transitorio",
											value: TipologiaPosizioneEnum.Transitorio,
										},
										{
											label: "Stabile",
											value: TipologiaPosizioneEnum.Stabile,
										},
									]}
									placeholder={t.seleziona_placeholder}
								/>
							)}
						</FormItem>
					)}
				/>

				<FormField
					control={form.control}
					name="budget"
					render={({ field }) => (
						<FormItem>
							<div className="flex flex-wrap items-center gap-x-2 pb-1">
								<FormLabel htmlFor="budgetslider">
									{`${t.parametri.budget_label1} - ${field.value.toLocaleString("it")},00 ${
										t.parametri.budget_label2
									}`}
								</FormLabel>
								<FormMessage />
							</div>
							<FormControl>
								<Slider
									defaultValue={[field.value]}
									disabled={isLimited}
									id="budgetslider"
									max={2000}
									min={0}
									onValueChange={(vals) => {
										field.onChange(Number(vals[0]));
									}}
									step={50}
									value={[form.getValues("budget")]}
								/>
							</FormControl>
							{!isLimited && (
								<FormDescription>{t.parametri.budget_desc}</FormDescription>
							)}
						</FormItem>
					)}
				/>
				<div className="grid w-full grid-cols-1 items-start gap-4 sm:grid-cols-2">
					<FormField
						control={form.control}
						name="entromese"
						render={({ field }) => (
							<FormItem className="w-full">
								<div className="flex flex-wrap items-center gap-x-2">
									<FormLabel htmlFor="select-mesi">
										{t.parametri.dalmese_label}...
									</FormLabel>
									{field.value !== null && !initialData && (
										<FieldResetButton
											onClick={() => form.setValue("entromese", null)}
										/>
									)}

									<FormMessage />
								</div>
								<FormControl>
									<MultiSelect
										defaultValue={
											field.value !== null
												? {
														// biome-ignore lint/style/noNonNullAssertion: <known size>
														label: t.parametri.mesi[field.value]!,
														value: String(field.value),
													}
												: undefined
										}
										disabled={isLimited}
										elementId="select-mesi"
										elementName="entro_mese"
										isMulti={false}
										key={field.value}
										onValueChange={(value) => {
											field.onChange(
												value.value !== "" ? parseInt(value.value) : null,
											);
										}}
										options={UnpackOptions({
											options: t.parametri.mesi,
										})}
										placeholder="Seleziona..."
									/>
								</FormControl>
							</FormItem>
						)}
					/>
					<FormField
						control={form.control}
						disabled={tipologia !== TipologiaPosizioneEnum.Transitorio}
						name="permanenza"
						render={({ field }) => (
							<FormItem className="w-full">
								<div className="flex flex-wrap items-center gap-x-2">
									<FormLabel
										className={cn(
											tipologia !== TipologiaPosizioneEnum.Transitorio &&
												"opacity-50",
										)}
										htmlFor="permanenza"
									>
										{t.parametri.permanenza_label}
									</FormLabel>
									{field.value !== null && !initialData && (
										<FieldResetButton
											onClick={() => form.setValue("permanenza", null)}
										/>
									)}
									<FormMessage />
								</div>

								<FormControl>
									<MultiSelect
										defaultValue={
											field.value !== null
												? {
														label: t.parametri.permanenza[field.value] || "",
														value: field.value.toString(),
													}
												: undefined
										}
										disabled={
											isLimited ||
											tipologia !== TipologiaPosizioneEnum.Transitorio
										}
										elementId="permanenza"
										elementName="permanenza"
										isMulti={false}
										key={field.value}
										onValueChange={(value) => {
											field.onChange(
												value.value !== "" ? parseInt(value.value) : null,
											);
										}}
										options={UnpackOptions({
											options: t.parametri.permanenza,
										})}
										placeholder="Seleziona..."
									/>
								</FormControl>
								{tipologia === TipologiaPosizioneEnum.Transitorio &&
									!isLimited && (
										<FormDescription>
											{t.parametri.permanenza_desc}
										</FormDescription>
									)}
							</FormItem>
						)}
					/>
				</div>
				<div className="flex w-full items-center justify-between gap-x-4">
					<FormField
						control={form.control}
						name="n_adulti"
						render={({ field }) => (
							<FormItem className={cn("w-full")}>
								<div className="flex flex-wrap items-center gap-x-2">
									<FormLabel
										className={cn("font-semibold text-base")}
										htmlFor="n_adulti"
									>
										{t.parametri.nadulti_label}
									</FormLabel>
									<FormMessage />
								</div>
								<FormControl>
									<Counter
										disabled={isLimited}
										name="n_adulti"
										onlyPositive
										setValue={(value) => field.onChange(Number(value))}
										value={Number(field.value)}
									/>
								</FormControl>
							</FormItem>
						)}
					/>
					<FormField
						control={form.control}
						name="n_minori"
						render={({ field }) => (
							<FormItem className={cn("w-full")}>
								<div className="flex flex-wrap items-center gap-x-2">
									<FormLabel
										className={cn("font-semibold text-base")}
										htmlFor="n_minori"
									>
										{t.parametri.nminori_label}
									</FormLabel>
									<FormMessage />
								</div>
								<FormControl>
									<Counter
										disabled={isLimited}
										name="n_minori"
										onlyPositive
										setValue={(value) => field.onChange(Number(value))}
										value={Number(field.value)}
									/>
								</FormControl>
							</FormItem>
						)}
					/>
				</div>
				<FormField
					control={form.control}
					name="arredato"
					render={({ field }) => (
						<FormItem className="w-full">
							<div className="flex flex-wrap items-center gap-x-2">
								<FormLabel htmlFor="arredato">
									{t.parametri.arredato_label}
								</FormLabel>
								<FormControl>
									<Switch
										className="data-[state=checked]:bg-neutral-700"
										defaultChecked={field.value}
										disabled={isLimited}
										id="arredato"
										onCheckedChange={field.onChange}
									/>
								</FormControl>
								<FormMessage />
							</div>

							<FormDescription>{t.parametri.arredato_desc}</FormDescription>
						</FormItem>
					)}
				/>

				{tipologia === TipologiaPosizioneEnum.Transitorio ? (
					<div className="items-top flex w-full flex-col justify-between gap-4 sm:flex-row">
						<FormField
							control={form.control}
							key={tipologia}
							name="motivazione_transitorio"
							render={({ field }) => {
								const existingValue = t.parametri.motivazioni_mappings.find(
									(m) => m.id === field.value,
								);
								return (
									<FormItem className="w-full">
										<div className="flex w-full flex-wrap items-center gap-x-2">
											<FormLabel htmlFor="motivazione_transitorio">
												{t.parametri.motivazione_label}
											</FormLabel>
											<FormMessage />
										</div>
										{isLimited ? (
											<div className="space-y-0">
												<p className="font-semibold text-lg">
													{existingValue?.title}
												</p>
												<p className="text-muted-foreground text-sm">
													La motivazione non può essere modificata. Contatta il
													supporto se necessario.
												</p>
											</div>
										) : (
											<>
												<MultiSelect
													defaultValue={
														existingValue
															? {
																	label: existingValue.title,
																	value: existingValue.id,
																}
															: undefined
													}
													elementId="select-motivazione_transitorio"
													elementName="motivazione_transitorio"
													isMulti={false}
													onValueChange={(value) => {
														field.onChange(value.value);
													}}
													options={t.parametri.motivazioni_mappings.map(
														(option) => ({
															label: option.title,
															value: option.id,
														}),
													)}
													placeholder={t.seleziona_placeholder}
												/>
												<FormDescription>
													{t.parametri.motivazione_desc}
												</FormDescription>
											</>
										)}
									</FormItem>
								);
							}}
						/>
						<FormField
							control={form.control}
							name="scadenza_motivazione_transitoria"
							render={({ field }) => (
								<FormItem className="flex w-full flex-col">
									<div className="flex flex-wrap items-center gap-x-2">
										<FormLabel htmlFor="scadenza_motivazione_transitoria">
											Scadenza motivazione
										</FormLabel>

										<FormMessage />
									</div>
									{isLimited ? (
										<div className="space-y-0">
											<p className="font-semibold text-lg">
												{field.value
													? format(field.value, "dd/MM/yyyy")
													: "Errore data invalida"}
											</p>
											<p className="text-muted-foreground text-sm">
												La scadenza non può essere modificata. Contatta il
												supporto se necessario.
											</p>
										</div>
									) : (
										<Popover>
											<PopoverTrigger asChild>
												<FormControl>
													<Button
														className={cn(
															"h-10 w-full bg-card pl-3 text-left font-medium",
															!field.value && "text-muted-foreground",
															"rounded-lg border border-neutral-300 shadow-xs outline-hidden file:border-0 file:bg-transparent file:font-medium file:text-sm disabled:cursor-not-allowed disabled:opacity-50 dark:focus:border-transparent",
														)}
														id="scadenza_motivazione_transitoria"
														variant={"outline"}
													>
														{field.value ? (
															format(field.value, "PPP", {
																locale: it,
															})
														) : (
															<span>{t.anagrafica.scegli_data}</span>
														)}
														<CalendarIcon className="ml-auto size-4 opacity-50" />
													</Button>
												</FormControl>
											</PopoverTrigger>
											<PopoverContent align="end" className="w-auto p-0">
												<Calendar
													autoFocus
													captionLayout="dropdown"
													defaultMonth={field.value || new Date()}
													endMonth={new Date(2050, 12)}
													locale={it}
													mode="single"
													onSelect={field.onChange}
													selected={field.value || undefined}
												/>
											</PopoverContent>
										</Popover>
									)}
									<FormDescription>
										es. scadenza contratto di lavoro, fine corso di studi, ecc.
									</FormDescription>
								</FormItem>
							)}
						/>
					</div>
				) : (
					<FormField
						control={form.control}
						key={tipologia}
						name="reddito"
						render={({ field }) => (
							<FormItem>
								<div className="flex flex-wrap items-center gap-x-2">
									<FormLabel htmlFor="select-reddito">
										{t.parametri.reddito_label}
									</FormLabel>
									<FormMessage />
								</div>

								<MultiSelect
									defaultValue={undefined}
									disabled={isLimited}
									elementId="select-reddito"
									elementName="reddito"
									isMulti={false}
									onValueChange={(value) => {
										field.onChange(value.value);
									}}
									options={UnpackOptions({
										options: t.parametri.reddito_options,
									})}
									placeholder={t.seleziona_placeholder}
								/>
							</FormItem>
						)}
					/>
				)}

				<div className="flex flex-col space-y-2">
					<Label htmlFor="altrePrefDialogButton">
						{t.parametri.altriparams_label}
					</Label>
					{!isLimited && (
						<FormDescription>{t.parametri.altriparams_desc}</FormDescription>
					)}
					<div className="mt-2 flex flex-wrap gap-2">
						{altrePrefMapping.map((pair) => {
							if (pair) {
								return (
									<FormField
										control={form.control}
										key={pair[0]}
										name={pair[0]}
										render={({ field }) => (
											<FormItem>
												<FormControl>
													<Badge
														className={cn(
															"text-sm",
															isLimited ? "cursor-default" : "cursor-pointer",
														)}
														onClick={() => {
															if (isLimited) return;
															field.onChange(!field.value);
														}}
														variant={field.value ? "default" : "outline"}
													>
														{field.value && <Check />}
														{pair[1]}
													</Badge>
												</FormControl>
											</FormItem>
										)}
									/>
								);
							}
						})}
					</div>
				</div>

				{/*
				<Separator />
				 {!isLimited && (
					<div className="flex w-full flex-col items-start justify-between gap-4 sm:flex-row">
						<FormField
							control={form.control}
							name="skipPayment"
							render={({ field }) => (
								<FormItem className="w-full">
									<div className="flex flex-wrap items-center gap-x-2">
										<FormLabel htmlFor="skipPayment">Salta Pagamento</FormLabel>
										<FormControl>
											<Switch
												className="data-[state=checked]:bg-neutral-700"
												defaultChecked={field.value}
												id="skipPayment"
												onCheckedChange={field.onChange}
											/>
										</FormControl>
										<FormMessage />
									</div>
									<FormDescription>
										Salta la richiesta di pagamento al cliente (per tutti i
										pagamenti)
									</FormDescription>
								</FormItem>
							)}
						/>
						<FormField
							control={form.control}
							name="skipControlloDoc"
							render={({ field }) => (
								<FormItem className="w-full">
									<div className="flex flex-wrap items-center gap-x-2">
										<FormLabel htmlFor="skipControlloDoc">
											Salta controllo documento
										</FormLabel>
										<FormControl>
											<Switch
												className="data-[state=checked]:bg-neutral-700"
												defaultChecked={field.value}
												id="skipControlloDoc"
												onCheckedChange={field.onChange}
											/>
										</FormControl>
										<FormMessage />
									</div>
									<FormDescription>
										Salta la richiesta del documento del cliente al momento
										dello sblocco contatti
									</FormDescription>
								</FormItem>
							)}
						/>
						<FormField
							control={form.control}
							name="skipDocMotivazione"
							render={({ field }) => (
								<FormItem className="w-full">
									<div className="flex flex-wrap items-center gap-x-2">
										<FormLabel htmlFor="skipDocMotivazione">
											Salta documento motivazione
										</FormLabel>
										<FormControl>
											<Switch
												className="data-[state=checked]:bg-neutral-700"
												defaultChecked={field.value}
												id="skipDocMotivazione"
												onCheckedChange={field.onChange}
											/>
										</FormControl>
										<FormMessage />
									</div>

									<FormDescription>
										Salta l&apos;invio del documento di motivazione al cliente
										al momento della conferma annuncio
									</FormDescription>
								</FormItem>
							)}
						/>
					</div>
				)} */}
				<div className="flex w-full justify-end gap-2">
					{!isLimited && (
						<Button type="submit" variant="success">
							Salva
						</Button>
					)}

					<Button
						disabled={isLimited || form.formState.isDirty}
						onClick={() => setOpen?.(false)}
						type="button"
						variant="outline"
					>
						Chiudi
					</Button>
				</div>
			</form>
		</Form>
	);
};
export const NewServizioModal = ({ userId }: { userId: UsersId }) => {
	const [open, setOpen] = useState(false);
	const utils = api.useUtils();

	const { mutate: add } = api.servizio.addServizio.useMutation({
		onError: (error) => {
			toast.error(error.message);
		},
		onSuccess: async () => {
			toast.success("Servizio creato con successo");
			await utils.servizio.invalidate();

			setOpen(false);
		},
	});

	function onSubmit(fields: FormValues) {
		add({ data: { ...fields, user_id: userId } });
	}
	return (
		<Dialog onOpenChange={setOpen} open={open}>
			<DialogTrigger asChild>
				<Button
					onClick={() => {
						setOpen(true);
					}}
					variant="outline"
				>
					Nuovo Servizio
				</Button>
			</DialogTrigger>
			<DialogContent className="max-h-[80%] w-full overflow-auto p-4 sm:max-w-5xl">
				<DialogHeader>
					<DialogTitle>Creazione Servizio</DialogTitle>
					<DialogDescription className="sr-only">desc</DialogDescription>
				</DialogHeader>
				<div className="overflow-y-auto">
					<FormServizio
						initialData={undefined}
						isLimited={false}
						onSubmit={onSubmit}
					/>
				</div>
			</DialogContent>
		</Dialog>
	);
};

export const EditServizioModal = () => {
	const { servizioId, isAdmin, servizio } = useServizio();
	const { t } = useTranslation();
	const [openEditParametri, setOpenEditParametri] = useState(false);

	const utils = api.useUtils();

	const { mutate: update } = api.servizio.updateServizio.useMutation({
		onError: (error) => {
			toast.error(error.message);
		},
		onSuccess: async () => {
			toast.success("Servizio modificato con successo");
			await utils.servizio.invalidate();

			setOpenEditParametri(false);
		},
	});

	function onSubmit(fields: FormValues) {
		update({
			data: {
				...fields,
			},
			servizioId,
		});
	}

	return (
		<Credenza onOpenChange={setOpenEditParametri} open={openEditParametri}>
			<CredenzaTrigger asChild>
				<Button
					aria-label="Parametri di ricerca"
					className="w-full"
					disabled={
						!isAdmin &&
						(servizio.isInterrotto ||
							servizio.annunci.some((a) => a.status_conferma !== null))
					}
					variant="secondary"
				>
					<SlidersHorizontal />
					{t.servizio.parametri.btn}
				</Button>
			</CredenzaTrigger>
			<CredenzaContent
				className="max-h-[90vh] w-full **:data-[slot=dialog-close]:hidden sm:max-w-5xl"
				onInteractOutside={(e) => {
					e.preventDefault();
				}}
			>
				<CredenzaHeader>
					<CredenzaTitle>{t.servizio.parametri.title}</CredenzaTitle>
					<CredenzaDescription className="sr-only">
						{t.servizio.parametri.title}
					</CredenzaDescription>
				</CredenzaHeader>
				<CredenzaBody className="w-full max-w-3xl overflow-y-auto pb-5 sm:max-w-5xl">
					<FormServizio
						initialData={servizio}
						isLimited={!isAdmin}
						onSubmit={onSubmit}
						setOpen={setOpenEditParametri}
					/>
				</CredenzaBody>
			</CredenzaContent>
		</Credenza>
	);
};
