import { z } from "zod";
import {
  Form,
  FormControl,
  FormDescription,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "~/components/custom_ui/form";
import { customErrorMapWrapper } from "~/hooks/locale";
import { useZodForm } from "~/lib/zodForm";
import { Button } from "~/components/ui/button";
import { useTranslation } from "~/providers/I18nProvider";
import { cn } from "~/lib/utils";
import TipologiaPosizioneEnum from "~/schemas/public/TipologiaPosizioneEnum";
import { Slider } from "~/components/ui/slider";
import { MultiSelect, UnpackOptions } from "~/components/custom_ui/multiselect";
import { Counter } from "~/components/counter";
import { Switch } from "~/components/ui/switch";
import { Label } from "~/components/ui/label";
import { Badge } from "~/components/ui/badge";
import type { Servizio } from "~/schemas/public/Servizio";

const schema = z
  .object({
    tipologia: z.custom<TipologiaPosizioneEnum>(),
    budget: z.coerce.number(),
    entromese: z.number().nullable(),
    n_adulti: z.coerce.number().min(1),
    n_minori: z.coerce.number(),
    permanenza: z.number().nullable(),
    motivazione_transitorio: z.string().nullable(),
    reddito: z.string().nullable(),
    arredato: z.boolean(),
    animali: z.boolean(),
    fumatori: z.boolean(),
    giardino: z.boolean(),
    parcheggio: z.boolean(),
    terrazzo: z.boolean(),
    ascensore: z.boolean(),
    pianoterra: z.boolean(),
  })
  .superRefine(({ n_adulti }, refinementContext) => {
    if (n_adulti <= 0) {
      refinementContext.addIssue({
        code: z.ZodIssueCode.custom,
        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 = {
      tipologia: TipologiaPosizioneEnum.Transitorio,
      budget: 0,
      entromese: null,
      n_adulti: 1,
      n_minori: 0,
      permanenza: null,
      motivazione_transitorio: "",
      reddito: "",
      arredato: false,
      animali: false,
      fumatori: false,
      giardino: false,
      parcheggio: false,
      terrazzo: false,
      ascensore: false,
      pianoterra: false,
    };
  }
  const { locale, t } = useTranslation();

  z.setErrorMap(customErrorMapWrapper(locale));

  const form = useZodForm({
    schema: 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 onSubmit={form.handleSubmit(onSubmit)} className="space-y-8 px-0.5">
        <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="text-lg font-semibold">{field.value}</p>
                  <p className="text-muted-foreground text-sm">
                    La tipologia non può essere modificata. Contatta il supporto
                    se necessario.
                  </p>
                </div>
              ) : (
                <MultiSelect
                  elementId="select-tipologia"
                  elementName="tipologia"
                  isMulti={false}
                  placeholder={t.seleziona_placeholder}
                  defaultValue={{
                    value: TipologiaPosizioneEnum.Transitorio,
                    label: "Transitorio",
                  }}
                  options={[
                    {
                      value: TipologiaPosizioneEnum.Transitorio,
                      label: "Transitorio",
                    },
                    {
                      value: TipologiaPosizioneEnum.Stabile,
                      label: "Stabile",
                    },
                  ]}
                  onValueChange={(value) => {
                    field.onChange(value.value);
                    form.setValue("motivazione_transitorio", null);
                    form.setValue("reddito", null);
                  }}
                />
              )}
            </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
                  min={0}
                  max={2000}
                  step={50}
                  defaultValue={[field.value]}
                  onValueChange={(vals) => {
                    field.onChange(vals[0]);
                  }}
                  rangeClassName="bg-neutral-700"
                  thumbClassName="border-neutral-700"
                  value={[form.getValues("budget")]}
                  id="budgetslider"
                />
              </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
                      type="button"
                      className="text-sm"
                      onClick={() => form.setValue("entromese", null)}
                    >
                      Reset
                    </button>
                  )}

                  <FormMessage />
                </div>
                <FormControl>
                  <MultiSelect
                    elementId="select-mesi"
                    elementName="entro_mese"
                    options={UnpackOptions({
                      options: t.preferenze.mesi,
                    })}
                    defaultValue={
                      field.value !== null
                        ? {
                            value: String(field.value),
                            label: t.preferenze.mesi[field.value]!,
                          }
                        : undefined
                    }
                    onValueChange={(value) => {
                      field.onChange(
                        value.value !== "" ? parseInt(value.value) : null,
                      );
                    }}
                    placeholder="Seleziona..."
                    isMulti={false}
                  />
                </FormControl>
              </FormItem>
            )}
          />
          <FormField
            control={form.control}
            name="permanenza"
            disabled={tipologia !== TipologiaPosizioneEnum.Transitorio}
            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
                      type="button"
                      className="text-sm"
                      onClick={() => form.setValue("permanenza", null)}
                    >
                      Reset
                    </button>
                  )}
                  <FormMessage />
                </div>

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

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

        {tipologia === TipologiaPosizioneEnum.Transitorio ? (
          <FormField
            key={tipologia}
            control={form.control}
            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="text-lg font-semibold">
                        {existingValue?.title}
                      </p>
                      <p className="text-muted-foreground text-sm">
                        La motivazione non può essere modificata. Contatta il
                        supporto se necessario.
                      </p>
                    </div>
                  ) : (
                    <>
                      <MultiSelect
                        elementId="select-motivazione_transitorio"
                        elementName="motivazione_transitorio"
                        isMulti={false}
                        placeholder={t.seleziona_placeholder}
                        defaultValue={
                          existingValue
                            ? {
                                value: existingValue.id,
                                label: existingValue.title,
                              }
                            : undefined
                        }
                        options={t.preferenze.motivazioni_mappings.map(
                          (option) => ({
                            value: option.id,
                            label: option.title,
                          }),
                        )}
                        onValueChange={(value) => {
                          field.onChange(value.value);
                        }}
                      />
                      <FormDescription>
                        {t.preferenze.motivazione_desc}
                      </FormDescription>
                    </>
                  )}
                </FormItem>
              );
            }}
          />
        ) : (
          <FormField
            key={tipologia}
            control={form.control}
            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
                  elementId="select-reddito"
                  elementName="reddito"
                  isMulti={false}
                  placeholder={t.seleziona_placeholder}
                  defaultValue={undefined}
                  options={UnpackOptions({
                    options: t.preferenze.reddito_options,
                  })}
                  onValueChange={(value) => {
                    field.onChange(value.value);
                  }}
                />
              </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, index) => {
              if (pair) {
                return (
                  <FormField
                    control={form.control}
                    key={index}
                    name={pair[0]}
                    render={({ field }) => (
                      <FormItem>
                        <FormControl>
                          <Badge
                            onClick={() => {
                              field.onChange(!field.value);
                            }}
                            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",
                            )}
                          >
                            {pair[1]}
                          </Badge>
                        </FormControl>
                      </FormItem>
                    )}
                  />
                );
              }
            })}
          </div>
        </div>

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