import { z } from "zod";
import { useZodForm } from "~/lib/zodForm";
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "~/components/custom_ui/form";
import Input from "~/components/custom_ui/input";
import { Button } from "~/components/ui/button";
import toast from "react-hot-toast";
import { customErrorMapWrapper } from "~/hooks/locale";
import { api } from "~/utils/api";
import { useTranslation } from "~/providers/I18nProvider";
import { differenceInYears, format } from "date-fns";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "~/components/ui/popover";
import { cn } from "~/lib/utils";
import { CalendarIcon } from "lucide-react";
import { Calendar } from "~/components/ui/calendar";
import {
  MultiSelect,
  RepackValues,
  UnpackOptions,
} from "~/components/custom_ui/multiselect";
import { it, enUS } from "date-fns/locale";
import { Separator } from "~/components/ui/separator";
import { GetNazioni } from "~/i18n/nazioni";
import { provincie } from "~/i18n/provincie";
import { checkFiscalCodeValidity, getComuneFieldValue } from "~/lib/form_utils";
import { getComuniNames } from "~/i18n/comuni";
import type { UserWithAnagrafica } from "~/server/services/user.service";
import { Switch } from "~/components/ui/switch";

export const ProfileFormAnagrafica = ({
  userData,
}: {
  userData: UserWithAnagrafica;
}) => {
  const profileFormSchema = z
    .object({
      data_nascita: z.coerce.date().optional(),
      luogo_nascita: z.string().optional(),
      sesso: z.string().optional(),
      nazione_nascita: z.string().optional(),
      codice_fiscale: z.string().optional(),
      via_residenza: z.string().optional(),
      civico_residenza: z.string().optional(),
      cap_residenza: z.string().optional(),
      comune_residenza: z.string().optional(),
      provincia_residenza: z.string().optional(),
      nazione_residenza: z.string().optional(),
      azienda: z.boolean(),
      fatturazione_aziendale: z.boolean(),
      codice_destinatario: z.string().length(7).nullable(),
      ragione_sociale: z.string().nullable(),
      sede_legale: z.string().nullable(),
      legale_rappresentante: z.string().nullable(),
      p_iva: z.string().nullable(),
    })
    .superRefine(
      (
        {
          data_nascita,
          codice_fiscale,
          sesso,
          luogo_nascita,
          nazione_nascita,
          cap_residenza,
          azienda,
          p_iva,
          ragione_sociale,
          sede_legale,
          legale_rappresentante,
          fatturazione_aziendale,
          codice_destinatario,
        },
        refinementContext,
      ) => {
        if (azienda) {
          if (!ragione_sociale || ragione_sociale.length < 1) {
            refinementContext.addIssue({
              code: z.ZodIssueCode.custom,
              message: "Inserisci la ragione sociale",
              path: ["ragione_sociale"],
            });
          }
          if (!sede_legale || sede_legale.length < 1) {
            refinementContext.addIssue({
              code: z.ZodIssueCode.custom,
              message: "Inserisci la sede legale",
              path: ["sede_legale"],
            });
          }
          if (!p_iva || p_iva.length < 1) {
            refinementContext.addIssue({
              code: z.ZodIssueCode.custom,
              message: "Inserisci la partita iva",
              path: ["p_iva"],
            });
          }
          if (!legale_rappresentante || legale_rappresentante.length < 1) {
            refinementContext.addIssue({
              code: z.ZodIssueCode.custom,
              message: "Inserisci il legale rappresentante",
              path: ["legale_rappresentante"],
            });
          }
        }
        if (fatturazione_aziendale) {
          if (!codice_destinatario || codice_destinatario.length != 7) {
            refinementContext.addIssue({
              code: z.ZodIssueCode.custom,
              message: "Inserisci il codice destinatario",
              path: ["codice_destinatario"],
            });
          }
        }

        if (cap_residenza) {
          if (cap_residenza.length !== 5) {
            refinementContext.addIssue({
              code: z.ZodIssueCode.custom,
              message: "Inserisci un CAP valido",
            });
          }
        }

        if (data_nascita) {
          const diff = differenceInYears(data_nascita, new Date());
          if (diff === 0) {
            refinementContext.addIssue({
              code: z.ZodIssueCode.custom,
              message: "Inserisci una data valida",
              path: ["data_nascita"],
            });
          }
        }
        if (
          codice_fiscale &&
          data_nascita &&
          sesso &&
          luogo_nascita &&
          nazione_nascita
        ) {
          {
            checkFiscalCodeValidity({
              path: "codice_fiscale",
              codiceFiscale: codice_fiscale,
              cognome: userData.cognome?.toUpperCase() || "",
              nome: userData.nome?.toUpperCase() || "",
              dataNascita: data_nascita,
              sesso,
              refinementContext,
              luogoNascita: luogo_nascita,
              nazioneNascita: nazione_nascita,
            });
          }
        }
      },
    );

  type ProfileFormValues = z.infer<typeof profileFormSchema>;

  const defaultValues: ProfileFormValues = {
    data_nascita: userData.data_nascita || new Date(),
    luogo_nascita: userData.luogo_nascita || "",
    nazione_nascita: userData.nazione_nascita || "",
    codice_fiscale: userData.codice_fiscale || "",
    via_residenza: userData.via_residenza || "",
    civico_residenza: userData.civico_residenza || "",
    cap_residenza: userData.cap_residenza || "",
    comune_residenza: userData.comune_residenza || "",
    provincia_residenza: userData.provincia_residenza || "",
    nazione_residenza: userData.nazione_residenza || "",
    sesso: userData.sesso || "",
    azienda: userData.azienda || false,
    ragione_sociale: userData.ragione_sociale || null,
    sede_legale: userData.sede_legale || null,
    legale_rappresentante: userData.legale_rappresentante || null,
    p_iva: userData.p_iva || null,
    fatturazione_aziendale: userData.fatturazione_aziendale || false,
    codice_destinatario: userData.codice_destinatario || null,
  };
  const { locale, t } = useTranslation();
  z.setErrorMap(customErrorMapWrapper(locale));

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

  const utils = api.useUtils();

  const { mutate } = api.users.editUserAnagrafica.useMutation({
    onSuccess: async () => {
      toast.success(t.profile.aggiornato);
      await utils.auth.getSession.invalidate();
      await utils.users.getUser.invalidate();
      await utils.users.getClientProfilo.invalidate();
    },
    onError: (error) => {
      toast.error(error.message);
    },
  });

  function onSubmit(fields: ProfileFormValues) {
    mutate({
      ...fields,
      userid: userData.id,
      idanagrafica: userData.idanagrafica || undefined,
    });
  }
  const nazioni_options = GetNazioni();
  const comuni_options = getComuniNames();
  const azienda = form.watch("azienda");
  const nazione_nascita = form.watch("nazione_nascita");
  const nazione_residenza = form.watch("nazione_residenza");
  const fatturazione_aziendale = form.watch("fatturazione_aziendale");
  const DatePickerLocale = locale === "it" ? it : enUS;
  return (
    <>
      <Form {...form}>
        <form
          onSubmit={form.handleSubmit(onSubmit)}
          className="h-full space-y-8 px-0.5"
        >
          <div className="flex w-full flex-col items-start justify-between gap-4 sm:flex-row">
            <FormField
              control={form.control}
              name="data_nascita"
              render={({ field }) => (
                <FormItem className="flex w-full flex-col">
                  <div className="flex flex-wrap items-center gap-x-2">
                    <FormLabel htmlFor="data_nascita">
                      {t.anagrafica.dataNascita}
                    </FormLabel>
                    <FormMessage />
                  </div>
                  <Popover>
                    <PopoverTrigger asChild>
                      <FormControl>
                        <Button
                          variant={"outline"}
                          id="data_nascita"
                          className={cn(
                            "h-[42px] w-full pl-3 text-left font-medium",
                            !field.value && "text-muted-foreground",
                            `text-primary dark:bg-primary rounded-lg border border-neutral-300 bg-white shadow-xs outline-hidden file:border-0 file:bg-transparent file:text-sm file:font-medium hover:border-neutral-400 focus:border-neutral-400 disabled:cursor-not-allowed disabled:opacity-50 aria-expanded:border-neutral-400 dark:border-neutral-500 dark:text-white dark:placeholder:text-neutral-400 dark:hover:border-neutral-400 dark:focus:border-transparent dark:aria-expanded:border-neutral-400`,
                          )}
                        >
                          {field.value ? (
                            format(field.value, "PPP", {
                              locale: DatePickerLocale,
                            })
                          ) : (
                            <span>{t.anagrafica.scegli_data}</span>
                          )}
                          <CalendarIcon className="ml-auto size-4 opacity-50" />
                        </Button>
                      </FormControl>
                    </PopoverTrigger>
                    <PopoverContent className="w-auto p-0" align="start">
                      <Calendar
                        locale={DatePickerLocale}
                        endMonth={new Date()}
                        mode="single"
                        defaultMonth={field.value}
                        captionLayout="dropdown"
                        selected={field.value}
                        onSelect={field.onChange}
                        disabled={(date) =>
                          date > new Date() || date < new Date("1900-01-01")
                        }
                        // eslint-disable-next-line jsx-a11y/no-autofocus
                        autoFocus
                      />
                    </PopoverContent>
                  </Popover>
                </FormItem>
              )}
            />

            <FormField
              control={form.control}
              name="nazione_nascita"
              render={({ field }) => (
                <FormItem className="w-full">
                  <div className="flex flex-wrap items-center gap-x-2">
                    <FormLabel htmlFor="select-naz">
                      {t.anagrafica.nazioneNascita}
                    </FormLabel>
                    <FormMessage />
                  </div>

                  <FormControl>
                    <MultiSelect
                      elementId="select-naz"
                      elementName="nazione_nascita"
                      options={UnpackOptions({ options: nazioni_options })}
                      defaultValue={
                        field.value
                          ? RepackValues({
                              options: nazioni_options,
                              values: field.value,
                            })
                          : undefined
                      }
                      onValueChange={async (value) => {
                        field.onChange(value.value);
                        await form.trigger("luogo_nascita");
                      }}
                      placeholder="Seleziona..."
                      isMulti={false}
                    />
                  </FormControl>
                </FormItem>
              )}
            />

            <FormField
              control={form.control}
              name="luogo_nascita"
              render={({ field }) => {
                if (nazione_nascita === "0") {
                  return (
                    <FormItem className="w-full">
                      <div className="flex flex-wrap items-center gap-x-2">
                        <FormLabel htmlFor="select-comune">
                          {t.anagrafica.luogoNascita}
                        </FormLabel>
                        <FormMessage />
                      </div>

                      <FormControl>
                        <MultiSelect
                          elementId="select-comune"
                          elementName="luogo_nascita"
                          options={UnpackOptions({ options: comuni_options })}
                          defaultValue={
                            field.value
                              ? getComuneFieldValue(field.value, comuni_options)
                              : undefined
                          }
                          onValueChange={async (value) => {
                            field.onChange(value.value);
                            await form.trigger("luogo_nascita");
                            await form.trigger("codice_fiscale");
                          }}
                          placeholder="Seleziona..."
                          isMulti={false}
                        />
                      </FormControl>
                    </FormItem>
                  );
                }
                return (
                  <FormItem className="w-full">
                    <div className="flex flex-wrap items-center gap-x-2">
                      <FormLabel htmlFor="luogoNascita">
                        {t.anagrafica.luogoNascita}
                      </FormLabel>
                      <FormMessage />
                    </div>
                    <FormControl>
                      <Input
                        {...field}
                        type="text"
                        id="luogoNascita"
                        onChange={async (v) => {
                          field.onChange(v.target.value);
                          await form.trigger("luogo_nascita");
                          await form.trigger("codice_fiscale");
                        }}
                      />
                    </FormControl>
                  </FormItem>
                );
              }}
            />
          </div>
          <div className="flex w-full flex-col items-start justify-between gap-4 sm:flex-row">
            <FormField
              control={form.control}
              name="sesso"
              render={({ field }) => (
                <FormItem className="w-full">
                  <div className="flex flex-wrap items-center gap-x-2">
                    <FormLabel htmlFor="select-sesso">
                      {t.anagrafica.sesso}
                    </FormLabel>
                    <FormMessage />
                  </div>
                  <MultiSelect
                    elementId="select-sesso"
                    elementName="sesso"
                    isMulti={false}
                    placeholder=""
                    defaultValue={t.anagrafica.sesso_options.filter(
                      (v) => v.value == field.value,
                    )}
                    options={t.anagrafica.sesso_options}
                    onValueChange={(value) => {
                      field.onChange(value.value);
                    }}
                  />
                </FormItem>
              )}
            />

            <FormField
              control={form.control}
              name="codice_fiscale"
              render={({ field }) => (
                <FormItem className="w-full">
                  <div className="flex flex-wrap items-center gap-x-2">
                    <FormLabel htmlFor="codice_fiscale">
                      {t.anagrafica.codiceFiscale}
                    </FormLabel>
                    <FormMessage />
                  </div>
                  <FormControl>
                    <Input
                      {...field}
                      onChange={async (v) => {
                        field.onChange(v.target.value.toUpperCase());
                        await form.trigger("codice_fiscale");
                      }}
                      type="text"
                      className="uppercase"
                      id="codice_fiscale"
                    />
                  </FormControl>
                </FormItem>
              )}
            />
            <FormField
              control={form.control}
              name="azienda"
              render={({ field }) => (
                <FormItem className="mt-6 w-full">
                  <div className="flex items-center justify-center gap-x-4">
                    <FormLabel htmlFor="azienda">Azienda?</FormLabel>
                    <FormControl>
                      <Switch
                        checked={field.value}
                        onCheckedChange={(v) => {
                          field.onChange(v);
                          if (!v) {
                            form.setValue("ragione_sociale", null);
                            form.setValue("sede_legale", null);
                            form.setValue("p_iva", null);
                          }
                        }}
                        id="azienda"
                        className="data-[state=checked]:bg-neutral-700"
                      />
                    </FormControl>
                    <FormMessage />
                  </div>
                </FormItem>
              )}
            />
          </div>
          {azienda && (
            <>
              <div className="flex w-full flex-col items-start justify-between gap-4 sm:flex-row">
                <FormField
                  control={form.control}
                  name="ragione_sociale"
                  render={({ field }) => (
                    <FormItem className="w-full">
                      <div className="flex flex-wrap items-center gap-x-2">
                        <FormLabel htmlFor="ragione_sociale">
                          {t.anagrafica.ragioneSociale}
                        </FormLabel>
                        <FormMessage />
                      </div>
                      <FormControl>
                        <Input
                          {...field}
                          type="text"
                          id="ragione_sociale"
                          value={field.value || undefined}
                        />
                      </FormControl>
                    </FormItem>
                  )}
                />
                <FormField
                  control={form.control}
                  name="sede_legale"
                  render={({ field }) => (
                    <FormItem className="w-full">
                      <div className="flex flex-wrap items-center gap-x-2">
                        <FormLabel htmlFor="sede_legale">
                          {t.anagrafica.sedeLegale}
                        </FormLabel>
                        <FormMessage />
                      </div>
                      <FormControl>
                        <Input
                          {...field}
                          type="text"
                          id="sede_legale"
                          value={field.value || undefined}
                        />
                      </FormControl>
                    </FormItem>
                  )}
                />
              </div>
              <div className="flex w-full flex-col items-start justify-between gap-4 sm:flex-row">
                <FormField
                  control={form.control}
                  name="p_iva"
                  render={({ field }) => (
                    <FormItem className="w-full">
                      <div className="flex flex-wrap items-center gap-x-2">
                        <FormLabel htmlFor="p_iva">
                          {t.anagrafica.p_iva}
                        </FormLabel>
                        <FormMessage />
                      </div>
                      <FormControl>
                        <Input
                          {...field}
                          type="text"
                          id="p_iva"
                          value={field.value || undefined}
                        />
                      </FormControl>
                    </FormItem>
                  )}
                />
                <FormField
                  control={form.control}
                  name="legale_rappresentante"
                  render={({ field }) => (
                    <FormItem className="w-full">
                      <div className="flex flex-wrap items-center gap-x-2">
                        <FormLabel htmlFor="legale_rappresentante">
                          {t.anagrafica.legale_rappresentante}
                        </FormLabel>
                        <FormMessage />
                      </div>
                      <FormControl>
                        <Input
                          {...field}
                          type="text"
                          id="legale_rappresentante"
                          value={field.value || undefined}
                        />
                      </FormControl>
                    </FormItem>
                  )}
                />
              </div>
              <FormField
                control={form.control}
                name="fatturazione_aziendale"
                render={({ field }) => (
                  <FormItem className="py-2">
                    <div className="flex items-center justify-start gap-x-4">
                      <FormLabel htmlFor="fatturazione_aziendale">
                        Vuoi che la fatturazione sia intestata alla tua azienda?
                      </FormLabel>
                      <FormControl>
                        <Switch
                          checked={field.value}
                          onCheckedChange={(v) => {
                            field.onChange(v);
                            if (!v) {
                              form.setValue("codice_destinatario", null);
                            }
                          }}
                          id="fatturazione_aziendale"
                          className="data-[state=checked]:bg-neutral-700"
                        />
                      </FormControl>
                      <FormMessage />
                    </div>
                  </FormItem>
                )}
              />
              {fatturazione_aziendale && (
                <FormField
                  control={form.control}
                  name="codice_destinatario"
                  render={({ field }) => (
                    <FormItem className="w-full">
                      <div className="flex flex-wrap items-center gap-x-2">
                        <FormLabel htmlFor="codice_destinatario">
                          Codice destinatario (SDI)
                        </FormLabel>
                        <FormMessage />
                      </div>

                      <FormControl>
                        <Input
                          {...field}
                          type="text"
                          id="codice_destinatario"
                          value={field.value || undefined}
                        />
                      </FormControl>
                    </FormItem>
                  )}
                />
              )}
            </>
          )}
          <Separator />
          <div className="flex w-full flex-col items-start justify-between gap-4 sm:flex-row">
            <FormField
              control={form.control}
              name="nazione_residenza"
              render={({ field }) => (
                <FormItem className="w-full">
                  <div className="flex flex-wrap items-center gap-x-2">
                    <FormLabel htmlFor="nazione_residenza">
                      {t.recapiti.nazione}
                    </FormLabel>
                    <FormMessage />
                  </div>
                  <MultiSelect
                    elementId="nazione_residenza"
                    options={UnpackOptions({ options: nazioni_options })}
                    onValueChange={async (value) => {
                      form.setValue("provincia_residenza", "");
                      field.onChange(value.value);
                      await form.trigger("comune_residenza");
                    }}
                    defaultValue={
                      field.value
                        ? RepackValues({
                            options: nazioni_options,
                            values: field.value,
                          })
                        : undefined
                    }
                    elementName="nazione"
                    isMulti={false}
                    placeholder="Seleziona"
                  />
                </FormItem>
              )}
            />

            <FormField
              control={form.control}
              name="provincia_residenza"
              render={({ field }) => (
                <FormItem className="w-full">
                  <div className="flex flex-wrap items-center gap-x-2">
                    <FormLabel htmlFor="provincia_residenza">
                      {t.recapiti.provincia}
                    </FormLabel>
                    <FormMessage />
                  </div>

                  {nazione_residenza === "0" ? (
                    <MultiSelect
                      elementId="provincia_residenza"
                      options={UnpackOptions({ options: provincie })}
                      onValueChange={(value) => {
                        field.onChange(value.value);
                      }}
                      defaultValue={
                        field.value
                          ? RepackValues({
                              options: provincie,
                              values: field.value,
                            })
                          : undefined
                      }
                      elementName="provincia"
                      isMulti={false}
                      placeholder="Seleziona"
                    />
                  ) : (
                    <FormControl>
                      <Input {...field} type="text" id="provincia_residenza" />
                    </FormControl>
                  )}
                </FormItem>
              )}
            />
          </div>
          <div className="flex w-full flex-col items-start justify-between gap-4 sm:flex-row">
            <FormField
              control={form.control}
              name="comune_residenza"
              render={({ field }) => {
                if (nazione_residenza === "0") {
                  return (
                    <FormItem className="w-full">
                      <div className="flex flex-wrap items-center gap-x-2">
                        <FormLabel htmlFor="select-comune">
                          {t.recapiti.comune}
                        </FormLabel>
                        <FormMessage />
                      </div>

                      <FormControl>
                        <MultiSelect
                          elementId="select-comune"
                          elementName="comune_residenza"
                          options={UnpackOptions({ options: comuni_options })}
                          defaultValue={
                            field.value
                              ? getComuneFieldValue(field.value, comuni_options)
                              : undefined
                          }
                          onValueChange={async (value) => {
                            field.onChange(value.value);
                            await form.trigger("comune_residenza");
                          }}
                          placeholder="Seleziona..."
                          isMulti={false}
                        />
                      </FormControl>
                    </FormItem>
                  );
                }
                return (
                  <FormItem className="w-full">
                    <div className="flex w-full flex-wrap items-center gap-x-2">
                      <FormLabel htmlFor="comune_residenza">
                        {t.recapiti.comune}
                      </FormLabel>
                      <FormMessage />
                    </div>
                    <FormControl>
                      <Input
                        {...field}
                        type="text"
                        id="comune_residenza"
                        className="w-full"
                        onChange={async (v) => {
                          field.onChange(v.target.value);
                          await form.trigger("comune_residenza");
                        }}
                      />
                    </FormControl>
                  </FormItem>
                );
              }}
            />
            <FormField
              control={form.control}
              name="cap_residenza"
              render={({ field }) => (
                <FormItem className="w-full">
                  <div className="flex flex-wrap items-center gap-x-2">
                    <FormLabel htmlFor="cap_residenza">
                      {t.recapiti.cap}
                    </FormLabel>

                    <FormMessage />
                  </div>
                  <FormControl>
                    <Input
                      {...field}
                      type="text"
                      id="cap_residenza"
                      placeholder="00100"
                    />
                  </FormControl>
                </FormItem>
              )}
            />
          </div>
          <div className="flex w-full flex-col items-start justify-between gap-4 sm:flex-row">
            <FormField
              control={form.control}
              name="via_residenza"
              render={({ field }) => (
                <FormItem className="w-full">
                  <div className="flex flex-wrap items-center gap-x-2">
                    <FormLabel htmlFor="via_residenza">
                      {t.recapiti.indirizzo}
                    </FormLabel>
                    <FormMessage />
                  </div>
                  <FormControl>
                    <Input
                      {...field}
                      type="text"
                      id="via_residenza"
                      placeholder="Via Roma"
                    />
                  </FormControl>
                </FormItem>
              )}
            />

            <FormField
              control={form.control}
              name="civico_residenza"
              render={({ field }) => (
                <FormItem className="w-full">
                  <div className="flex flex-wrap items-center gap-x-2">
                    <FormLabel htmlFor="civico_residenza">
                      {t.recapiti.civico}
                    </FormLabel>

                    <FormMessage />
                  </div>
                  <FormControl>
                    <Input
                      {...field}
                      type="text"
                      id="civico_residenza"
                      placeholder="50"
                    />
                  </FormControl>
                </FormItem>
              )}
            />
          </div>

          <Button type="submit">{t.profile.aggiorna}</Button>
        </form>
      </Form>
    </>
  );
};
