function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }

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) || _nonIterableRest(); }

function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }

function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_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; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }

function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }

function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }

function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

/*
Copyright (c) 2018-2020 Uber Technologies, Inc.

This source code is licensed under the MIT license found in the
LICENSE file in the root directory of this source tree.
*/
import * as React from 'react';
import ArrowRight from '../icon/arrow-right.js';
import ArrowLeft from '../icon/arrow-left.js';
import TriangleDown from '../icon/triangle-down.js';
import { StatefulMenu } from '../menu/index.js';
import { Popover } from '../popover/index.js';
import { LocaleContext } from '../locale/index.js';
import { ThemeContext } from '../styles/theme-provider.js';
import { StyledCalendarHeader, StyledPrevButton, StyledNextButton, StyledMonthHeader, StyledWeekdayHeader, StyledMonthYearSelectButton, StyledMonthYearSelectIconContainer } from './styled-components.js';
import { addDays, addMonths, getMonth, getMonthInLocale, getStartOfWeek, getWeekdayMinInLocale, getYear, monthDisabledBefore, monthDisabledAfter, setMonth, setYear, subMonths } from './utils/index.js';
import { ORIENTATION, WEEKDAYS } from './constants.js';
import { getOverrides, mergeOverrides } from '../helpers/overrides.js';

var navBtnStyle = function navBtnStyle(_ref) {
  var $theme = _ref.$theme;
  return {
    cursor: 'pointer'
  };
};

var MIN_YEAR = 2000;
var MAX_YEAR = 2030;
var MIN_MONTH = 0;
var MAX_MONTH = 11;
var DIRECTION = {
  NEXT: 'next',
  PREVIOUS: 'previous'
};

function yearMonthToId(year, month) {
  return "".concat(year, "-").concat(month);
}

function idToYearMonth(id) {
  return id.split('-').map(Number);
}

var CalendarHeader =
/*#__PURE__*/
function (_React$Component) {
  _inherits(CalendarHeader, _React$Component);

  function CalendarHeader() {
    var _getPrototypeOf2;

    var _this;

    _classCallCheck(this, CalendarHeader);

    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }

    _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(CalendarHeader)).call.apply(_getPrototypeOf2, [this].concat(args)));

    _defineProperty(_assertThisInitialized(_this), "state", {
      isMonthYearDropdownOpen: false
    });

    _defineProperty(_assertThisInitialized(_this), "handleMonthChange", function (_ref2) {
      var value = _ref2.value;

      if (_this.props.onMonthChange) {
        // $FlowFixMe
        _this.props.onMonthChange({
          date: setMonth(_this.props.date, value[0].id)
        });
      }
    });

    _defineProperty(_assertThisInitialized(_this), "handleYearChange", function (_ref3) {
      var value = _ref3.value;

      if (_this.props.onYearChange) {
        // $FlowFixMe
        _this.props.onYearChange({
          date: setYear(_this.props.date, value[0].id)
        });
      }
    });

    _defineProperty(_assertThisInitialized(_this), "increaseMonth", function () {
      if (_this.props.onMonthChange) {
        // $FlowFixMe
        _this.props.onMonthChange({
          date: addMonths(_this.props.date, 1)
        });
      }
    });

    _defineProperty(_assertThisInitialized(_this), "decreaseMonth", function () {
      if (_this.props.onMonthChange) {
        // $FlowFixMe
        _this.props.onMonthChange({
          date: subMonths(_this.props.date, 1)
        });
      }
    });

    _defineProperty(_assertThisInitialized(_this), "isMultiMonthHorizontal", function () {
      var _this$props = _this.props,
          monthsShown = _this$props.monthsShown,
          orientation = _this$props.orientation;

      if (!monthsShown) {
        return false;
      }

      return orientation === ORIENTATION.horizontal && monthsShown > 1;
    });

    _defineProperty(_assertThisInitialized(_this), "isHiddenPaginationButton", function (direction) {
      var _this$props2 = _this.props,
          monthsShown = _this$props2.monthsShown,
          order = _this$props2.order;

      if (monthsShown && _this.isMultiMonthHorizontal()) {
        if (direction === DIRECTION.NEXT) {
          var isLastMonth = order === monthsShown - 1;
          return !isLastMonth;
        } else {
          var isFirstMonth = order === 0;
          return !isFirstMonth;
        }
      }

      return false;
    });

    _defineProperty(_assertThisInitialized(_this), "renderPreviousMonthButton", function (_ref4) {
      var locale = _ref4.locale,
          theme = _ref4.theme;
      var _this$props3 = _this.props,
          date = _this$props3.date,
          _this$props3$override = _this$props3.overrides,
          overrides = _this$props3$override === void 0 ? {} : _this$props3$override;
      var allPrevDaysDisabled = monthDisabledBefore(date, _this.props);
      var isDisabled = false;

      if (allPrevDaysDisabled) {
        isDisabled = true;
      }

      var nextMonth = subMonths(date, 1);

      if (getYear(nextMonth) < MIN_YEAR) {
        isDisabled = true;
      }

      var isHidden = _this.isHiddenPaginationButton(DIRECTION.PREVIOUS);

      if (isHidden) {
        isDisabled = true;
      }

      var _getOverrides = getOverrides(overrides.PrevButton, StyledPrevButton),
          _getOverrides2 = _slicedToArray(_getOverrides, 2),
          PrevButton = _getOverrides2[0],
          prevButtonProps = _getOverrides2[1];

      var _getOverrides3 = getOverrides(overrides.PrevButtonIcon, theme.direction === 'rtl' ? ArrowRight : ArrowLeft),
          _getOverrides4 = _slicedToArray(_getOverrides3, 2),
          PrevButtonIcon = _getOverrides4[0],
          prevButtonIconProps = _getOverrides4[1];

      var clickHandler = _this.decreaseMonth;

      if (allPrevDaysDisabled) {
        clickHandler = null;
      }

      return React.createElement(PrevButton, _extends({
        "aria-label": locale.datepicker.previousMonth,
        tabIndex: 0,
        onClick: clickHandler,
        disabled: isDisabled,
        $disabled: isDisabled
      }, prevButtonProps), isHidden ? null : React.createElement(PrevButtonIcon, _extends({
        size: '24px',
        overrides: {
          Svg: {
            style: navBtnStyle
          }
        }
      }, prevButtonIconProps)));
    });

    _defineProperty(_assertThisInitialized(_this), "renderNextMonthButton", function (_ref5) {
      var locale = _ref5.locale,
          theme = _ref5.theme;
      var _this$props4 = _this.props,
          date = _this$props4.date,
          _this$props4$override = _this$props4.overrides,
          overrides = _this$props4$override === void 0 ? {} : _this$props4$override;
      var allNextDaysDisabled = monthDisabledAfter(date, _this.props);
      var isDisabled = false;

      if (allNextDaysDisabled) {
        isDisabled = true;
      }

      var nextMonth = addMonths(date, 1);

      if (getYear(nextMonth) > MAX_YEAR) {
        isDisabled = true;
      }

      var isHidden = _this.isHiddenPaginationButton(DIRECTION.NEXT);

      if (isHidden) {
        isDisabled = true;
      }

      var _getOverrides5 = getOverrides(overrides.NextButton, StyledNextButton),
          _getOverrides6 = _slicedToArray(_getOverrides5, 2),
          NextButton = _getOverrides6[0],
          nextButtonProps = _getOverrides6[1];

      var _getOverrides7 = getOverrides(overrides.NextButtonIcon, theme.direction === 'rtl' ? ArrowLeft : ArrowRight),
          _getOverrides8 = _slicedToArray(_getOverrides7, 2),
          NextButtonIcon = _getOverrides8[0],
          nextButtonIconProps = _getOverrides8[1];

      var clickHandler = _this.increaseMonth; // The other option is to always provide a click handler and let customers
      // override its functionality based on the `$allPrevDaysDisabled` prop
      // in a custom NextButton component override
      // Their options would be to render `null` or not apply the components handler
      // on click or do nothing

      if (allNextDaysDisabled) {
        clickHandler = null;
      }

      return React.createElement(NextButton, _extends({
        "aria-label": locale.datepicker.nextMonth,
        tabIndex: 0,
        onClick: clickHandler,
        disabled: isDisabled,
        $disabled: isDisabled
      }, nextButtonProps), isHidden ? null : React.createElement(NextButtonIcon, _extends({
        size: '24px',
        overrides: {
          Svg: {
            style: navBtnStyle
          }
        }
      }, nextButtonIconProps)));
    });

    _defineProperty(_assertThisInitialized(_this), "canArrowsOpenDropdown", function (event) {
      if (!_this.state.isMonthYearDropdownOpen) {
        if (event.key === 'ArrowUp' || event.key === 'ArrowDown') {
          return true;
        }
      }

      return false;
    });

    _defineProperty(_assertThisInitialized(_this), "renderMonthYearDropdown", function () {
      var _this$props5 = _this.props,
          date = _this$props5.date,
          locale = _this$props5.locale,
          maxDate = _this$props5.maxDate,
          minDate = _this$props5.minDate,
          _this$props5$override = _this$props5.overrides,
          overrides = _this$props5$override === void 0 ? {} : _this$props5$override;

      var _getOverrides9 = getOverrides(overrides.MonthYearSelectButton, StyledMonthYearSelectButton),
          _getOverrides10 = _slicedToArray(_getOverrides9, 2),
          MonthYearSelectButton = _getOverrides10[0],
          monthYearSelectButtonProps = _getOverrides10[1];

      var _getOverrides11 = getOverrides(overrides.MonthYearSelectIconContainer, StyledMonthYearSelectIconContainer),
          _getOverrides12 = _slicedToArray(_getOverrides11, 2),
          MonthYearSelectIconContainer = _getOverrides12[0],
          monthYearSelectIconContainerProps = _getOverrides12[1];

      var _getOverrides13 = getOverrides(overrides.MonthYearSelectPopover, Popover),
          _getOverrides14 = _slicedToArray(_getOverrides13, 2),
          OverriddenPopover = _getOverrides14[0],
          popoverProps = _getOverrides14[1];

      var _getOverrides15 = getOverrides(overrides.MonthYearSelectStatefulMenu, StatefulMenu),
          _getOverrides16 = _slicedToArray(_getOverrides15, 2),
          OverriddenStatefulMenu = _getOverrides16[0],
          menuProps = _getOverrides16[1];

      var menuOverrides = mergeOverrides({
        List: {
          style: {
            height: 'auto',
            maxHeight: '257px'
          }
        }
      }, // $FlowFixMe
      menuProps && menuProps.overrides); // $FlowFixMe

      menuProps.overrides = menuOverrides;
      var defaultMonths = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
      var maxYear = maxDate ? getYear(maxDate) : MAX_YEAR;
      var minYear = minDate ? getYear(minDate) : MIN_YEAR;
      var maxDateMonth = maxDate ? getMonth(maxDate) : MAX_MONTH; // Generates array like [0,1,.... maxDateMonth]

      var maxYearMonths = Array.from({
        length: maxDateMonth + 1
      }, function (x, i) {
        return i;
      });
      var minDateMonth = minDate ? getMonth(minDate) : MIN_MONTH; // Generates array like [minDateMonth, ...., 10, 11]

      var minYearMonths = Array.from({
        length: 12 - minDateMonth
      }, function (x, i) {
        return i + minDateMonth;
      });
      var items = [];

      var _loop = function _loop(i) {
        var months = void 0;

        if (i === minYear && i === maxYear) {
          months = maxYearMonths.filter(function (month) {
            return minYearMonths.includes(month);
          });
        } else if (i === minYear) {
          months = minYearMonths;
        } else if (i === maxYear) {
          months = maxYearMonths;
        } else {
          months = defaultMonths;
        }

        months.forEach(function (month) {
          items.push({
            id: yearMonthToId(i, month),
            label: "".concat(getMonthInLocale(month, locale), " ").concat(i)
          });
        });
      };

      for (var i = minYear; i <= maxYear; i++) {
        _loop(i);
      }

      var initialIndex = items.findIndex(function (item) {
        return item.id === yearMonthToId(getYear(date), getMonth(date));
      });
      var monthYearTitle = "".concat(getMonthInLocale(getMonth(date), locale), " ").concat(getYear(date));
      return _this.isMultiMonthHorizontal() ? React.createElement("div", null, monthYearTitle) : React.createElement(OverriddenPopover, _extends({
        placement: "bottom",
        focusLock: false,
        mountNode: _this.props.popoverMountNode,
        isOpen: _this.state.isMonthYearDropdownOpen,
        onClick: function onClick() {
          _this.setState(function (prev) {
            return {
              isMonthYearDropdownOpen: !prev.isMonthYearDropdownOpen
            };
          });
        },
        onClickOutside: function onClickOutside() {
          return _this.setState({
            isMonthYearDropdownOpen: false
          });
        },
        content: function content() {
          return React.createElement(OverriddenStatefulMenu, _extends({
            initialState: {
              highlightedIndex: initialIndex,
              isFocused: true
            },
            items: items,
            onItemSelect: function onItemSelect(_ref6) {
              var item = _ref6.item,
                  event = _ref6.event;
              event.preventDefault();

              var _idToYearMonth = idToYearMonth(item.id),
                  _idToYearMonth2 = _slicedToArray(_idToYearMonth, 2),
                  year = _idToYearMonth2[0],
                  month = _idToYearMonth2[1];

              date.setFullYear(year, month);
              _this.props.onMonthChange && _this.props.onMonthChange({
                date: date
              });
              _this.props.onYearChange && _this.props.onYearChange({
                date: date
              });

              _this.setState({
                isMonthYearDropdownOpen: false
              });
            }
          }, menuProps));
        }
      }, popoverProps), React.createElement(MonthYearSelectButton, _extends({
        onKeyUp: function onKeyUp(event) {
          if (_this.canArrowsOpenDropdown(event)) {
            _this.setState({
              isMonthYearDropdownOpen: true
            });
          }
        },
        onKeyDown: function onKeyDown(event) {
          if (_this.canArrowsOpenDropdown(event)) {
            // disables page scroll
            event.preventDefault();
          }

          if (event.key === 'Tab') {
            _this.setState({
              isMonthYearDropdownOpen: false
            });
          }
        }
      }, monthYearSelectButtonProps), monthYearTitle, React.createElement(MonthYearSelectIconContainer, monthYearSelectIconContainerProps, React.createElement(TriangleDown, null))));
    });

    return _this;
  }

  _createClass(CalendarHeader, [{
    key: "render",
    value: function render() {
      var _this2 = this;

      var _this$props$overrides = this.props.overrides,
          overrides = _this$props$overrides === void 0 ? {} : _this$props$overrides;

      var _getOverrides17 = getOverrides(overrides.CalendarHeader, StyledCalendarHeader),
          _getOverrides18 = _slicedToArray(_getOverrides17, 2),
          CalendarHeader = _getOverrides18[0],
          calendarHeaderProps = _getOverrides18[1];

      var _getOverrides19 = getOverrides(overrides.MonthHeader, StyledMonthHeader),
          _getOverrides20 = _slicedToArray(_getOverrides19, 2),
          MonthHeader = _getOverrides20[0],
          monthHeaderProps = _getOverrides20[1];

      var _getOverrides21 = getOverrides(overrides.WeekdayHeader, StyledWeekdayHeader),
          _getOverrides22 = _slicedToArray(_getOverrides21, 2),
          WeekdayHeader = _getOverrides22[0],
          weekdayHeaderProps = _getOverrides22[1];

      var startOfWeek = getStartOfWeek(this.props.date, this.props.locale);
      return React.createElement(ThemeContext.Consumer, null, function (theme) {
        return React.createElement(LocaleContext.Consumer, null, function (locale) {
          return React.createElement(React.Fragment, null, React.createElement(CalendarHeader, calendarHeaderProps, _this2.renderPreviousMonthButton({
            locale: locale,
            theme: theme
          }), _this2.renderMonthYearDropdown(), _this2.renderNextMonthButton({
            locale: locale,
            theme: theme
          })), React.createElement(MonthHeader, _extends({
            role: "presentation"
          }, monthHeaderProps), WEEKDAYS.map(function (offset) {
            var day = addDays(startOfWeek, offset);
            return React.createElement(WeekdayHeader, _extends({
              key: offset
            }, weekdayHeaderProps), getWeekdayMinInLocale(day, _this2.props.locale));
          })));
        });
      });
    }
  }]);

  return CalendarHeader;
}(React.Component);

_defineProperty(CalendarHeader, "defaultProps", {
  date: new Date(),
  locale: null,
  maxDate: null,
  minDate: null,
  onYearChange: function onYearChange() {},
  overrides: {}
});

export { CalendarHeader as default };