"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.Calendar = void 0;
var _ahooks = require("ahooks");
var _classnames = _interopRequireDefault(require("classnames"));
var _dayjs = _interopRequireDefault(require("dayjs"));
var _isoWeek = _interopRequireDefault(require("dayjs/plugin/isoWeek"));
var _react = _interopRequireWildcard(require("react"));
var _devLog = require("../../utils/dev-log");
var _nativeProps = require("../../utils/native-props");
var _replaceMessage = require("../../utils/replace-message");
var _usePropsValue = require("../../utils/use-props-value");
var _withDefaultProps = require("../../utils/with-default-props");
var _configProvider = require("../config-provider");
var _arrowLeft = require("./arrow-left");
var _arrowLeftDouble = require("./arrow-left-double");
var _convert = require("./convert");
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
_dayjs.default.extend(_isoWeek.default);
const classPrefix = 'adm-calendar';
const defaultProps = {
  weekStartsOn: 'Sunday',
  defaultValue: null,
  allowClear: true,
  prevMonthButton: _react.default.createElement(_arrowLeft.ArrowLeft, null),
  prevYearButton: _react.default.createElement(_arrowLeftDouble.ArrowLeftDouble, null),
  nextMonthButton: _react.default.createElement(_arrowLeft.ArrowLeft, null),
  nextYearButton: _react.default.createElement(_arrowLeftDouble.ArrowLeftDouble, null)
};
const Calendar = exports.Calendar = (0, _react.forwardRef)((p, ref) => {
  const today = (0, _dayjs.default)();
  const props = (0, _withDefaultProps.mergeProps)(defaultProps, p);
  const {
    locale
  } = (0, _configProvider.useConfig)();
  const markItems = [...locale.Calendar.markItems];
  if (props.weekStartsOn === 'Sunday') {
    const item = markItems.pop();
    if (item) markItems.unshift(item);
  }
  const [dateRange, setDateRange] = (0, _usePropsValue.usePropsValue)({
    value: props.value === undefined ? undefined : (0, _convert.convertValueToRange)(props.selectionMode, props.value),
    defaultValue: (0, _convert.convertValueToRange)(props.selectionMode, props.defaultValue),
    onChange: v => {
      var _a, _b;
      if (props.selectionMode === 'single') {
        (_a = props.onChange) === null || _a === void 0 ? void 0 : _a.call(props, v ? v[0] : null);
      } else if (props.selectionMode === 'range') {
        (_b = props.onChange) === null || _b === void 0 ? void 0 : _b.call(props, v);
      }
    }
  });
  const [intermediate, setIntermediate] = (0, _react.useState)(false);
  const [current, setCurrent] = (0, _react.useState)(() => (0, _dayjs.default)(dateRange ? dateRange[0] : today).date(1));
  (0, _ahooks.useUpdateEffect)(() => {
    var _a;
    (_a = props.onPageChange) === null || _a === void 0 ? void 0 : _a.call(props, current.year(), current.month() + 1);
  }, [current]);
  (0, _react.useImperativeHandle)(ref, () => ({
    jumpTo: pageOrPageGenerator => {
      let page;
      if (typeof pageOrPageGenerator === 'function') {
        page = pageOrPageGenerator({
          year: current.year(),
          month: current.month() + 1
        });
      } else {
        page = pageOrPageGenerator;
      }
      setCurrent((0, _convert.convertPageToDayjs)(page));
    },
    jumpToToday: () => {
      setCurrent((0, _dayjs.default)().date(1));
    }
  }));
  const handlePageChange = (action, num, type) => {
    const nxtCurrent = current[action](num, type);
    if (action === 'subtract' && props.minPage) {
      const minPage = (0, _convert.convertPageToDayjs)(props.minPage);
      if (nxtCurrent.isBefore(minPage, type)) {
        return;
      }
    }
    if (action === 'add' && props.maxPage) {
      const maxPage = (0, _convert.convertPageToDayjs)(props.maxPage);
      if (nxtCurrent.isAfter(maxPage, type)) {
        return;
      }
    }
    setCurrent(nxtCurrent);
  };
  const header = _react.default.createElement("div", {
    className: `${classPrefix}-header`
  }, props.prevYearButton !== null && _react.default.createElement("a", {
    className: `${classPrefix}-arrow-button ${classPrefix}-arrow-button-year`,
    onClick: () => {
      handlePageChange('subtract', 1, 'year');
    }
  }, props.prevYearButton), props.prevMonthButton !== null && _react.default.createElement("a", {
    className: `${classPrefix}-arrow-button ${classPrefix}-arrow-button-month`,
    onClick: () => {
      handlePageChange('subtract', 1, 'month');
    }
  }, props.prevMonthButton), _react.default.createElement("div", {
    className: `${classPrefix}-title`
  }, (0, _replaceMessage.replaceMessage)(locale.Calendar.yearAndMonth, {
    year: current.year().toString(),
    month: (current.month() + 1).toString()
  })), props.nextMonthButton !== null && _react.default.createElement("a", {
    className: (0, _classnames.default)(`${classPrefix}-arrow-button`, `${classPrefix}-arrow-button-right`, `${classPrefix}-arrow-button-right-month`),
    onClick: () => {
      handlePageChange('add', 1, 'month');
    }
  }, props.nextMonthButton), props.nextYearButton !== null && _react.default.createElement("a", {
    className: (0, _classnames.default)(`${classPrefix}-arrow-button`, `${classPrefix}-arrow-button-right`, `${classPrefix}-arrow-button-right-year`),
    onClick: () => {
      handlePageChange('add', 1, 'year');
    }
  }, props.nextYearButton));
  const maxDay = (0, _react.useMemo)(() => props.max && (0, _dayjs.default)(props.max), [props.max]);
  const minDay = (0, _react.useMemo)(() => props.min && (0, _dayjs.default)(props.min), [props.min]);
  function renderCells() {
    var _a;
    const cells = [];
    let iterator = current.subtract(current.isoWeekday(), 'day');
    if (props.weekStartsOn === 'Monday') {
      iterator = iterator.add(1, 'day');
    }
    while (cells.length < 6 * 7) {
      const d = iterator;
      let isSelect = false;
      let isBegin = false;
      let isEnd = false;
      let isSelectRowBegin = false;
      let isSelectRowEnd = false;
      if (dateRange) {
        const [begin, end] = dateRange;
        isBegin = d.isSame(begin, 'day');
        isEnd = d.isSame(end, 'day');
        isSelect = isBegin || isEnd || d.isAfter(begin, 'day') && d.isBefore(end, 'day');
        if (isSelect) {
          isSelectRowBegin = (cells.length % 7 === 0 || d.isSame(d.startOf('month'), 'day')) && !isBegin;
          isSelectRowEnd = (cells.length % 7 === 6 || d.isSame(d.endOf('month'), 'day')) && !isEnd;
        }
      }
      const inThisMonth = d.month() === current.month();
      const disabled = props.shouldDisableDate ? props.shouldDisableDate(d.toDate()) : maxDay && d.isAfter(maxDay, 'day') || minDay && d.isBefore(minDay, 'day');
      const originalCell = _react.default.createElement("div", {
        key: d.valueOf(),
        className: (0, _classnames.default)(`${classPrefix}-cell`, (disabled || !inThisMonth) && `${classPrefix}-cell-disabled`, inThisMonth && {
          [`${classPrefix}-cell-today`]: d.isSame(today, 'day'),
          [`${classPrefix}-cell-selected`]: isSelect,
          [`${classPrefix}-cell-selected-begin`]: isBegin,
          [`${classPrefix}-cell-selected-end`]: isEnd,
          [`${classPrefix}-cell-selected-row-begin`]: isSelectRowBegin,
          [`${classPrefix}-cell-selected-row-end`]: isSelectRowEnd
        }),
        onClick: () => {
          if (!props.selectionMode) return;
          if (disabled) return;
          const date = d.toDate();
          if (!inThisMonth) {
            setCurrent(d.clone().date(1));
          }
          function shouldClear() {
            if (!props.allowClear) return false;
            if (!dateRange) return false;
            const [begin, end] = dateRange;
            return d.isSame(begin, 'date') && d.isSame(end, 'day');
          }
          if (props.selectionMode === 'single') {
            if (props.allowClear && shouldClear()) {
              setDateRange(null);
              return;
            }
            setDateRange([date, date]);
          } else if (props.selectionMode === 'range') {
            if (!dateRange) {
              setDateRange([date, date]);
              setIntermediate(true);
              return;
            }
            if (shouldClear()) {
              setDateRange(null);
              setIntermediate(false);
              return;
            }
            if (intermediate) {
              const another = dateRange[0];
              setDateRange(another > date ? [date, another] : [another, date]);
              setIntermediate(false);
            } else {
              setDateRange([date, date]);
              setIntermediate(true);
            }
          }
        }
      }, _react.default.createElement("div", {
        className: `${classPrefix}-cell-top`
      }, props.renderDate ? props.renderDate(d.toDate()) : d.date()), _react.default.createElement("div", {
        className: `${classPrefix}-cell-bottom`
      }, (_a = props.renderLabel) === null || _a === void 0 ? void 0 : _a.call(props, d.toDate())));
      // Wrap with Fragment to ensure key is properly set
      const cellWithKey = props.cellRender ? _react.default.createElement(_react.default.Fragment, {
        key: d.valueOf()
      }, props.cellRender(originalCell, {
        date: d.toDate()
      })) : originalCell;
      cells.push(cellWithKey);
      iterator = iterator.add(1, 'day');
    }
    return cells;
  }
  const body = _react.default.createElement("div", {
    className: `${classPrefix}-cells`
  }, renderCells());
  const mark = _react.default.createElement("div", {
    className: `${classPrefix}-mark`
  }, markItems.map((item, index) => _react.default.createElement("div", {
    key: index,
    className: `${classPrefix}-mark-cell`
  }, item)));
  // Dev only warning
  if (process.env.NODE_ENV !== 'production') {
    (0, _react.useEffect)(() => {
      (0, _devLog.devWarning)('Calendar', 'Calendar will be removed in the future, please use CalendarPickerView instead.');
    }, []);
  }
  return (0, _nativeProps.withNativeProps)(props, _react.default.createElement("div", {
    className: classPrefix
  }, header, mark, body));
});