import "@/components/common/date-range.css";
import {
  DateRangePicker as BaseDateRangePicker,
  DateRangePickerProps,
  DateValue,
  RangeValue,
} from "@nextui-org/react";
import { ControllerFieldState } from "react-hook-form";
import { FaExclamationTriangle } from "react-icons/fa";
import { useState, useEffect } from "react";
import { parseDate, isWeekend } from "@internationalized/date";
import { useLocale } from "@react-aria/i18n";

type DateRangeCustomProps = {
  fieldProps: any;
  fieldState: ControllerFieldState;
  hasWeekendsAvailable?: boolean;
  control?: any;
  name?: string;
};

type DateRangeProps = DateRangeCustomProps & DateRangePickerProps;

function DateRange({
  label,
  allowsNonContiguousRanges = true,
  description,
  defaultValue,
  variant = "faded",
  color,
  size,
  placeholderValue,
  minValue,
  maxValue,
  labelPlacement = "outside",
  errorMessage,
  startContent,
  endContent,
  isRequired,
  isReadOnly,
  isDisabled,
  isInvalid,
  inputRef,
  hourCycle = 24,
  granularity,
  hideTimeZone,
  shouldForceLeadingZeros = true,
  disableAnimation,
  visibleMonths = 2,
  fieldProps,
  fieldState,
  classNames = {
    calendar: "dark font-noto",
    base: "mb-1.5 light text-black font-noto",
    innerWrapper: "text-black",
    input: `font-noto ${fieldState.invalid || isInvalid ? "text-black" : ""}`,
    label: "block text-sm font-bold tracking-tight font-inter",
    description:
      "font-inter font-regular text-[12px] text-gray-500 leading-tight",
    errorMessage:
      "font-inter font-regular mt-0.5 text-[12px] leading-tight flex text-red-800 font-semibold tracking-tight",
  },
  hasWeekendsAvailable = true,
}: DateRangeProps) {
  // Unique key to force re-render after form reset. DO NOT REMOVE.
  const [key, setKey] = useState<string>(Math.random().toString());
  let { locale } = useLocale();

  const convertStringToDateValue = (
    dateStr: string,
  ): RangeValue<DateValue> | undefined => {
    if (!dateStr) return undefined; // Handle empty or null strings
    const [startStr, endStr] = dateStr.split(" - ");
    if (!startStr || !endStr) throw new Error("Invalid date string.");

    const [startDay, startMonth, startYear] = startStr.split("/").map(Number);
    const [endDay, endMonth, endYear] = endStr.split("/").map(Number);

    const start = parseDate(
      `${startYear}-${startMonth.toString().padStart(2, "0")}-${startDay
        .toString()
        .padStart(2, "0")}`,
    );
    const end = parseDate(
      `${endYear}-${endMonth.toString().padStart(2, "0")}-${endDay
        .toString()
        .padStart(2, "0")}`,
    );

    return { start, end };
  };

  const [value, setValue] = useState<RangeValue<DateValue> | undefined>(
    fieldProps.value ? convertStringToDateValue(fieldProps.value) : undefined,
  );

  useEffect(() => {
    const newValue = fieldProps.value
      ? convertStringToDateValue(fieldProps.value)
      : undefined;
    setValue(newValue);
    setKey(Math.random().toString());
  }, [fieldProps.value]);

  const handleChange = (newValue: RangeValue<DateValue> | undefined) => {
    if (newValue?.start && newValue?.end) {
      const start = new Date(
        newValue.start.year,
        newValue.start.month - 1,
        newValue.start.day,
      );

      const end = new Date(
        newValue.end.year,
        newValue.end.month - 1,
        newValue.end.day,
      );

      const formattedStart = start.toLocaleDateString("en-GB");
      const formattedEnd = end.toLocaleDateString("en-GB");

      const formattedValue = `${formattedStart} - ${formattedEnd}`;

      setValue(newValue);
      fieldProps.onChange(formattedValue);
    } else {
      setValue(undefined);
      fieldProps.onChange(""); // Use an empty string instead of undefined
    }
  };

  return (
    <BaseDateRangePicker
      {...fieldProps}
      key={key}
      allowsNonContiguousRanges={allowsNonContiguousRanges}
      aria-describedby={fieldProps.name}
      aria-labelledby={`${fieldProps?.name}-label`}
      classNames={classNames}
      color={color}
      defaultValue={defaultValue}
      description={description}
      disableAnimation={disableAnimation}
      endContent={endContent}
      errorMessage={
        fieldState.error ? (
          <>
            <FaExclamationTriangle className="me-1 my-auto size-3" />
            {fieldState.error.message}
          </>
        ) : (
          errorMessage
        )
      }
      granularity={granularity}
      hideTimeZone={hideTimeZone}
      hourCycle={hourCycle}
      id={fieldProps?.name}
      inputRef={inputRef}
      isDateUnavailable={(date) =>
        !hasWeekendsAvailable && isWeekend(date, locale)
      }
      isDisabled={isDisabled}
      isInvalid={fieldState.invalid ?? isInvalid}
      isReadOnly={isReadOnly}
      isRequired={isRequired}
      label={label}
      labelPlacement={labelPlacement}
      maxValue={maxValue}
      minValue={minValue}
      placeholderValue={placeholderValue}
      radius="sm"
      shouldForceLeadingZeros={shouldForceLeadingZeros}
      size={size}
      startContent={startContent}
      value={value}
      variant={variant}
      visibleMonths={visibleMonths}
      onChange={handleChange}
    />
  );
}

export default DateRange;
