function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }

function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }

function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }

function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }

function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }

function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }

function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }

import { __rest } from "tslib";
import React, { createElement, forwardRef, useState, createRef } from "react";
import classNames from 'classnames';
import dayjs from 'dayjs';
import { Slider as ReactSlider } from "@alifd/meet-react-component-one";
import View from '../view';
import CalendarContent from './content';
import CalendarHeader from './header';
import CalendarTimePicker from './time-picker';
import { useLocale } from '../locale';
import { HeaderType } from './types';
import { isValidDate, toDate } from '../utils/date';
import { cloneDate, genContentHeight, getMaxMinDate, getTargetDate, NOW, genTotalPageDates, getSelectedIndex } from './utils';
var defaultLocale = {
  weekdays: ['日', '一', '二', '三', '四', '五', '六'],
  months: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
  year: '年',
  month: '月',
  day: '日',
  timePickerLabel: '选择时间'
};

function formatValue(value) {
  if (!value) {
    return undefined;
  }

  if (Array.isArray(value)) {
    return value.map(function (it) {
      return toDate(it);
    });
  }

  return toDate(value);
}

var Calendar = function Calendar(props, ref) {
  var _props$prefix = props.prefix,
      prefix = _props$prefix === void 0 ? 'mt-' : _props$prefix,
      defaultValue = props.defaultValue,
      value = props.value,
      _props$shape = props.shape,
      shape = _props$shape === void 0 ? 'panel' : _props$shape,
      _props$mode = props.mode,
      mode = _props$mode === void 0 ? 'month' : _props$mode,
      validRange = props.validRange,
      _props$onSelect = props.onSelect,
      onSelect = _props$onSelect === void 0 ? function () {} : _props$onSelect,
      dateCellRender = props.dateCellRender,
      monthCellRender = props.monthCellRender,
      disabledDate = props.disabledDate,
      _onModeChange = props.onModeChange,
      _props$needSlider = props.needSlider,
      needSlider = _props$needSlider === void 0 ? false : _props$needSlider,
      _props$enableYearPick = props.enableYearPicker,
      enableYearPicker = _props$enableYearPick === void 0 ? false : _props$enableYearPick,
      _props$enableTimePick = props.enableTimePicker,
      enableTimePicker = _props$enableTimePick === void 0 ? false : _props$enableTimePick,
      _props$timeFormat = props.timeFormat,
      timeFormat = _props$timeFormat === void 0 ? 'HH:mm:ss' : _props$timeFormat,
      _props$sliderHeight = props.sliderHeight,
      sliderHeight = _props$sliderHeight === void 0 ? genContentHeight(mode) : _props$sliderHeight,
      _props$sliderWidth = props.sliderWidth,
      sliderWidth = _props$sliderWidth === void 0 ? '750' : _props$sliderWidth,
      renderCellBottom = props.renderCellBottom,
      renderCellRight = props.renderCellRight,
      renderHeadLeft = props.renderHeadLeft,
      renderHeadRight = props.renderHeadRight,
      firstDay = props.firstDay,
      fixSliderNumber = props.fixSliderNumber,
      others = __rest(props, ["prefix", "defaultValue", "value", "shape", "mode", "validRange", "onSelect", "dateCellRender", "monthCellRender", "disabledDate", "onModeChange", "needSlider", "enableYearPicker", "enableTimePicker", "timeFormat", "sliderHeight", "sliderWidth", "renderCellBottom", "renderCellRight", "renderHeadLeft", "renderHeadRight", "firstDay", "fixSliderNumber"]);

  var genInitVisibleDate = function genInitVisibleDate(sValue) {
    var date = NOW;

    if (sValue) {
      if (Array.isArray(sValue)) {
        if (sValue.length > 0) {
          date = sValue[0];
        }
      } else {
        date = sValue;
      }
    }

    if (firstDay && mode === 'week') {
      var tempDay = dayjs(date).day(firstDay);
      date = new Date(tempDay.valueOf());
    }

    return cloneDate(date);
  };

  var genInitSelectedDate = function genInitSelectedDate(sValue, dValue, vShape) {
    var tempSDate = sValue || dValue;

    if (tempSDate) {
      return tempSDate;
    }

    if (vShape === 'range') {
      return [];
    }

    if (vShape === 'multi') {
      return [];
    }

    return null;
  };

  var locale = useLocale('Calendar', others, defaultLocale);
  var selectedDate = genInitSelectedDate(formatValue(value), formatValue(defaultValue), shape);

  var _useState = useState(mode),
      _useState2 = _slicedToArray(_useState, 2),
      currentMode = _useState2[0],
      changeCurrentMode = _useState2[1];

  var _useState3 = useState(genInitVisibleDate(selectedDate)),
      _useState4 = _slicedToArray(_useState3, 2),
      visibleDate = _useState4[0],
      changeVisibleDate = _useState4[1];

  var _getMaxMinDate = getMaxMinDate(validRange),
      _getMaxMinDate2 = _slicedToArray(_getMaxMinDate, 2),
      minDate = _getMaxMinDate2[0],
      maxDate = _getMaxMinDate2[1];

  var _useState5 = useState(getTargetDate(mode, visibleDate, 'pre', maxDate, minDate)),
      _useState6 = _slicedToArray(_useState5, 2),
      preVisibleDate = _useState6[0],
      changePreVisibleDate = _useState6[1];

  var _useState7 = useState(visibleDate),
      _useState8 = _slicedToArray(_useState7, 2),
      currentVisibleDate = _useState8[0],
      changeCurrentVisibleDate = _useState8[1];

  var _useState9 = useState(getTargetDate(mode, visibleDate, 'next', maxDate, minDate)),
      _useState10 = _slicedToArray(_useState9, 2),
      nextVisibleDate = _useState10[0],
      changeNextVisibleDate = _useState10[1];

  var totalPageDates = fixSliderNumber ? genTotalPageDates(minDate, maxDate, mode, visibleDate, firstDay) : [];
  var defaultIndex = getSelectedIndex(totalPageDates, visibleDate);

  var _useState11 = useState(defaultIndex),
      _useState12 = _slicedToArray(_useState11, 2),
      currentPage = _useState12[0],
      changeCurrentPage = _useState12[1];

  var _useState13 = useState(false),
      _useState14 = _slicedToArray(_useState13, 2),
      showYearPicker = _useState14[0],
      setYearPickerShow = _useState14[1];

  var _useState15 = useState(false),
      _useState16 = _slicedToArray(_useState15, 2),
      showTimePicker = _useState16[0],
      setTimePickerShow = _useState16[1];

  var sliderRef = /*#__PURE__*/createRef();
  var showTimePickerNode = enableTimePicker && mode === 'month' && shape === 'panel' && !needSlider;

  if (showTimePickerNode && !selectedDate) {
    selectedDate = new Date();
  }

  var renderContent = function renderContent() {
    return renderContentWithVisibleDate(visibleDate);
  };

  var renderContentWithVisibleDate = function renderContentWithVisibleDate(visibleD) {
    var shapeContentMap = {
      fullscreen: 'fullscreen',
      range: 'range',
      multi: 'multi'
    };
    var contentType = shapeContentMap[shape] || 'normal';
    return /*#__PURE__*/React.createElement(CalendarContent, {
      prefix: prefix,
      selectedDate: selectedDate,
      visibleDate: visibleD,
      type: contentType,
      firstDay: firstDay,
      mode: _onModeChange ? mode : currentMode,
      enableTimePicker: showTimePickerNode,
      onDateChange: function onDateChange(newValue, clickedItem) {
        if (!onSelect) {
          return;
        }

        if (showTimePickerNode) {
          var _d = selectedDate ? dayjs(selectedDate) : dayjs(new Date());

          var h = _d.hour();

          var m = _d.minute();

          var s = _d.second();

          var newDate = dayjs(newValue).hour(h).minute(m).second(s);
          onSelect(newDate.toDate());
        } else {
          onSelect(newValue);
        }
      },
      maxDate: maxDate,
      minDate: minDate,
      disabledDate: disabledDate,
      locale: locale,
      renderCellBottom: renderCellBottom,
      renderCellRight: renderCellRight,
      dateCellRender: dateCellRender,
      monthCellRender: monthCellRender
    });
  };

  var getShapeType = function getShapeType() {
    var headerType = HeaderType.normal;

    if (shape === 'fullscreen' || shape === 'card' && mode !== 'week') {
      headerType = HeaderType.select;
    }

    return headerType;
  };

  var renderHeader = function renderHeader() {
    return /*#__PURE__*/React.createElement(CalendarHeader, {
      prefix: prefix,
      date: visibleDate,
      maxDate: maxDate,
      minDate: minDate,
      enableYearPicker: enableYearPicker && !needSlider,
      enableTimePicker: showTimePickerNode,
      mode: _onModeChange ? mode : currentMode,
      type: getShapeType(),
      locale: locale,
      renderHeadLeft: renderHeadLeft,
      renderHeadRight: renderHeadRight,
      onPickerShow: function onPickerShow(show) {
        setYearPickerShow(show);
      },
      onModeChange: function onModeChange(v) {
        if (_onModeChange) {
          _onModeChange(v);

          return;
        }

        changeCurrentMode(v);
      },
      onDateChange: function onDateChange(date, isAdd, changeMode) {
        if (changeMode === 'picker') {
          var d = dayjs(date);
          var y = d.year();
          var m = d.month();
          var firstDayOfMonth = dayjs("".concat(y, "-").concat(m + 1, "-01"));
          var day = isValidDate(selectedDate) ? dayjs(selectedDate).date() : 1;

          if (firstDayOfMonth.daysInMonth() < day) {
            day = firstDayOfMonth.daysInMonth();
          }

          if (shape !== 'range' && shape !== 'multi') {
            onSelect(dayjs("".concat(y, "-").concat(m + 1, "-").concat(day)).toDate());
          }

          changeVisibleDate(date);
          return;
        }

        if (fixSliderNumber) {
          var sliderIndex = currentPage;

          if (isAdd) {
            sliderIndex = sliderIndex + 1;
          } else {
            sliderIndex = sliderIndex - 1;
          }

          if (sliderIndex >= 0 && sliderIndex <= totalPageDates.length - 1) {
            sliderRef.current.slideTo(sliderIndex);
          }

          return;
        }

        changeVisibleDate(date);
        var newPre;
        var newCurrent;
        var newNext;

        if (isAdd) {
          newPre = getTargetDate(changeMode, preVisibleDate, 'next', maxDate, minDate);
          newCurrent = getTargetDate(changeMode, currentVisibleDate, 'next', maxDate, minDate);
          newNext = getTargetDate(changeMode, nextVisibleDate, 'next', maxDate, minDate);
        } else {
          newPre = getTargetDate(changeMode, preVisibleDate, 'pre', maxDate, minDate);
          newCurrent = getTargetDate(changeMode, currentVisibleDate, 'pre', maxDate, minDate);
          newNext = getTargetDate(changeMode, nextVisibleDate, 'pre', maxDate, minDate);
        }

        changeCurrentVisibleDate(newCurrent);
        changePreVisibleDate(newPre);
        changeNextVisibleDate(newNext);
      }
    });
  };

  var genSliderItems = function genSliderItems() {
    var preItem = /*#__PURE__*/React.createElement(ReactSlider.Item, {
      key: "Slider.Item.0"
    }, renderContentWithVisibleDate(preVisibleDate));
    var currentItem = /*#__PURE__*/React.createElement(ReactSlider.Item, {
      key: "Slider.Item.1"
    }, renderContentWithVisibleDate(currentVisibleDate));
    var nextItem = /*#__PURE__*/React.createElement(ReactSlider.Item, {
      key: "Slider.Item.2"
    }, renderContentWithVisibleDate(nextVisibleDate));
    return [preItem, currentItem, nextItem];
  };

  var dealSliderChange = function dealSliderChange(oldIndex, newIndex) {
    if (oldIndex === newIndex) {
      return;
    }

    var newVisible;
    var newPre = preVisibleDate;
    var newCurrent = currentVisibleDate;
    var newNext = nextVisibleDate;

    if (oldIndex === 2 && newIndex === 0) {
      newVisible = getTargetDate(mode, visibleDate, 'next', maxDate, minDate);
      newCurrent = getTargetDate(mode, newVisible, 'next', maxDate, minDate);
    } else {
      if (oldIndex === 0 && newIndex === 2) {
        newVisible = getTargetDate(mode, visibleDate, 'pre', maxDate, minDate);
        newCurrent = getTargetDate(mode, newVisible, 'pre', maxDate, minDate);
      } else {
        if (newIndex > oldIndex) {
          newVisible = getTargetDate(mode, visibleDate, 'next', maxDate, minDate);

          if (newIndex === 1) {
            newNext = getTargetDate(mode, newVisible, 'next', maxDate, minDate);
          }

          if (newIndex === 2) {
            newPre = getTargetDate(mode, newVisible, 'next', maxDate, minDate);
          }
        }

        if (newIndex < oldIndex) {
          newVisible = getTargetDate(mode, visibleDate, 'pre', maxDate, minDate);

          if (newIndex === 0) {
            newNext = getTargetDate(mode, newVisible, 'pre', maxDate, minDate);
          }

          if (newIndex === 1) {
            newPre = getTargetDate(mode, newVisible, 'pre', maxDate, minDate);
          }
        }
      }
    }

    changeVisibleDate(newVisible);
    changeCurrentVisibleDate(newCurrent);
    changeNextVisibleDate(newNext);
    changePreVisibleDate(newPre);
  };

  var renderFixSliderContent = function renderFixSliderContent() {
    var items = [];

    for (var i = 0; i < totalPageDates.length; i++) {
      items.push( /*#__PURE__*/React.createElement(ReactSlider.Item, {
        key: 'Slider.Item.' + 'i'
      }, renderContentWithVisibleDate(totalPageDates[i])));
    }

    return /*#__PURE__*/React.createElement(ReactSlider, {
      ref: sliderRef,
      autoPlay: false,
      showsPagination: false,
      index: defaultIndex,
      loop: false,
      width: sliderWidth,
      height: sliderHeight,
      direction: "horizontal",
      onChange: function onChange(index) {
        changeCurrentPage(index.index);
      }
    }, items);
  };

  var renderSliderContent = function renderSliderContent() {
    if (fixSliderNumber) {
      return renderFixSliderContent();
    }

    return /*#__PURE__*/React.createElement(ReactSlider, {
      autoPlay: false,
      showsPagination: false,
      index: 1,
      width: sliderWidth,
      height: sliderHeight,
      direction: "horizontal",
      onChange: function onChange(index) {
        dealSliderChange(currentPage, index.index);
        changeCurrentPage(index.index);
      }
    }, genSliderItems());
  };

  var renderCalendar = function renderCalendar() {
    var s = getShapeType();

    if (needSlider && s === 'normal') {
      return renderSliderContent();
    }

    return renderContent();
  };

  var handleTimePickerToggle = function handleTimePickerToggle(show) {
    setTimePickerShow(show);
  };

  return /*#__PURE__*/React.createElement(View, _extends({
    ref: ref
  }, others, {
    className: classNames("".concat(prefix, "calendar"), "".concat(prefix, "calendar-").concat(shape), "".concat(prefix, "calendar-").concat(shape, "-").concat(currentMode))
  }), !showTimePicker ? renderHeader() : null, !showYearPicker && !showTimePicker ? renderCalendar() : null, showTimePickerNode && !showYearPicker && /*#__PURE__*/React.createElement(CalendarTimePicker, {
    value: selectedDate,
    format: timeFormat,
    label: locale.timePickerLabel,
    onPickerToggle: handleTimePickerToggle,
    onChange: function onChange(date) {
      if (onSelect) {
        onSelect(date);
      }
    }
  }));
};

export default /*#__PURE__*/forwardRef(Calendar);