"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.Context = exports.CalendarPickerView = void 0;
var _classnames = _interopRequireDefault(require("classnames"));
var _dayjs = _interopRequireDefault(require("dayjs"));
var _isoWeek = _interopRequireDefault(require("dayjs/plugin/isoWeek"));
var _isSameOrBefore = _interopRequireDefault(require("dayjs/plugin/isSameOrBefore"));
var _react = _interopRequireWildcard(require("react"));
var _nativeProps = require("../../utils/native-props");
var _usePropsValue = require("../../utils/use-props-value");
var _withDefaultProps = require("../../utils/with-default-props");
var _configProvider = require("../config-provider");
var _convert = require("./convert");
var _useSyncScroll = _interopRequireDefault(require("./useSyncScroll"));
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);
_dayjs.default.extend(_isSameOrBefore.default);
const classPrefix = 'adm-calendar-picker-view';
const Context = exports.Context = _react.default.createContext({
  visible: false
});
const defaultProps = {
  weekStartsOn: 'Sunday',
  defaultValue: null,
  allowClear: true,
  usePopup: true,
  selectionMode: 'single'
};
const CalendarPickerView = exports.CalendarPickerView = (0, _react.forwardRef)((p, ref) => {
  var _a;
  const bodyRef = (0, _react.useRef)(null);
  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));
  const onDateChange = v => {
    if (v) {
      setCurrent((0, _dayjs.default)(v[0]).date(1));
    }
    setDateRange(v);
  };
  const showHeader = props.title !== false;
  // =============================== Scroll ===============================
  const context = (0, _react.useContext)(Context);
  const scrollTo = (0, _useSyncScroll.default)(current, context.visible, bodyRef);
  // ============================== Boundary ==============================
  // 记录默认的 min 和 max，并在外部的值超出边界时自动扩充
  const [defaultMin, setDefaultMin] = (0, _react.useState)(current);
  const [defaultMax, setDefaultMax] = (0, _react.useState)(() => current.add(6, 'month'));
  (0, _react.useEffect)(() => {
    if (dateRange) {
      const [startDate, endDate] = dateRange;
      if (!props.min && startDate && (0, _dayjs.default)(startDate).isBefore(defaultMin)) {
        setDefaultMin((0, _dayjs.default)(startDate).date(1));
      }
      if (!props.max && endDate && (0, _dayjs.default)(endDate).isAfter(defaultMax)) {
        setDefaultMax((0, _dayjs.default)(endDate).endOf('month'));
      }
    }
  }, [dateRange]);
  const maxDay = (0, _react.useMemo)(() => props.max ? (0, _dayjs.default)(props.max) : defaultMax, [props.max, defaultMax]);
  const minDay = (0, _react.useMemo)(() => props.min ? (0, _dayjs.default)(props.min) : defaultMin, [props.min, defaultMin]);
  // ================================ Refs ================================
  (0, _react.useImperativeHandle)(ref, () => ({
    jumpTo: pageOrPageGenerator => {
      let page;
      if (typeof pageOrPageGenerator === 'function') {
        page = pageOrPageGenerator({
          year: current.year(),
          month: current.month() + 1
        });
      } else {
        page = pageOrPageGenerator;
      }
      const next = (0, _convert.convertPageToDayjs)(page);
      setCurrent(next);
      scrollTo(next);
    },
    jumpToToday: () => {
      const next = (0, _dayjs.default)().date(1);
      setCurrent(next);
      scrollTo(next);
    },
    getDateRange: () => dateRange
  }));
  // =============================== Render ===============================
  const header = _react.default.createElement("div", {
    className: `${classPrefix}-header`
  }, _react.default.createElement("div", {
    className: `${classPrefix}-title`
  }, (_a = props.title) !== null && _a !== void 0 ? _a : locale.Calendar.title));
  function renderBody() {
    var _a;
    const cells = [];
    let monthIterator = minDay;
    // 遍历月份
    while (monthIterator.isSameOrBefore(maxDay, 'month')) {
      const year = monthIterator.year();
      const month = monthIterator.month() + 1;
      const renderMap = {
        year,
        month
      };
      const yearMonth = `${year}-${month}`;
      // 获取需要预先填充的空格，如果是 7 天则不需要填充
      const presetEmptyCellCount = props.weekStartsOn === 'Monday' ? monthIterator.date(1).isoWeekday() - 1 : monthIterator.date(1).isoWeekday();
      const presetEmptyCells = presetEmptyCellCount == 7 ? null : Array(presetEmptyCellCount).fill(null).map((_, index) => _react.default.createElement("div", {
        key: index,
        className: `${classPrefix}-cell`
      }));
      cells.push(_react.default.createElement("div", {
        key: yearMonth,
        "data-year-month": yearMonth
      }, _react.default.createElement("div", {
        className: `${classPrefix}-title`
      }, (_a = locale.Calendar.yearAndMonth) === null || _a === void 0 ? void 0 : _a.replace(/\${(.*?)}/g, (_, variable) => {
        var _a;
        return (_a = renderMap[variable]) === null || _a === void 0 ? void 0 : _a.toString();
      })), _react.default.createElement("div", {
        className: `${classPrefix}-cells`
      }, presetEmptyCells, Array(monthIterator.daysInMonth()).fill(null).map((_, index) => {
        const d = monthIterator.date(index + 1);
        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 disabled = props.shouldDisableDate ? props.shouldDisableDate(d.toDate()) : maxDay && d.isAfter(maxDay, 'day') || minDay && d.isBefore(minDay, 'day');
        const renderTop = () => {
          var _a;
          if (props.renderTop === false) return null;
          const contentWrapper = content => _react.default.createElement("div", {
            className: `${classPrefix}-cell-top`
          }, content);
          const top = (_a = props.renderTop) === null || _a === void 0 ? void 0 : _a.call(props, d.toDate());
          if (top) {
            return contentWrapper(top);
          }
          if (props.selectionMode === 'range') {
            if (isBegin && isEnd) {
              return contentWrapper(locale.Calendar.startAndEnd);
            }
            if (isBegin) {
              return contentWrapper(locale.Calendar.start);
            }
            if (isEnd) {
              return contentWrapper(locale.Calendar.end);
            }
          }
          if (d.isSame(today, 'day') && !isSelect) {
            return contentWrapper(locale.Calendar.today);
          }
          return contentWrapper(null);
        };
        const renderBottom = () => {
          var _a;
          if (props.renderBottom === false) return null;
          return _react.default.createElement("div", {
            className: `${classPrefix}-cell-bottom`
          }, (_a = props.renderBottom) === null || _a === void 0 ? void 0 : _a.call(props, d.toDate()));
        };
        return _react.default.createElement("div", {
          key: d.valueOf(),
          className: (0, _classnames.default)(`${classPrefix}-cell`, {
            [`${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,
            [`${classPrefix}-cell-disabled`]: !!disabled
          }),
          onClick: () => {
            if (!props.selectionMode) return;
            if (disabled) return;
            const date = d.toDate();
            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()) {
                onDateChange(null);
                return;
              }
              onDateChange([date, date]);
            } else if (props.selectionMode === 'range') {
              if (!dateRange) {
                onDateChange([date, date]);
                setIntermediate(true);
                return;
              }
              if (shouldClear()) {
                onDateChange(null);
                setIntermediate(false);
                return;
              }
              if (intermediate) {
                const another = dateRange[0];
                onDateChange(another > date ? [date, another] : [another, date]);
                setIntermediate(false);
              } else {
                onDateChange([date, date]);
                setIntermediate(true);
              }
            }
          }
        }, renderTop(), _react.default.createElement("div", {
          className: `${classPrefix}-cell-date`
        }, props.renderDate ? props.renderDate(d.toDate()) : d.date()), renderBottom());
      }))));
      monthIterator = monthIterator.add(1, 'month');
    }
    return cells;
  }
  const body = _react.default.createElement("div", {
    className: `${classPrefix}-body`,
    ref: bodyRef
  }, renderBody());
  const mark = _react.default.createElement("div", {
    className: `${classPrefix}-mark`
  }, markItems.map((item, index) => _react.default.createElement("div", {
    key: index,
    className: `${classPrefix}-mark-cell`
  }, item)));
  return (0, _nativeProps.withNativeProps)(props, _react.default.createElement("div", {
    className: classPrefix
  }, showHeader && header, mark, body));
});