"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

function _react() {
  const data = _interopRequireWildcard(require("react"));

  _react = function () {
    return data;
  };

  return data;
}

function _jsxRuntime() {
  const data = require("react/jsx-runtime");

  _jsxRuntime = function () {
    return data;
  };

  return data;
}

function _clsx() {
  const data = _interopRequireDefault(require("clsx"));

  _clsx = function () {
    return data;
  };

  return data;
}

var _utils = require("../utils");

var _utils2 = require("./utils");

var _utils3 = require("../datetime-picker/utils");

var _CalendarDay = _interopRequireDefault(require("./CalendarDay"));

var _useRect = require("../hooks/use-rect");

var _ConfigProviderContext = _interopRequireDefault(require("../config-provider/ConfigProviderContext"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }

function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

/* eslint-disable no-plusplus */
const CalenderMonth = (0, _react().forwardRef)((props, ref) => {
  const [visible, setVisible] = (0, _react().useState)();
  const daysRef = (0, _react().useRef)();
  const [monthRef, setMonthRef] = (0, _react().useState)();
  const height = (0, _react().useRef)(0);
  const {
    prefixCls,
    createNamespace,
    locale
  } = (0, _react().useContext)(_ConfigProviderContext.default);
  const [bem] = createNamespace('calendar', prefixCls);
  (0, _react().useEffect)(() => {
    if (monthRef) {
      height.current = (0, _useRect.getRect)(monthRef).height;
    }
  }, [monthRef]);
  const title = (0, _react().useMemo)(() => {
    return props.formatMonthTitle ? props.formatMonthTitle(props.date) : locale.vanCalendar.monthTitle(...(0, _utils2.formatMonthTitle)(props.date));
  }, [props.date, props.formatMonthTitle]);
  const rowHeight = (0, _react().useMemo)(() => (0, _utils.addUnit)(props.rowHeight), [props.rowHeight]);
  const offset = (0, _react().useMemo)(() => {
    const realDay = props.date.getDay();

    if (props.firstDayOfWeek) {
      return (realDay + 7 - props.firstDayOfWeek) % 7;
    }

    return realDay;
  }, [props.date, props.firstDayOfWeek]);
  const totalDay = (0, _react().useMemo)(() => (0, _utils3.getMonthEndDay)(props.date.getFullYear(), props.date.getMonth() + 1), [props.date]);
  const shouldRender = (0, _react().useMemo)(() => visible || !props.lazyRender, [visible]);

  const getTitle = () => title;

  const scrollIntoView = body => {
    const el = props.showSubtitle ? daysRef.current : monthRef;
    const scrollTop = el.getBoundingClientRect().top - body.getBoundingClientRect().top + body.scrollTop;
    (0, _utils.setScrollTop)(body, scrollTop);
  };

  const getMultipleDayType = day => {
    const isSelected = date => props.currentDate.some(item => (0, _utils2.compareDay)(item, date) === 0);

    if (isSelected(day)) {
      const prevDay = (0, _utils2.getPrevDay)(day);
      const nextDay = (0, _utils2.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 = (0, _utils2.compareDay)(day, startDay);

    if (!endDay) {
      return compareToStart === 0 ? 'start' : '';
    }

    const compareToEnd = (0, _utils2.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 ((0, _utils2.compareDay)(day, minDate) < 0 || (0, _utils2.compareDay)(day, maxDate) > 0) {
      return 'disabled';
    }

    if (currentDate === null) {
      return '';
    }

    if (Array.isArray(currentDate)) {
      if (type === 'multiple') {
        return getMultipleDayType(day);
      }

      if (type === 'range') {
        return getRangeDayType(day);
      }
    } else if (type === 'single') {
      return (0, _utils2.compareDay)(day, currentDate) === 0 ? 'selected' : '';
    }

    return '';
  };

  const getBottomInfo = dayType => {
    if (props.type === 'range') {
      if (dayType === 'start') {
        return locale.vanCalendar.start;
      }

      if (dayType === 'end') {
        return locale.vanCalendar.end;
      }

      if (dayType === 'start-end') {
        return locale.vanCalendar.startEnd;
      }
    }

    return null;
  };

  const renderTitle = () => {
    if (props.showMonthTitle) {
      return (0, _jsxRuntime().jsx)("div", Object.assign({
        className: (0, _clsx().default)(bem('month-title'))
      }, {
        children: title
      }));
    }

    return null;
  };

  const renderMark = () => {
    if (props.showMark && shouldRender) {
      return (0, _jsxRuntime().jsx)("div", Object.assign({
        className: (0, _clsx().default)(bem('month-mark'))
      }, {
        children: props.date.getMonth() + 1
      }));
    }

    return null;
  };

  const placeholders = (0, _react().useMemo)(() => {
    const count = Math.ceil((totalDay + offset) / 7);
    return Array(count).fill({
      type: 'placeholder'
    });
  }, [totalDay, offset]);
  const days = (0, _react().useMemo)(() => {
    const internalDays = [];
    const year = props.date.getFullYear();
    const month = props.date.getMonth();

    for (let day = 1; day <= totalDay; day++) {
      const date = new Date(year, month, day);
      const type = getDayType(date);
      let config = {
        date,
        type,
        text: day,
        bottomInfo: getBottomInfo(type)
      };

      if (props.formatter) {
        config = props.formatter(config);
      }

      internalDays.push(config);
    }

    return internalDays;
  }, [getDayType, props.date, props.formatter]);

  const renderDay = (item, index) => (0, _jsxRuntime().jsx)(_CalendarDay.default, {
    item: item,
    index: index,
    color: props.color,
    offset: offset,
    rowHeight: rowHeight,
    onClick: props.onClick,
    topInfoRender: props.topInfoRender,
    bottomInfoRender: props.bottomInfoRender
  }, index);

  const renderDays = () => (0, _jsxRuntime().jsxs)("div", Object.assign({
    ref: daysRef,
    role: "grid",
    className: (0, _clsx().default)(bem('days'))
  }, {
    children: [renderMark(), (shouldRender ? days : placeholders).map(renderDay)]
  }));

  (0, _react().useImperativeHandle)(ref, () => ({
    getTitle,
    getHeight: () => height.current,
    setVisible,
    scrollIntoView
  }));
  return (0, _jsxRuntime().jsxs)("div", Object.assign({
    className: (0, _clsx().default)(bem('month')),
    ref: setMonthRef
  }, {
    children: [renderTitle(), renderDays()]
  }));
});
var _default = CalenderMonth;
exports.default = _default;