import { zodResolver } from "@hookform/resolvers/zod";
import { toast } from "@xtablo/shared";
import { Button } from "@xtablo/ui/components/button";
import { ButtonGroup } from "@xtablo/ui/components/button-group";
import { DatePickerV1 } from "@xtablo/ui/components/date-picker";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@xtablo/ui/components/dialog";
import { Label } from "@xtablo/ui/components/label";
import { TimeInput } from "@xtablo/ui/components/time-input";
import { PlusIcon } from "lucide-react";
import { Controller, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import * as z from "zod";
import { Exception } from "../hooks/availabilities";

const formSchema = z.object({
  exceptionType: z.enum(["day", "hours"]),
  exceptionDate: z.date(),
  exceptionHours: z.array(
    z.object({
      start: z.string(),
      end: z.string(),
    })
  ),
});

export const ExceptionModal = ({
  isOpen,
  onClose,
  onSubmit,
}: {
  isOpen: boolean;
  onClose: () => void;
  onSubmit: (newException: Exception) => void;
}) => {
  const { t } = useTranslation("components");
  const form = useForm<z.infer<typeof formSchema>>({
    // biome-ignore lint/suspicious/noExplicitAny: zodResolver typing is incompatible with current zod type in this package.
    resolver: zodResolver(formSchema as any),
    defaultValues: {
      exceptionType: "day",
      exceptionDate: new Date(),
      exceptionHours: [{ start: "09:00", end: "17:00" }],
    },
  });

  const onSubmitForm = (data: z.infer<typeof formSchema>) => {
    onClose();
    onSubmit({
      date: data.exceptionDate.toISOString(),
      type: data.exceptionType,
      hours: data.exceptionHours,
    });
    toast.add({
      title: t("exceptionModal.toast.success.title"),
      description: t("exceptionModal.toast.success.description"),
      type: "success",
    });
  };

  return (
    <form id="exception-form" onSubmit={form.handleSubmit(onSubmitForm)}>
      <Dialog open={isOpen} onOpenChange={onClose}>
        <DialogContent className="max-w-2xl max-h-[90vh] overflow-y-auto">
          <DialogHeader>
            <DialogTitle>{t("exceptionModal.title")}</DialogTitle>
            <DialogDescription>{t("exceptionModal.description")}</DialogDescription>
          </DialogHeader>

          <div className="space-y-2">
            <Label htmlFor="exception-type">{t("exceptionModal.labels.exceptionType")}</Label>
            <Controller
              name="exceptionType"
              control={form.control}
              render={({ field }) => (
                <ButtonGroup
                  id="exception-type"
                  orientation="horizontal"
                  className="w-full max-w-md"
                >
                  <Button
                    variant={field.value === "day" ? "default" : "outline"}
                    onClick={() => field.onChange("day")}
                    type="button"
                    className="flex-1"
                  >
                    {t("exceptionModal.types.allDay")}
                  </Button>
                  <Button
                    variant={field.value === "hours" ? "default" : "outline"}
                    onClick={() => field.onChange("hours")}
                    type="button"
                    className="flex-1"
                  >
                    {t("exceptionModal.types.customHours")}
                  </Button>
                </ButtonGroup>
              )}
            />
          </div>

          <div className="space-y-4">
            <div className="space-y-2">
              <Controller
                name="exceptionDate"
                control={form.control}
                render={({ field }) => (
                  <DatePickerV1
                    label={t("exceptionModal.labels.exceptionDate")}
                    value={field.value || undefined}
                    onChange={(date) => field.onChange(date || new Date())}
                  />
                )}
              />
            </div>

            <Controller
              name="exceptionType"
              control={form.control}
              render={({ field: typeField }) =>
                typeField.value === "hours" ? (
                  <Controller
                    name="exceptionHours"
                    control={form.control}
                    render={({ field: hoursField }) => (
                      <div className="space-y-2">
                        <div className="space-y-2">
                          {hoursField.value.map((timeRange, index) => (
                            <div key={index} className="flex items-end gap-2 w-full">
                              <div className="w-full max-w-xs space-y-2">
                                <Label htmlFor={`exception-start-${index}`}>
                                  {t("exceptionModal.labels.startTime")}
                                </Label>
                                <TimeInput
                                  value={timeRange.start}
                                  onChange={(value) => {
                                    const updatedRanges = [...hoursField.value];
                                    updatedRanges[index] = {
                                      ...updatedRanges[index],
                                      start: value,
                                    };
                                    hoursField.onChange(updatedRanges);
                                  }}
                                  id={`exception-start-${index}`}
                                />
                              </div>

                              <div className="w-full max-w-xs space-y-2">
                                <Label htmlFor={`exception-end-${index}`}>
                                  {t("exceptionModal.labels.endTime")}
                                </Label>
                                <TimeInput
                                  value={timeRange.end}
                                  onChange={(value) => {
                                    const updatedRanges = [...hoursField.value];
                                    updatedRanges[index] = {
                                      ...updatedRanges[index],
                                      end: value,
                                    };
                                    hoursField.onChange(updatedRanges);
                                  }}
                                  id={`exception-end-${index}`}
                                />
                              </div>
                              {hoursField.value.length > 1 && (
                                <Button
                                  variant="outline"
                                  size="sm"
                                  type="button"
                                  onClick={() => {
                                    const updatedRanges = hoursField.value.filter(
                                      (_, i) => i !== index
                                    );
                                    hoursField.onChange(
                                      updatedRanges.length > 0
                                        ? updatedRanges
                                        : [{ start: "09:00", end: "17:00" }]
                                    );
                                  }}
                                  className="mb-1 text-red-600 hover:text-red-700 border-red-200 hover:border-red-300"
                                >
                                  {t("exceptionModal.buttons.delete")}
                                </Button>
                              )}
                            </div>
                          ))}
                          <Button
                            variant="outline"
                            size="sm"
                            type="button"
                            onClick={() => {
                              hoursField.onChange([
                                ...hoursField.value,
                                { start: "09:00", end: "17:00" },
                              ]);
                            }}
                          >
                            <PlusIcon className="w-4 h-4 mr-1" />
                            {t("exceptionModal.buttons.addSlot")}
                          </Button>
                        </div>
                      </div>
                    )}
                  />
                ) : (
                  <></>
                )
              }
            />
          </div>

          <DialogFooter>
            <Button variant="outline" onClick={onClose}>
              {t("exceptionModal.buttons.cancel")}
            </Button>
            <Button
              variant="default"
              type="submit"
              className="[--btn-bg:var(--color-green-800)]"
              form="exception-form"
            >
              {t("exceptionModal.buttons.add")}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </form>
  );
};
