import React, { forwardRef, useContext, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
import classNames from "classnames";
import CalendarDay from "./CalendarDay";
import ConfigProviderContext from "../config-provider/ConfigProviderContext";
import { compareDay, formatMonthTitle, getMonthEndDay, getNextDay, getPrevDay, t } from "./utils";
import { addUnit, setScrollTop } from "../utils";
import { getRect } from "../hooks/get-rect";
const CalendarMonth = /* @__PURE__ */ forwardRef((props, ref) => {
  const {
    prefixCls,
    createNamespace
  } = useContext(ConfigProviderContext);
  const [bem] = createNamespace("calendar", prefixCls);
  const [visible, setVisible] = useState(false);
  const {
    showMonthTitle,
    date,
    showMark,
    firstDayOfWeek
  } = props;
  const daysRef = useRef(null);
  const [monthRef, setMonthRef] = useState();
  const height = useRef(0);
  useEffect(() => {
    if (monthRef) {
      height.current = getRect(monthRef).height;
    }
  }, [monthRef]);
  const title = useMemo(() => {
    const formatterFn = props.formatMonthTitle || formatMonthTitle;
    return formatterFn(date);
  }, [date]);
  const rowHeight = useMemo(() => addUnit(props.rowHeight), [props.rowHeight]);
  const offset = useMemo(() => {
    const realDay = date.getDay();
    if (firstDayOfWeek) {
      return (realDay + 7 - firstDayOfWeek) % 7;
    }
    return realDay;
  }, [date, firstDayOfWeek]);
  const totalDay = useMemo(() => {
    return getMonthEndDay(date.getFullYear(), date.getMonth() + 1);
  }, [date]);
  const shouldRender = useMemo(() => visible || !props.lazyRender, [visible, props.lazyRender]);
  const getTitle = () => title;
  const onClick = (item) => {
    var _a;
    (_a = props.onClick) == null ? void 0 : _a.call(props, item);
  };
  const getMultipleDayType = (day) => {
    const isSelected = (date2) => props.currentDate.some((item) => compareDay(item, date2) === 0);
    if (isSelected(day)) {
      const prevDay = getPrevDay(day);
      const nextDay = getNextDay(day);
      const prevSelected = isSelected(prevDay);
      const nextSelected = isSelected(nextDay);
      if (prevSelected && nextSelected) {
        return "multiple-middle";
      }
      if (prevSelected) {
        return "end";
      }
      if (nextSelected) {
        return "start";
      }
      return "multiple-selected";
    }
    return "";
  };
  const getRangeDayType = (day) => {
    const [startDay, endDay] = props.currentDate;
    if (!startDay) {
      return "";
    }
    const compareToStart = compareDay(day, startDay);
    if (!endDay) {
      return compareToStart === 0 ? "start" : "";
    }
    const compareToEnd = compareDay(day, endDay);
    if (props.allowSameDay && compareToStart === 0 && compareToEnd === 0) {
      return "start-end";
    }
    if (compareToStart === 0) {
      return "start";
    }
    if (compareToEnd === 0) {
      return "end";
    }
    if (compareToStart > 0 && compareToEnd < 0) {
      return "middle";
    }
    return "";
  };
  const getDayType = (day) => {
    const {
      type,
      minDate,
      maxDate,
      currentDate
    } = props;
    if (compareDay(day, minDate) < 0 || compareDay(day, maxDate) > 0) {
      return "disabled";
    }
    if (Array.isArray(currentDate)) {
      if (type === "multiple") {
        return getMultipleDayType(day);
      }
      if (type === "range") {
        return getRangeDayType(day);
      }
    } else if (type === "single") {
      return compareDay(day, currentDate) === 0 ? "selected" : "";
    }
    return "";
  };
  const getBottomInfo = (dayType) => {
    if (props.type === "range") {
      if (dayType === "start" || dayType === "end") {
        return t(dayType);
      }
      if (dayType === "start-end") {
        return t("startEnd");
      }
    }
    return "";
  };
  const renderTitle = () => {
    return showMonthTitle ? /* @__PURE__ */ React.createElement("div", {
      className: classNames(bem("month-title"))
    }, title) : null;
  };
  const renderMark = () => {
    return showMark && shouldRender ? /* @__PURE__ */ React.createElement("div", {
      className: classNames(bem("month-mark"))
    }, props.date.getMonth() + 1) : null;
  };
  const placeholders = useMemo(() => {
    const count = Math.ceil((totalDay + offset) / 7);
    return Array(count).fill({
      type: "placeholder"
    });
  }, [totalDay, offset]);
  const daysList = useMemo(() => {
    const days = [];
    const year = props.date.getFullYear();
    const month = props.date.getMonth();
    for (let day = 1; day <= totalDay; day++) {
      const date2 = new Date(year, month, day);
      const type = getDayType(date2);
      let config = {
        date: date2,
        type,
        text: day,
        bottomInfo: getBottomInfo(type)
      };
      if (props.formatter) {
        config = props.formatter(config);
      }
      days.push(config);
    }
    return days;
  }, [props.currentDate, props.date, props.formatter]);
  const disabledDays = useMemo(() => daysList.filter((day) => day.type === "disabled"), [daysList]);
  const scrollToDate = (body, targetDate) => {
    if (daysRef.current) {
      const daysRect = getRect(daysRef.current);
      const totalRows = placeholders.length;
      const currentRow = Math.ceil((targetDate.getDate() + offset) / 7);
      const rowOffset = (currentRow - 1) * daysRect.height / totalRows;
      setScrollTop(body, daysRect.top + rowOffset + body.scrollTop - getRect(body).top);
    }
  };
  const renderDay = (item, index) => {
    return /* @__PURE__ */ React.createElement(CalendarDay, {
      key: String(index),
      item,
      index,
      color: props.color,
      offset,
      rowHeight,
      onClick
    });
  };
  const renderDays = () => {
    return /* @__PURE__ */ React.createElement("div", {
      ref: daysRef,
      role: "grid",
      className: classNames(bem("days"))
    }, renderMark(), (shouldRender ? daysList : placeholders).map(renderDay));
  };
  useImperativeHandle(ref, () => ({
    getTitle,
    getHeight: () => height.current,
    setVisible,
    scrollToDate,
    disabledDays
  }));
  return /* @__PURE__ */ React.createElement("div", {
    className: classNames(bem("month")),
    ref: setMonthRef
  }, renderTitle(), renderDays());
});
CalendarMonth.defaultProps = {};
var stdin_default = CalendarMonth;
export {
  stdin_default as default
};
