import _extends from "@babel/runtime/helpers/extends";
import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized";
import _inheritsLoose from "@babel/runtime/helpers/inheritsLoose";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import React from 'react';
import PropTypes from 'prop-types';
import BSFormControl from 'react-bootstrap/lib/FormControl';
import classnames from 'classnames';
import { Icon } from '../../Icon';
import _ from 'lodash';
import { isElementFocused } from './datePickerHelpers';
import { FormControl } from '../FormControl';
import OutsideClickHandler from 'react-outside-click-handler';
import { KeyNames } from '../../../../utils/constants';
import { translate } from '../../../../utils';
import { wait } from '../../../utils/functions';

var toFnWithDate = function toFnWithDate(str) {
  return function (_ref) {
    var date = _ref.date;
    return translate(str, {
      date: date
    });
  };
};

var instanceCounter = 0;
var WAIT_TIME_OUT_WHEN_BLUR = 150;
export var DatePickerBase =
/*#__PURE__*/
function (_FormControl) {
  _inheritsLoose(DatePickerBase, _FormControl);

  function DatePickerBase(props, ctx) {
    var _this;

    _this = _FormControl.call(this, props, ctx) || this;

    _defineProperty(_assertThisInitialized(_this), "calendarContainer", null);

    _defineProperty(_assertThisInitialized(_this), "onKeyDown", _.throttle(function (event) {
      switch (event.key) {
        case KeyNames.ArrowDown:
          _this.onInputKeyDownArrowDown();

          break;

        case KeyNames.Escape:
        case KeyNames.Tab:
          _this.closeDayPicker();

          break;

        default:
          break;
      }
    }));

    _defineProperty(_assertThisInitialized(_this), "onCalendarKeyUp", _.throttle(function (event) {
      if (event.key === KeyNames.Escape) {
        _this.closeDayPicker();

        _this.focusToInput();
      }
    }));

    _defineProperty(_assertThisInitialized(_this), "isPreventCloseDayPickerOnBlur", false);

    _defineProperty(_assertThisInitialized(_this), "onInputKeyDownArrowDown", function () {
      _this.showDayPicker();

      _this.focusOnDateCell();
    });

    _defineProperty(_assertThisInitialized(_this), "focusOnDateCell", function () {
      return _this.setStatePromise({
        isDayPickerFocused: false
      }).then(function () {
        return _this.setStatePromise({
          isDayPickerFocused: true
        });
      });
    });

    _defineProperty(_assertThisInitialized(_this), "blurDateCell", function () {
      return _this.setStatePromise({
        isDayPickerFocused: false
      });
    });

    _defineProperty(_assertThisInitialized(_this), "setStatePromise", function (state) {
      return new Promise(function (resolve) {
        _this.setState(state, resolve);
      });
    });

    _defineProperty(_assertThisInitialized(_this), "showDayPicker", function () {
      if (!_this.state.isDayPickerVisible) {
        _this.setState({
          isDayPickerVisible: true,
          isDayPickerFocused: false
        });
      }
    });

    _defineProperty(_assertThisInitialized(_this), "handleFocusInput", function () {
      var isInputFocusedFromOutside = _this.state.isInputFocusedFromOutside;

      if (isInputFocusedFromOutside) {
        _this.showDayPicker();
      }
    });

    _defineProperty(_assertThisInitialized(_this), "handleToggleDayPickerDisplay", function (e) {
      if (!_.isEmpty(e)) {
        e.stopPropagation();
      }

      var isDayPickerVisible = _this.state.isDayPickerVisible;

      if (isDayPickerVisible) {
        _this.closeDayPicker();
      } else {
        _this.showDayPicker();
      }
    });

    _defineProperty(_assertThisInitialized(_this), "isFocusedInsideDayPickerContainer", function () {
      return isElementFocused(_this.calendarContainer);
    });

    _defineProperty(_assertThisInitialized(_this), "focusToInput", function () {
      return _this.focus();
    });

    _defineProperty(_assertThisInitialized(_this), "handleBlurDatePickerControl", function () {
      wait(WAIT_TIME_OUT_WHEN_BLUR).then(function () {
        if (!_this.isPreventCloseDayPickerOnBlur && !_this.isFocusedInsideDayPickerContainer()) {
          _this.toggleIsInputFocusedFromOutside(true);

          _this.closeDayPicker();
        }
      });
    });

    _defineProperty(_assertThisInitialized(_this), "toggleIsInputFocusedFromOutside", function (isInputFocusedFromOutside) {
      return _this.setStatePromise({
        isInputFocusedFromOutside: isInputFocusedFromOutside
      });
    });

    _defineProperty(_assertThisInitialized(_this), "handleMouseDownPreventCloseDayPicker", function () {
      _this.isPreventCloseDayPickerOnBlur = true;
    });

    _defineProperty(_assertThisInitialized(_this), "handleCloseDayPickerOnBlur", function () {
      _this.isPreventCloseDayPickerOnBlur = false;
    });

    _defineProperty(_assertThisInitialized(_this), "setContainerRef", function (el) {
      return _this.calendarContainer = el;
    });

    _defineProperty(_assertThisInitialized(_this), "handleOutsideClick", function () {
      _this.toggleIsInputFocusedFromOutside(true);

      _this.closeDayPicker();
    });

    _defineProperty(_assertThisInitialized(_this), "getDisplayValue", function () {
      return null;
    });

    _defineProperty(_assertThisInitialized(_this), "handleMouseUpDayPickerContainer", function () {});

    _defineProperty(_assertThisInitialized(_this), "handlePreventDefault", function (e) {
      return e.preventDefault();
    });

    _this.state = {
      isDayPickerFocused: false,
      isDayPickerVisible: false,
      isPreventDayPickerClosed: false,
      isInputFocusedFromOutside: true
    };
    _this.instanceId = instanceCounter++;
    return _this;
  }

  var _proto = DatePickerBase.prototype;

  _proto.componentDidMount = function componentDidMount() {
    var _this2 = this;

    this.setState({
      isInputFocusedFromOutside: true
    });
    this.calendarContainer.addEventListener('keydown', function (event) {
      if (_this2.state.isDayPickerVisible && event.key === KeyNames.Escape) {
        event.stopPropagation();
      }
    });
  };

  _proto.closeDayPicker = function closeDayPicker() {
    return this.setStatePromise({
      isDayPickerVisible: false,
      isDayPickerFocused: false
    });
  };

  /** @abstract */
  _proto.getDatePickerContainerClassName = function getDatePickerContainerClassName() {
    return '';
  }
  /** @abstract */
  ;

  _proto.renderDatePicker = function renderDatePicker() {
    return null;
  }
  /** @abstract */
  ;

  /** @abstract */
  _proto.getPhrases = function getPhrases() {
    var _this$props$dayPicker = this.props.dayPickerPhrase,
        calendarLabel = _this$props$dayPicker.calendarLabel,
        closeDatePicker = _this$props$dayPicker.closeDatePicker,
        focusStartDate = _this$props$dayPicker.focusStartDate,
        clearDate = _this$props$dayPicker.clearDate,
        clearDates = _this$props$dayPicker.clearDates,
        jumpToPrevMonth = _this$props$dayPicker.jumpToPrevMonth,
        jumpToNextMonth = _this$props$dayPicker.jumpToNextMonth,
        keyboardShortcuts = _this$props$dayPicker.keyboardShortcuts,
        showKeyboardShortcutsPanel = _this$props$dayPicker.showKeyboardShortcutsPanel,
        hideKeyboardShortcutsPanel = _this$props$dayPicker.hideKeyboardShortcutsPanel,
        openThisPanel = _this$props$dayPicker.openThisPanel,
        enterKey = _this$props$dayPicker.enterKey,
        leftArrowRightArrow = _this$props$dayPicker.leftArrowRightArrow,
        upArrowDownArrow = _this$props$dayPicker.upArrowDownArrow,
        pageUpPageDown = _this$props$dayPicker.pageUpPageDown,
        homeEnd = _this$props$dayPicker.homeEnd,
        escape = _this$props$dayPicker.escape,
        questionMark = _this$props$dayPicker.questionMark,
        selectFocusedDate = _this$props$dayPicker.selectFocusedDate,
        moveFocusByOneDay = _this$props$dayPicker.moveFocusByOneDay,
        moveFocusByOneWeek = _this$props$dayPicker.moveFocusByOneWeek,
        moveFocusByOneMonth = _this$props$dayPicker.moveFocusByOneMonth,
        moveFocustoStartAndEndOfWeek = _this$props$dayPicker.moveFocustoStartAndEndOfWeek,
        returnFocusToInput = _this$props$dayPicker.returnFocusToInput,
        keyboardNavigationInstructions = _this$props$dayPicker.keyboardNavigationInstructions,
        chooseAvailableDate = _this$props$dayPicker.chooseAvailableDate,
        chooseAvailableStartDate = _this$props$dayPicker.chooseAvailableStartDate,
        chooseAvailableEndDate = _this$props$dayPicker.chooseAvailableEndDate,
        dateIsUnavailable = _this$props$dayPicker.dateIsUnavailable,
        dateIsSelected = _this$props$dayPicker.dateIsSelected;
    var phrases = {
      calendarLabel: calendarLabel,
      closeDatePicker: closeDatePicker,
      focusStartDate: focusStartDate,
      clearDate: clearDate,
      clearDates: clearDates,
      jumpToPrevMonth: jumpToPrevMonth,
      jumpToNextMonth: jumpToNextMonth,
      keyboardShortcuts: keyboardShortcuts,
      showKeyboardShortcutsPanel: showKeyboardShortcutsPanel,
      hideKeyboardShortcutsPanel: hideKeyboardShortcutsPanel,
      openThisPanel: openThisPanel,
      enterKey: enterKey,
      leftArrowRightArrow: leftArrowRightArrow,
      upArrowDownArrow: upArrowDownArrow,
      pageUpPageDown: pageUpPageDown,
      homeEnd: homeEnd,
      escape: escape,
      questionMark: questionMark,
      selectFocusedDate: selectFocusedDate,
      moveFocusByOneDay: moveFocusByOneDay,
      moveFocusByOneWeek: moveFocusByOneWeek,
      moveFocusByOneMonth: moveFocusByOneMonth,
      moveFocustoStartAndEndOfWeek: moveFocustoStartAndEndOfWeek,
      returnFocusToInput: returnFocusToInput,
      keyboardNavigationInstructions: keyboardNavigationInstructions,
      chooseAvailableDate: toFnWithDate(chooseAvailableDate),
      chooseAvailableStartDate: toFnWithDate(chooseAvailableStartDate),
      chooseAvailableEndDate: toFnWithDate(chooseAvailableEndDate),
      dateIsUnavailable: toFnWithDate(dateIsUnavailable),
      dateIsSelected: toFnWithDate(dateIsSelected)
    };

    _.forEach(phrases, function (value, key) {
      if (value === undefined) {
        phrases[key] = DatePickerBase.defaultProps[key];
      }
    });

    return phrases;
  }
  /** @abstract */
  ;

  _proto.render = function render() {
    var _this$props = this.props,
        testAutomationId = _this$props.testAutomationId,
        disabled = _this$props.disabled,
        inputProps = _this$props.inputProps,
        dayPickerPhrase = _this$props.dayPickerPhrase,
        ariaLabel = _this$props.ariaLabel;
    var keyboardNavigationInstructions = dayPickerPhrase.keyboardNavigationInstructions;
    var ariaDescribeId = "date-picker-input-describe-message-" + this.instanceId;
    return React.createElement(OutsideClickHandler, {
      onOutsideClick: this.handleOutsideClick
    }, React.createElement("div", {
      ref: this.setContainerRef,
      "data-test-automation-id": testAutomationId,
      className: classnames('rc-datepicker', {
        'rc-datepicker-disabled': disabled
      }),
      onMouseDown: this.handleMouseDownPreventCloseDayPicker,
      onKeyDown: this.handleCloseDayPickerOnBlur,
      onKeyUp: this.handleCloseDayPickerOnBlur,
      onBlur: this.handleBlurDatePickerControl
    }, React.createElement(Icon, {
      name: "calendar",
      onClick: this.handleToggleDayPickerDisplay
    }), React.createElement(BSFormControl, _extends({
      onKeyDown: this.onKeyDown,
      onFocus: this.handleFocusInput,
      type: "text",
      ref: "input",
      value: this.getDisplayValue(),
      onChange: this.handlePreventDefault,
      "aria-describedby": ariaDescribeId,
      "aria-label": ariaLabel
    }, inputProps)), React.createElement("p", {
      className: "sr-only",
      id: ariaDescribeId
    }, keyboardNavigationInstructions), React.createElement("div", {
      "data-test-automation-id": "datePickerContainer",
      className: "rc-datepicker-container " + this.getDatePickerContainerClassName(),
      onKeyUp: this.onCalendarKeyUp,
      onMouseUp: this.handleMouseUpDayPickerContainer
    }, this.renderDatePicker())));
  };

  return DatePickerBase;
}(FormControl);

_defineProperty(DatePickerBase, "propTypes", Object.assign({}, FormControl.propTypes, {
  inputProps: PropTypes.object,
  ariaLabel: PropTypes.string,
  disabled: PropTypes.bool,
  testAutomationId: PropTypes.string.isRequired,
  dayPickerPhrase: PropTypes.object
}));

_defineProperty(DatePickerBase, "defaultProps", Object.assign({}, FormControl.defaultProps, {
  ariaLabel: null,
  dayPickerPhrase: {
    calendarLabel: 'TRANSLATE:DATEPICKER_PHRASE_CALENDAR_LABEL',
    closeDatePicker: 'TRANSLATE:DATEPICKER_PHRASE_CLOSE_DATE_PICKER',
    focusStartDate: 'TRANSLATE:DATEPICKER_PHRASE_FOCUS_START_DATE',
    clearDate: 'TRANSLATE:DATEPICKER_PHRASE_CLEAR_DATE',
    clearDates: 'TRANSLATE:DATEPICKER_PHRASE_CLEAR_DATES',
    jumpToPrevMonth: 'TRANSLATE:DATEPICKER_PHRASE_JUMP_TO_PREV_MONTH',
    jumpToNextMonth: 'TRANSLATE:DATEPICKER_PHRASE_JUMP_TO_NEXT_MONTH',
    keyboardShortcuts: 'TRANSLATE:DATEPICKER_PHRASE_KEYBOARD_SHORTCUTS',
    showKeyboardShortcutsPanel: 'TRANSLATE:DATEPICKER_PHRASE_SHOW_KEYBOARD_SHORTCUTS_PANEL',
    hideKeyboardShortcutsPanel: 'TRANSLATE:DATEPICKER_PHRASE_HIDE_KEYBOARD_SHORTCUTS_PANEL',
    openThisPanel: 'TRANSLATE:DATEPICKER_PHRASE_OPEN_THIS_PANEL',
    enterKey: 'TRANSLATE:DATEPICKER_PHRASE_ENTER_KEY',
    leftArrowRightArrow: 'TRANSLATE:DATEPICKER_PHRASE_LEFT_ARROW_RIGHT_ARROW',
    upArrowDownArrow: 'TRANSLATE:DATEPICKER_PHRASE_UP_ARROW_DOWN_ARROW',
    pageUpPageDown: 'TRANSLATE:DATEPICKER_PHRASE_PAGE_UP_PAGE_DOWN',
    homeEnd: 'TRANSLATE:DATEPICKER_PHRASE_HOME_END',
    escape: 'TRANSLATE:DATEPICKER_PHRASE_ESCAPE',
    questionMark: 'TRANSLATE:DATEPICKER_PHRASE_QUESTION_MARK',
    selectFocusedDate: 'TRANSLATE:DATEPICKER_PHRASE_SELECT_FOCUSED_DATE',
    moveFocusByOneDay: 'TRANSLATE:DATEPICKER_PHRASE_MOVE_FOCUS_BY_ONE_DAY',
    moveFocusByOneWeek: 'TRANSLATE:DATEPICKER_PHRASE_MOVE_FOCUS_BY_ONE_WEEK',
    moveFocusByOneMonth: 'TRANSLATE:DATEPICKER_PHRASE_MOVE_FOCUS_BY_ONE_MONTH',
    moveFocustoStartAndEndOfWeek: 'TRANSLATE:DATEPICKER_PHRASE_MOVE_FOCUSTO_START_AND_END_OF_WEEK',
    returnFocusToInput: 'TRANSLATE:DATEPICKER_PHRASE_RETURN_FOCUS_TO_INPUT',
    keyboardNavigationInstructions: 'TRANSLATE:DATEPICKER_PHRASE_KEYBOARD_NAVIGATION_INSTRUCTIONS',
    chooseAvailableDate: 'TRANSLATE:DATEPICKER_PHRASE_CHOOSE_AVAILABLE_DATE',
    chooseAvailableStartDate: 'TRANSLATE:DATEPICKER_PHRASE_CHOOSE_AVAILABLE_START_DATE',
    chooseAvailableEndDate: 'TRANSLATE:DATEPICKER_PHRASE_CHOOSE_AVAILABLE_ENDDATE',
    dateIsUnavailable: 'TRANSLATE:DATEPICKER_PHRASE_DATE_IS_UNAVAILABLE',
    dateIsSelected: 'TRANSLATE:DATEPICKER_PHRASE_DATE_IS_SELECTED'
  }
}));