import { isValidDate } from "@web3r/flowerkit/date";
import { formatDate } from "date-fns";
import type { ReactNode, MouseEvent } from "react";
import {
  cloneElement,
  isValidElement,
  useContext,
  useMemo,
} from "react";
import { DatePickerFastNav } from "./DatePickerFastNav";
import { Btn } from "../../btn";
import type { TDatePickerCustomHeaderSlotProps, THeaderStateActions, TDatePickerCustomHeaderProps } from "../config/types";
import { DatePickerContext } from "../context";
import { getDateFormat } from "../lib";

/**
 * Шапка календаря
 * @returns {ReactNode}
 */
export const DatePickerCustomHeader = ({
  dateInputValue,
  pickerRef,
  name,
  date,
  maxDate,
  minDate,
  changeYear,
  changeMonth,
  decreaseMonth,
  increaseMonth,
  prevMonthButtonDisabled,
  nextMonthButtonDisabled,
  onCtrlChange,
  slotHeader,
  dateFormat,
  timeFormat,
  isTime,
  isFastNav,
  iconPrev,
  iconNext,
}: TDatePickerCustomHeaderProps): ReactNode => {

  const { getCN } = useContext(DatePickerContext);

  const stateActions = useMemo<THeaderStateActions>(() => ({
    decreaseMonth,
    changeYear,
    changeMonth,
    increaseMonth,
  }), [ changeMonth, changeYear, decreaseMonth, increaseMonth ]);

  const onPrevClick = (event: MouseEvent) => {
    event.preventDefault();
    if (typeof onCtrlChange === "function") {
      onCtrlChange({
        data: {
          name,
          value: date,
          dateInputValue,
          type: "decreaseMonth",
        },
        ref: pickerRef,
        event,
        stateActions,
      });
    } else {
      decreaseMonth();
    }
  };

  const onNextClick = (event: MouseEvent) => {
    event.preventDefault();
    if (typeof onCtrlChange === "function") {
      onCtrlChange({
        data: {
          name,
          value: date,
          dateInputValue,
          type: "increaseMonth",
        },
        ref: pickerRef,
        event: event,
        stateActions,
      });
    } else {
      increaseMonth();
    }
  };

  const format = getDateFormat(isTime, dateFormat, timeFormat);
  const currentDateTitle = isValidDate(date) ? formatDate(date, format) : "";

  const customSlot = useMemo<ReactNode>(() => isValidElement<TDatePickerCustomHeaderSlotProps>(slotHeader) ? cloneElement(slotHeader, {
    ...slotHeader?.props ?? {},
    stateActions,
    date,
  }) : null, [ slotHeader, date, onCtrlChange, stateActions ]);

  return (
    <header className={getCN("ctrl")}>
      <div className={getCN("ctrlLayout")}>
        <div className={getCN("ctrlNav", { isPrev: true })}>
          <Btn size={"small"} iconSize={"medium"} icon={iconPrev} label={null} onClick={onPrevClick}
            isDisabled={prevMonthButtonDisabled} type={"button"} />
        </div>
        <div className={getCN("ctrlCurrent")}>
          {currentDateTitle}
        </div>
        <div className={getCN("ctrlNav", { isNext: true })}>
          <Btn size={"small"} iconSize={"medium"} icon={iconNext} label={null} onClick={onNextClick}
            isDisabled={nextMonthButtonDisabled} type={"button"} />
        </div>
      </div>
      {isFastNav && <DatePickerFastNav name={name} dateInputValue={dateInputValue}
        pickerRef={pickerRef} maxDate={maxDate} minDate={minDate} isPrevMonthDisabled={prevMonthButtonDisabled}
        isNextMonthDisabled={nextMonthButtonDisabled} stateActions={stateActions}
        date={date} onCtrlChange={onCtrlChange} />}
      {!!customSlot && <div className={getCN("ctrlSlot")}>{customSlot}</div>}
    </header>
  );

};
