import { isValidDate } from "@web3r/flowerkit/date";
import { getStrWithZeroFromNum } from "@web3r/flowerkit/str";
import type { ReactNode } from "react";
import { useCallback, useContext, useMemo } from "react";
import type { ReactDatePickerCustomHeaderProps } from "react-datepicker";
import { Locale } from "../../locale";
import { Select } from "../../select";
import type { TOnChangeParams } from "../../select/config/types";
import type {
  THeaderStateActions, IDatePicker, TDatePickerCustomHeaderProps, TValidDateSingleStamp, TValidDateUnionStamp,
} from "../config/types";
import { DatePickerContext } from "../context";
import { getYearsRange } from "../lib";

type TDatePickerFastNavProps = {
  stateActions: THeaderStateActions;
  isPrevMonthDisabled: ReactDatePickerCustomHeaderProps["prevMonthButtonDisabled"];
  isNextMonthDisabled: ReactDatePickerCustomHeaderProps["nextMonthButtonDisabled"];
  onCtrlChange: IDatePicker["onCtrlChange"];
  minDate: TValidDateSingleStamp;
  maxDate: TValidDateSingleStamp;
  date: Date;
} & Pick<TDatePickerCustomHeaderProps, "dateInputValue" | "pickerRef" | "name">;

/**
 * Блок выстрой навигации
 * @returns {ReactNode}
 */
export const DatePickerFastNav = ({
  stateActions,
  date,
  onCtrlChange,
  isPrevMonthDisabled,
  isNextMonthDisabled,
  maxDate,
  minDate,
  name,
  dateInputValue,
  pickerRef,
}: TDatePickerFastNavProps): ReactNode => {

  const { getCN } = useContext(DatePickerContext);

  const months = useMemo(() => {
    return [ ...Array(12).keys() ].map((index) => {
      return {
        label: getStrWithZeroFromNum(index + 1),
        value: index.toString(),
      };
    });
  }, []);

  const years = useMemo(() => {
    if (isValidDate(minDate) && isValidDate(maxDate)) {
      return getYearsRange(minDate as Date, maxDate as Date)
        .map((date) => {
          const yyyy = date.getFullYear().toString();
          return {
            label: yyyy,
            value: yyyy,
          };
        }).reverse();
    } else {
      console.error(`[DatePickerFastNav] Something wrong with "minDate" or "maxDate" from year select`, [ minDate, maxDate ]);
      return [];
    }
  }, [ minDate, maxDate ]);

  const onChangeYear = useCallback((params: TOnChangeParams) => {
    const { data } = params;
    if (typeof onCtrlChange === "function") {
      onCtrlChange({
        data: {
          name,
          dateInputValue,
          value: (data.value as { value?: string; } | null)?.value as unknown as TValidDateUnionStamp,
          type: "changeYear",
        },
        event: new Event("change"),
        stateActions,
        ref: pickerRef,
      });
    } else {
      const yyyy = Number((data.value as { value?: string; } | null)?.value);
      if (Number.isNaN(yyyy)) {
        console.error(`[DatePickerFastNav] Something wrong with value from year select`, data);
      } else {
        stateActions.changeYear(yyyy);
      }
    }
  }, [ onCtrlChange, date, stateActions ]);

  const onChangeMonth = useCallback((params: TOnChangeParams) => {
    const { data } = params;
    if (typeof onCtrlChange === "function") {
      onCtrlChange({
        data: {
          name,
          dateInputValue,
          value: (data.value as { value?: string; } | null)?.value as unknown as TValidDateUnionStamp,
          type: "changeMonth",
        },
        event: new Event("change"),
        stateActions,
        ref: pickerRef,
      });
    } else {
      const mm = Number((data.value as { value?: string; } | null)?.value);
      if (Number.isNaN(mm)) {
        console.error(`[DatePickerFastNav] Something wrong with value from month select`, data);
      } else {
        stateActions.changeMonth(mm);
      }
    }
  }, [ onCtrlChange, date, stateActions ]);

  const currentMonth = useMemo(() => isValidDate(date) ? date.getMonth().toString() : null, [ date ]);
  const currentYear = useMemo(() => isValidDate(date) ? date.getFullYear().toString() : null, [ date ]);

  return (
    <div className={getCN("fastNav")}>
      <div className={getCN("fastNavMonths")}>
        <Locale code={"datePicker.month"} />
        <Select isDisabled={isPrevMonthDisabled && isNextMonthDisabled} value={currentMonth} onChange={onChangeMonth}
          options={months} />
      </div>
      <div className={getCN("fastNavYears")}>
        <Locale code={"datePicker.year"} />
        <Select isDisabled={isPrevMonthDisabled && isNextMonthDisabled} onChange={onChangeYear} value={currentYear}
          options={years} />
      </div>
    </div>
  );

};
