import { useState } from "react";
import { Control, FieldValues } from "react-hook-form";
import $ from "@/shared/common/jquery-global";
import { FormField, FormItem, FormLabel, FormMessage } from "../../ui/form";
import EthiopianDatePickerModal, {
  convertEthiopianToGregorian,
} from "./AmharicDatePicker";
import { Popover, PopoverContent, PopoverTrigger } from "../../ui/popover";
import { Button } from "../../ui/button";
import { cn } from "@/shared/lib/utils";
import { format } from "date-fns";
import { CalendarIcon } from "lucide-react";
import { Calendar } from "../../ui/calendar";
import { Input } from "../../ui/input";
import { useTranslation } from "react-i18next";
import {
  formatEthiopianClockTime,
  utcToEthiopian,
} from "@/shared/common/utils/ethiopianTimeZone";

interface DateFieldProps {
  name: "startDate" | "endDate";
  label: string;
  control: Control<FieldValues>;
  isEthiopian: boolean;
  minDate?: Date | null;
}

interface EthiopianCalendarFormatter {
  fromJSDate: (jsDate: Date) => unknown;
  formatDate: (
    format: string,
    date: unknown,
    settings?: { localNumbers?: boolean },
  ) => string;
}

const DateField: React.FC<DateFieldProps> = ({
  name,
  label,
  control,
  isEthiopian,
  minDate,
}) => {
  const [gregorianTimeFallback, setGregorianTimeFallback] = useState<string>(
    () => format(new Date(), "HH:mm"),
  );
  const { t } = useTranslation();

  return (
    <FormField
      control={control}
      name={name}
      render={({ field }) => {
        const getGregorianTimeValue = (): string => {
          if (
            field.value instanceof Date &&
            !Number.isNaN(field.value.getTime())
          ) {
            return format(field.value, "HH:mm");
          }
          return gregorianTimeFallback;
        };

        const handleEthiopianChange = (ethiopianDate: string) => {
          const gregorianDate = convertEthiopianToGregorian(ethiopianDate);
          if (!Number.isNaN(gregorianDate.getTime())) {
            field.onChange(gregorianDate);
          }
        };

        const getDisplayText = (): string => {
          if (isEthiopian) {
            if (
              field.value instanceof Date &&
              !Number.isNaN(field.value.getTime())
            ) {
              const ethiopianTime = utcToEthiopian(field.value);
              const timeStr = formatEthiopianClockTime(field.value);

              try {
                const ethiopianCalendar = $.calendars.instance(
                  "ethiopian",
                  "am",
                ) as unknown as EthiopianCalendarFormatter;
                const ethiopianDate =
                  ethiopianCalendar.fromJSDate(ethiopianTime);
                const dateStr = ethiopianCalendar.formatDate(
                  "yyyy-mm-dd",
                  ethiopianDate,
                  { localNumbers: true },
                );
                return `${dateStr} ${timeStr}`;
              } catch {
                const fallbackDate = format(ethiopianTime, "yyyy-MM-dd");
                return `${fallbackDate} ${timeStr}`;
              }
            }
            return t("delegation.pickDate");
          }
          if (
            field.value instanceof Date &&
            !Number.isNaN(field.value.getTime())
          ) {
            const dateText = format(field.value, "PPP");
            const timeText = format(field.value, "HH:mm");
            return `${dateText} ${timeText}`;
          }
          return t("delegation.pickDate");
        };

        return (
          <FormItem className="flex flex-col gap-2">
            <FormLabel className="text-base font-medium text-gray-700 dark:text-gray-200">
              {label}
            </FormLabel>

            <Popover>
              <PopoverTrigger asChild>
                <Button
                  variant="outline"
                  className={cn(
                    "group h-11 w-full justify-between rounded-md border border-gray-300 bg-white px-3 text-left text-base font-normal shadow-sm transition-colors hover:bg-gray-50 focus-visible:ring-2 focus-visible:ring-primary/30 dark:border-gray-600 dark:bg-gray-800 dark:hover:bg-gray-700 dark:text-gray-100",
                    !field.value && "text-gray-500 dark:text-gray-400",
                  )}>
                  <span className="truncate">{getDisplayText()}</span>
                  <CalendarIcon className="ml-3 h-4 w-4 shrink-0 text-gray-500 transition-colors group-hover:text-gray-700 dark:text-gray-400 dark:group-hover:text-gray-200" />
                </Button>
              </PopoverTrigger>

              <PopoverContent
                className="w-auto max-w-[95vw] overflow-x-auto rounded-lg border border-gray-200 bg-white p-3 shadow-xl dark:border-gray-700 dark:bg-gray-900"
                side="bottom"
                align="start"
                sideOffset={8}
                avoidCollisions={false}>
                {isEthiopian ? (
                  <div className="flex min-w-[20rem] flex-col gap-2">
                    <EthiopianDatePickerModal
                      value={field.value}
                      onChange={handleEthiopianChange}
                    />
                  </div>
                ) : (
                  <div className="min-w-[20rem] space-y-3">
                    <Calendar
                      mode="single"
                      selected={
                        field.value instanceof Date &&
                        !Number.isNaN(field.value.getTime())
                          ? field.value
                          : undefined
                      }
                      defaultMonth={
                        field.value instanceof Date &&
                        !Number.isNaN(field.value.getTime())
                          ? field.value
                          : minDate instanceof Date &&
                              !Number.isNaN(minDate.getTime())
                            ? minDate
                            : undefined
                      }
                      onSelect={(selectedDate) => {
                        if (!selectedDate) {
                          field.onChange(null);
                          return;
                        }

                        const [hours, minutes] = getGregorianTimeValue()
                          .split(":")
                          .map(Number);
                        const nextDate = new Date(selectedDate);
                        nextDate.setHours(hours || 0, minutes || 0, 0, 0);
                        field.onChange(nextDate);
                      }}
                      initialFocus
                      className="w-full p-2"
                      disabled={(date) => {
                        const startOfToday = new Date(
                          new Date().setHours(0, 0, 0, 0),
                        );
                        if (date < startOfToday) return true;
                        if (
                          minDate instanceof Date &&
                          !Number.isNaN(minDate.getTime())
                        ) {
                          const startOfMin = new Date(minDate);
                          startOfMin.setHours(0, 0, 0, 0);
                          if (date < startOfMin) return true;
                        }
                        return false;
                      }}
                    />
                    <div className="space-y-1 px-2 pb-1">
                      <p className="text-xs font-medium text-gray-600 dark:text-gray-300">
                        {t("common.Time", "Time")}
                      </p>
                      <Input
                        type="time"
                        value={getGregorianTimeValue()}
                        onChange={(event) => {
                          const newTime = event.target.value;
                          setGregorianTimeFallback(newTime);

                          if (
                            field.value instanceof Date &&
                            !Number.isNaN(field.value.getTime())
                          ) {
                            const [hours, minutes] = newTime
                              .split(":")
                              .map(Number);
                            const nextDate = new Date(field.value);
                            nextDate.setHours(hours || 0, minutes || 0, 0, 0);
                            field.onChange(nextDate);
                          }
                        }}
                        className="h-10"
                      />
                    </div>
                  </div>
                )}
              </PopoverContent>
            </Popover>

            <FormMessage className="text-sm" />
          </FormItem>
        );
      }}
    />
  );
};

export default DateField;
