import { z } from "zod/v4";
import { Counter } from "~/components/counter";
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 { Label } from "~/components/ui/label";
import { Slider } from "~/components/ui/slider";
import { Switch } from "~/components/ui/switch";
import { cn } from "~/lib/utils";
import { useZodForm } from "~/lib/zodForm";
import { useTranslation } from "~/providers/I18nProvider";
import type { Servizio } from "~/schemas/public/Servizio";
import TipologiaPosizioneEnum from "~/schemas/public/TipologiaPosizioneEnum";

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.custom<TipologiaPosizioneEnum>(),
	})
	.superRefine(({ n_adulti }, refinementContext) => {
		if (n_adulti <= 0) {
			refinementContext.issues.push({
				code: "custom",
				input: "",
				message: "Inserisci il numero di persone",
				path: ["npersone"],
			});
		}
	});

export type FormValues = z.infer<typeof Schema>;

export const FormNewServizio = ({
	initialData,
	onSubmit,
	isLimited,
}: {
	initialData: Servizio | undefined;
	onSubmit: (fields: FormValues) => void;
	isLimited: boolean;
}) => {
	// 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,
		};
	}
	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.altrePrefMapping 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.preferenze.budget_label1} - ${field.value.toLocaleString("it")},00 ${
										t.preferenze.budget_label2
									}`}
								</FormLabel>
								<FormMessage />
							</div>
							<FormControl>
								<Slider
									defaultValue={[field.value]}
									id="budgetslider"
									max={2000}
									min={0}
									onValueChange={(vals) => {
										field.onChange(Number(vals[0]));
									}}
									rangeClassName="bg-neutral-700"
									step={50}
									thumbClassName="border-neutral-700"
									value={[form.getValues("budget")]}
								/>
							</FormControl>
							<FormDescription>{t.preferenze.budget_desc}</FormDescription>
						</FormItem>
					)}
				/>
				<div className="flex w-full items-start justify-between gap-x-4">
					<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.preferenze.dalmese_label}...
									</FormLabel>
									{field.value !== null && !initialData && (
										<button
											className="text-sm"
											onClick={() => form.setValue("entromese", null)}
											type="button"
										>
											Reset
										</button>
									)}

									<FormMessage />
								</div>
								<FormControl>
									<MultiSelect
										defaultValue={
											field.value !== null
												? {
														// biome-ignore lint/style/noNonNullAssertion: <known size>
														label: t.preferenze.mesi[field.value]!,
														value: String(field.value),
													}
												: undefined
										}
										elementId="select-mesi"
										elementName="entro_mese"
										isMulti={false}
										onValueChange={(value) => {
											field.onChange(
												value.value !== "" ? parseInt(value.value) : null,
											);
										}}
										options={UnpackOptions({
											options: t.preferenze.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 htmlFor="permanenza">
										{t.preferenze.permanenza_label}
									</FormLabel>
									{field.value !== null && !initialData && (
										<button
											className="text-sm"
											onClick={() => form.setValue("permanenza", null)}
											type="button"
										>
											Reset
										</button>
									)}
									<FormMessage />
								</div>

								<FormControl>
									<MultiSelect
										defaultValue={
											field.value
												? {
														label: t.preferenze.permanenza[field.value] || "",
														value: field.value.toString(),
													}
												: undefined
										}
										disabled={tipologia !== TipologiaPosizioneEnum.Transitorio}
										elementId="permanenza"
										elementName="permanenza"
										isMulti={false}
										onValueChange={(value) => {
											field.onChange(
												value.value !== "" ? parseInt(value.value) : null,
											);
										}}
										options={UnpackOptions({
											options: t.preferenze.permanenza,
										})}
										placeholder="Seleziona..."
									/>
								</FormControl>
								<FormDescription>
									{t.preferenze.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.preferenze.nadulti_label}
									</FormLabel>
									<FormMessage />
								</div>
								<FormControl>
									<Counter
										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.preferenze.nminori_label}
									</FormLabel>
									<FormMessage />
								</div>
								<FormControl>
									<Counter
										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.preferenze.arredato_label}
								</FormLabel>
								<FormControl>
									<Switch
										checked={field.value}
										className="data-[state=checked]:bg-neutral-700"
										id="arredato"
										onCheckedChange={field.onChange}
									/>
								</FormControl>
								<FormMessage />
							</div>

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

				{tipologia === TipologiaPosizioneEnum.Transitorio ? (
					<FormField
						control={form.control}
						key={tipologia}
						name="motivazione_transitorio"
						render={({ field }) => {
							const existingValue = t.preferenze.motivazioni_mappings.find(
								(m) => m.id === field.value,
							);
							return (
								<FormItem>
									<div className="flex flex-wrap items-center gap-x-2">
										<FormLabel htmlFor="motivazione_transitorio">
											{t.preferenze.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.preferenze.motivazioni_mappings.map(
													(option) => ({
														label: option.title,
														value: option.id,
													}),
												)}
												placeholder={t.seleziona_placeholder}
											/>
											<FormDescription>
												{t.preferenze.motivazione_desc}
											</FormDescription>
										</>
									)}
								</FormItem>
							);
						}}
					/>
				) : (
					<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.preferenze.reddito_label}
									</FormLabel>
									<FormMessage />
								</div>

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

				<div className="flex flex-col space-y-2">
					<Label htmlFor="altrePrefDialogButton">
						{t.preferenze.altrepref_label}
					</Label>
					<FormDescription>{t.preferenze.altrepref_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(
															"cursor-pointer text-sm",
															field.value
																? "bg-neutral-800 hover:bg-neutral-800 sm:hover:bg-neutral-900/80"
																: "bg-neutral-200 text-neutral-700 hover:bg-neutral-200 sm:hover:bg-neutral-900/80 sm:hover:text-neutral-50",
														)}
														onClick={() => {
															field.onChange(!field.value);
														}}
													>
														{pair[1]}
													</Badge>
												</FormControl>
											</FormItem>
										)}
									/>
								);
							}
						})}
					</div>
				</div>

				<Button type="submit">Salva</Button>
			</form>
		</Form>
	);
};
