import { useEffect, useMemo, useState } from "react";
import { useTranslations } from "@/hooks/translations";
import { FormField } from "@/types";
import DateInput from "./DateInput";
import ErrorText from "../ErrorText";
import { stringify, getCurrentYear } from "./utils";
import { IDate, getDateAsString } from "@/services/date";
import { ELocalesPlacement, language } from "@/locales";
import { getDateInputLocaleFormat } from "@/locales/localFormats";

export function DatePicker(
  props: FormField<Date | IDate | string> & {
    differenceOfMaximumAndCurrentYear?: number;
  }
): JSX.Element {
  const { translate } = useTranslations(ELocalesPlacement.V1);
  const { name, value, inputClassName, differenceOfMaximumAndCurrentYear = 11, onValid, onInvalid } = props;
  const date = getDateAsString(value);
  const [initYear, initMonth, initDay] = date.split("-");
  const [year, setYear] = useState(initYear);
  const [month, setMonth] = useState(
    initMonth?.startsWith("0") ? initMonth?.slice(1) : initMonth
  );
  const [day, setDay] = useState(
    initDay?.startsWith("0") ? initDay?.slice(1) : initDay
  );
  const [hasError, setHasError] = useState(false);

  const years = useMemo(() => {
    const currentYear = getCurrentYear();
    return Array.from({ length: 66 }, (_, index) => {
      return currentYear - differenceOfMaximumAndCurrentYear - index;
    });
  }, []);
  const months = useMemo(() => {
    return Array.from({ length: 12 }, (_, index) => {
      return index + 1;
    });
  }, []);

  const days = useMemo(() => {
    return Array.from(
      { length: new Date(Number(year), Number(month), 0).getDate() || 31 },
      (_, index) => (index + 1).toString()
    );
  }, [month, year]);

  const isValid = (value: string) => {
    const date = new Date(value);
    const isCorrectDate = stringify(date) === value;
    const isNotFutureDate = date?.getTime() <= Date.now();
    const isNotMinDate = date?.getFullYear() >= getCurrentYear() - 200;
    return isCorrectDate && isNotFutureDate && isNotMinDate;
  };

  const dateInputLocaleFormat = useMemo(
    () => getDateInputLocaleFormat(language),
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [language]
  );

  useEffect(() => {
    if (year && month && day) {
      const currentValue = `${year}-${month?.padStart(2, "0")}-${day?.padStart(
        2,
        "0"
      )}`;
      setHasError(!isValid(currentValue));
      isValid(currentValue) ? onValid(currentValue) : onInvalid();
    } else {
      setHasError(false);
      onValid("");
    }
  }, [year, month, day, hasError, onValid, onInvalid]);

  return (
    <form name={name} className="date-picker">
      <div className="date-picker__container">
        {dateInputLocaleFormat.map((value, index) => (
          <div key={index}>
            {value === "y" && (
              <DateInput
                name="year"
                value={year ? String(parseInt(year, 10)) : ""}
                values={years}
                label={translate("year")}
                placeholder="YYYY"
                inputClassName={inputClassName}
                onChange={(year: string) => setYear(year)}
              />
            )}
            {value === "m" && (
              <DateInput
                name="month"
                value={month}
                values={months}
                label={translate("month")}
                placeholder="MM"
                inputClassName={inputClassName}
                onChange={(month: string) => setMonth(month)}
              />
            )}
            {value === "d" && (
              <DateInput
                name="day"
                value={day}
                values={days}
                label={translate("day")}
                placeholder="DD"
                inputClassName={inputClassName}
                onChange={(day: string) => setDay(day)}
              />
            )}
          </div>
        ))}
      </div>
      <ErrorText
        isShown={hasError}
        message={translate("invalid_date", undefined, ELocalesPlacement.V0)}
      />
    </form>
  );
}
