"use strict";

var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

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

var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));

var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));

var _bem = require("@zarm-design/bem");

var _dayjs = _interopRequireDefault(require("dayjs"));

var _throttle = _interopRequireDefault(require("lodash/throttle"));

var _react = _interopRequireWildcard(require("react"));

var _reactTransitionGroup = require("react-transition-group");

var _carousel = _interopRequireDefault(require("../carousel"));

var _configProvider = require("../config-provider");

var _useScroll = _interopRequireDefault(require("../use-scroll"));

var _dom = require("../utils/dom");

var _Header = _interopRequireDefault(require("./Header"));

var _Month = _interopRequireDefault(require("./Month"));

var _parseState = _interopRequireDefault(require("./utils/parseState"));

var _Week = _interopRequireDefault(require("./Week"));

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }

var Calendar = /*#__PURE__*/_react.default.forwardRef(function (props, ref) {
  var className = props.className,
      dateRender = props.dateRender,
      disabledDate = props.disabledDate,
      onChange = props.onChange,
      mode = props.mode,
      maxDate = props.max,
      minDate = props.min,
      direction = props.direction,
      header = props.header;

  var container = ref || /*#__PURE__*/_react.default.createRef();

  var _useContext = (0, _react.useContext)(_configProvider.ConfigContext),
      prefixCls = _useContext.prefixCls;

  var carouselRef = (0, _react.useRef)(null);
  var bem = (0, _bem.createBEM)('calendar', {
    prefixCls: prefixCls
  });
  var cls = bem([className]);

  var _useState = (0, _react.useState)(function () {
    return _objectSpread(_objectSpread({}, (0, _parseState.default)(props)), {}, {
      step: 0
    });
  }),
      _useState2 = (0, _slicedToArray2.default)(_useState, 2),
      state = _useState2[0],
      setState = _useState2[1];

  var min = state.min,
      max = state.max,
      value = state.value;
  var nodes = (0, _react.useRef)({});

  var scrollBodyRef = /*#__PURE__*/_react.default.createRef();

  var weekRef = _react.default.useRef();

  var _useState3 = (0, _react.useState)(),
      _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
      scrollDate = _useState4[0],
      setScrollDate = _useState4[1];

  var _useState5 = (0, _react.useState)(false),
      _useState6 = (0, _slicedToArray2.default)(_useState5, 2),
      scrolling = _useState6[0],
      setScrolling = _useState6[1];

  var isHorizontal = (0, _react.useMemo)(function () {
    return direction === 'horizontal';
  }, [direction]);
  var months = (0, _react.useMemo)(function () {
    var month = [];
    var dateMax = (0, _dayjs.default)(max);
    var dateMin = (0, _dayjs.default)(min);
    var len = (dateMax.year() - dateMin.year()) * 12 + dateMax.month() - dateMin.month();
    var i = 0;

    do {
      month.push((0, _dayjs.default)(min).add(i, 'month').toDate());
      i += 1;
    } while (i <= len);

    return month;
  }, [state.max, state.min]);
  var currentMonthIndex = (0, _react.useMemo)(function () {
    var currentTime = (0, _dayjs.default)(value[0] || new Date());
    return months.findIndex(function (current) {
      return (0, _dayjs.default)(current).isSame(currentTime, 'month');
    });
  }, [state.value]);

  var _useState7 = (0, _react.useState)(currentMonthIndex),
      _useState8 = (0, _slicedToArray2.default)(_useState7, 2),
      currentMonth = _useState8[0],
      setCurrentMonth = _useState8[1]; // 月历定位


  var scrollIntoView = (0, _react.useRef)(false);

  var anchor = function anchor() {
    var target = value[0] || new Date();
    var key = "".concat(target.getFullYear(), "-").concat(target.getMonth());
    var node = nodes.current[key];

    if (node !== null && node !== void 0 && node.el() && scrollBodyRef.current && weekRef.current) {
      var _node$el;

      scrollIntoView.current = true;
      var top = (_node$el = node.el()) === null || _node$el === void 0 ? void 0 : _node$el.offsetTop;

      var _getElementSize = (0, _dom.getElementSize)(weekRef.current),
          height = _getElementSize.height;

      scrollBodyRef.current.scrollTop = top - height;
    }
  };

  var handleDateClick = (0, _react.useCallback)(function (date) {
    var step = state.step,
        steps = state.steps;
    var currentStep = step + 1;
    var idx = value.map(Number).indexOf(Number(date));

    if (currentStep === 1 && mode !== 'multiple') {
      value.splice(0, value.length);
    }

    if (mode === 'range') {
      value[currentStep - 1] = date;
    } else if (idx > -1) {
      value.splice(idx, 1);
    } else if (mode === 'multiple') {
      value.push(date);
    } else {
      value[currentStep - 1] = date;
    }

    value.sort(function (item1, item2) {
      return +item1 - +item2;
    });
    setState(function (prevState) {
      return _objectSpread(_objectSpread({}, prevState), {}, {
        value: value,
        step: currentStep === steps ? 0 : currentStep
      });
    });

    if ((currentStep >= steps || mode === 'multiple') && typeof onChange === 'function') {
      onChange(value);
    }
  }, [value, mode, onChange, state]);

  var renderMonth = function renderMonth(dateMonth) {
    var key = "".concat(dateMonth.getFullYear(), "-").concat(dateMonth.getMonth() + 1);
    return /*#__PURE__*/_react.default.createElement(_Month.default, {
      key: key,
      min: min,
      max: max,
      mode: mode,
      value: value,
      dateMonth: dateMonth,
      dateRender: dateRender,
      disabledDate: disabledDate,
      onDateClick: handleDateClick,
      ref: function ref(n) {
        nodes.current[key] = n;
      }
    });
  };

  var content = (0, _react.useMemo)(function () {
    return months.map(function (item) {
      return renderMonth(item);
    });
  }, [months, min, max, disabledDate, dateRender, mode, handleDateClick, value]);
  var showHeader = (0, _react.useMemo)(function () {
    return direction === 'horizontal' && header;
  }, [direction, header]);
  var weekNode = weekRef === null || weekRef === void 0 ? void 0 : weekRef.current;
  var bodyScroll = (0, _throttle.default)(function () {
    var body = scrollBodyRef.current;

    if (!body) {
      return false;
    }

    var _ref = body,
        scrollTop = _ref.scrollTop;
    var keys = Object.keys(nodes === null || nodes === void 0 ? void 0 : nodes.current);
    keys = keys.sort(function (a, b) {
      return new Date(a).getTime() - new Date(b).getTime();
    });

    for (var i = 0; i < keys.length; i++) {
      var _nodes$current$keys$i;

      var el = nodes === null || nodes === void 0 ? void 0 : (_nodes$current$keys$i = nodes.current[keys[i]]) === null || _nodes$current$keys$i === void 0 ? void 0 : _nodes$current$keys$i.el();

      if ((el === null || el === void 0 ? void 0 : el.offsetTop) + (el === null || el === void 0 ? void 0 : el.clientHeight) - (weekNode === null || weekNode === void 0 ? void 0 : weekNode.clientHeight) > scrollTop) {
        setScrollDate(el.getAttribute('title'));
        return;
      }
    }
  }, 150);
  var monthsContent = isHorizontal ? /*#__PURE__*/_react.default.createElement(_carousel.default, {
    className: bem('body'),
    showPagination: false,
    activeIndex: currentMonth,
    onChange: setCurrentMonth,
    ref: carouselRef
  }, content) : /*#__PURE__*/_react.default.createElement("div", {
    className: bem('body'),
    ref: scrollBodyRef,
    onScroll: bodyScroll
  }, content, /*#__PURE__*/_react.default.createElement(_reactTransitionGroup.Transition, {
    in: scrolling,
    timeout: 500
  }, function (tState) {
    return /*#__PURE__*/_react.default.createElement("div", {
      className: bem('scroll-month', [(0, _defineProperty2.default)({}, tState, true)])
    }, scrollDate);
  }));
  (0, _react.useEffect)(function () {
    !isHorizontal && anchor();
  }, [direction, minDate, maxDate]);
  var timer = (0, _react.useRef)();
  (0, _useScroll.default)({
    container: scrollBodyRef,
    onScroll: function onScroll() {
      !scrollIntoView.current && setScrolling(true);

      if (timer.current) {
        clearTimeout(timer.current);
      }

      timer.current = setTimeout(function () {
        setScrolling(false);
        scrollIntoView.current = false;
      }, 250);
    }
  });
  (0, _react.useEffect)(function () {
    setState(_objectSpread(_objectSpread({}, (0, _parseState.default)(props)), {}, {
      step: state.step
    }));
  }, [mode, maxDate, minDate, direction]);
  return /*#__PURE__*/_react.default.createElement("div", {
    className: cls,
    ref: container
  }, showHeader && /*#__PURE__*/_react.default.createElement(_Header.default, {
    changeMonth: function changeMonth(idx) {
      var _carouselRef$current;

      // @ts-ignore
      carouselRef === null || carouselRef === void 0 ? void 0 : (_carouselRef$current = carouselRef.current) === null || _carouselRef$current === void 0 ? void 0 : _carouselRef$current.onSlideTo(idx);
    },
    months: months,
    currentMonth: currentMonth
  }), /*#__PURE__*/_react.default.createElement(_Week.default, {
    ref: weekRef
  }), monthsContent);
});

Calendar.defaultProps = {
  mode: 'single',
  dateRender: function dateRender(date) {
    return date.getDate();
  },
  disabledDate: function disabledDate() {
    return false;
  },
  direction: 'vertical',
  header: false
};
var _default = Calendar;
exports.default = _default;