'use strict';

import _extends from "@babel/runtime/helpers/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/objectWithoutPropertiesLoose";
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 ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { isEmpty } from 'lodash';
import Nav from 'react-bootstrap/lib/Nav';
import { KeyCodes } from '../../utils/constants';
import { NavDropdown, TabItem } from '../index';
import { cleanEmptyChildren, isElementHasType } from '../utils/functions';
export var TAB_PANEL_STYLES = {
  TABS: 'tabs',
  PILLS: 'pills',
  MENU: 'menu'
};
export var TAB_PANEL_ITEM_ROLES = {
  menuitem: 'menuitem',
  tab: 'tab'
};
export var TabPanel =
/*#__PURE__*/
function (_React$Component) {
  _inheritsLoose(TabPanel, _React$Component);

  function TabPanel() {
    var _this;

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

    _this = _React$Component.call.apply(_React$Component, [this].concat(args)) || this;

    _defineProperty(_assertThisInitialized(_this), "state", {
      focusedItemIndex: 0,
      isDropdownOpen: false
    });

    _defineProperty(_assertThisInitialized(_this), "isStyledAsTab", function () {
      var _this$props = _this.props,
          bsStyle = _this$props.bsStyle,
          activeKey = _this$props.activeKey;
      return bsStyle === TAB_PANEL_STYLES.TABS || activeKey || activeKey === 0;
    });

    _defineProperty(_assertThisInitialized(_this), "setFocusedItemByIndex", function (index) {
      var rawChildren = _this.props.children;
      var children = cleanEmptyChildren(rawChildren);

      if (index !== -1 && !children[index].props.disabled) {
        _this.setState({
          focusedItemIndex: index
        });
      }
    });

    _defineProperty(_assertThisInitialized(_this), "handleClick", function (event) {
      var rawChildren = _this.props.children;
      var children = cleanEmptyChildren(rawChildren);
      var tabPanelNode = ReactDOM.findDOMNode(_assertThisInitialized(_this));
      var childNode = event.target.parentNode;
      var index = TabPanel.getChildIndex(tabPanelNode, childNode);

      _this.setFocusedItemByIndex(index);

      if (!TabPanel.isItemOfDropdownType(children[index])) {
        _this.setState({
          isDropdownOpen: false
        });
      }
    });

    _defineProperty(_assertThisInitialized(_this), "handleKeyDown", function (event) {
      var rawChildren = _this.props.children;
      var children = cleanEmptyChildren(rawChildren);
      var _this$state = _this.state,
          focusedItemIndex = _this$state.focusedItemIndex,
          isDropdownOpen = _this$state.isDropdownOpen;
      var focusedTab = children[focusedItemIndex];

      switch (event.keyCode) {
        case KeyCodes.ARROW_LEFT:
        case KeyCodes.ARROW_UP:
          if (!isDropdownOpen) {
            var previousTab = _this.getPreviousTab();

            _this.setFocusedItemByIndex(previousTab);
          }

          break;

        case KeyCodes.ARROW_RIGHT:
          if (!isDropdownOpen) {
            var nextTab = _this.getNextTab();

            _this.setFocusedItemByIndex(nextTab);
          }

          break;

        case KeyCodes.ARROW_DOWN:
          if (!isDropdownOpen) {
            if (TabPanel.isItemOfDropdownType(focusedTab)) {
              _this.setState({
                isDropdownOpen: true
              });
            } else {
              var _nextTab = _this.getNextTab();

              _this.setFocusedItemByIndex(_nextTab);

              event.preventDefault();
            }
          }

          break;

        case KeyCodes.TAB:
          _this.setState({
            isDropdownOpen: false
          });

          var activeItem = _this.getActiveItemIndex();

          if (activeItem < focusedItemIndex && event.shiftKey || activeItem > focusedItemIndex && !event.shiftKey) {
            _this.setFocusedItemByIndex(activeItem);

            event.preventDefault();
          }

          break;

        case KeyCodes.ENTER:
        case KeyCodes.SPACE:
          if (TabPanel.isItemCanBeFocusedWithKeyboard(children[focusedItemIndex])) {
            event.preventDefault();

            _this.setState({
              isDropdownOpen: false
            });

            _this.setActiveItem(focusedTab, event.target);
          }

          break;

        case KeyCodes.ESC:
          _this.setState({
            isDropdownOpen: false
          });

      }
    });

    _defineProperty(_assertThisInitialized(_this), "setActiveItem", function (focusedTab, target) {
      var focusedItem;

      if (TabPanel.isItemOfTabItemType(focusedTab)) {
        focusedItem = focusedTab;
      } else {
        var navDropdownNode = target.parentNode.parentNode;
        var index = TabPanel.getChildIndex(navDropdownNode, target);
        var children = cleanEmptyChildren(focusedTab.props.children);
        focusedItem = children[index];
      }

      if (isEmpty(focusedItem)) {
        return;
      }

      var activeTabPath = TabPanel.getItemPath(focusedItem);

      _this.activatePath(activeTabPath);

      var _focusedItem$props = focusedItem.props,
          eventKey = _focusedItem$props.eventKey,
          onClick = _focusedItem$props.onClick,
          onSelect = _focusedItem$props.onSelect;

      if (onSelect) {
        onSelect(eventKey);
      }

      if (onClick) {
        onClick();
      }
    });

    _defineProperty(_assertThisInitialized(_this), "activatePath", function (activeTabPath) {
      if (activeTabPath) {
        _this.context.router.push(activeTabPath);
      }
    });

    return _this;
  }

  TabPanel.getChildIndex = function getChildIndex(containerNode, childNode) {
    var index = -1;
    var childrenArray = Array.from(containerNode.children);

    while (index === -1 && childNode !== null) {
      index = childrenArray.indexOf(childNode);
      childNode = childNode.parentNode;
    }

    return index;
  };

  TabPanel.getItemPath = function getItemPath(item) {
    if (isEmpty(item) || isEmpty(item.props)) {
      return '';
    }

    var to = item.props.to;
    return to && (to.pathname || to) || '';
  };

  TabPanel.isItemCanBeFocusedWithKeyboard = function isItemCanBeFocusedWithKeyboard(item) {
    var isAllowedByDefault = TabPanel.isItemOfDropdownType(item) || TabPanel.isItemOfTabItemType(item);
    return isAllowedByDefault || item.props.role in TAB_PANEL_ITEM_ROLES;
  };

  TabPanel.isItemOfDropdownType = function isItemOfDropdownType(item) {
    return item && isElementHasType(item, NavDropdown);
  };

  TabPanel.isItemOfTabItemType = function isItemOfTabItemType(item) {
    return item && isElementHasType(item, TabItem);
  };

  var _proto = TabPanel.prototype;

  _proto.getChildContext = function getChildContext() {
    return {
      isStyledAsTab: this.isStyledAsTab
    };
  };

  _proto.componentDidMount = function componentDidMount() {
    this.focusActiveItem();
  };

  _proto.componentDidUpdate = function componentDidUpdate(previousProps, previousState) {
    if (this.isStyledAsTab()) {
      var previousFocusedItemIndex = previousState.focusedItemIndex;
      var focusedItemIndex = this.state.focusedItemIndex;

      if (previousFocusedItemIndex !== focusedItemIndex) {
        this.focusToItemNodeByIndex(focusedItemIndex);
      }
    }
  };

  _proto.focusToItemNodeByIndex = function focusToItemNodeByIndex(focusedItemIndex) {
    var childNodes = ReactDOM.findDOMNode(this).children;
    var activeNode = childNodes[focusedItemIndex];

    if (activeNode) {
      activeNode.firstChild.focus();
    }
  };

  _proto.focusActiveItem = function focusActiveItem() {
    var activeItemIndex = this.getActiveItemIndex();
    this.setFocusedItemByIndex(activeItemIndex);
    this.focusToItemNodeByIndex(activeItemIndex);
  };

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

    var _this$props2 = this.props,
        activeKey = _this$props2.activeKey,
        rawChildren = _this$props2.children;
    var children = cleanEmptyChildren(rawChildren);
    var activeItemIndex;

    if (activeKey === null) {
      activeItemIndex = children.findIndex(function (child) {
        return child && (child.props.active || _this2.context.router && _this2.context.router.isActive(TabPanel.getItemPath(child), false));
      });
    } else {
      activeItemIndex = children.findIndex(function (child) {
        return child && child.props.eventKey === activeKey;
      });
    }

    return activeItemIndex;
  };

  _proto.getPreviousTab = function getPreviousTab() {
    var rawChildren = this.props.children;
    var children = cleanEmptyChildren(rawChildren);
    var focusedItemIndex = this.state.focusedItemIndex;
    var previousItemIndex = focusedItemIndex - 1;
    var isPreviousChildPresent = previousItemIndex >= 0;
    var lastChildIndex = children.length - 1;

    if (isPreviousChildPresent && TabPanel.isItemCanBeFocusedWithKeyboard(children[previousItemIndex])) {
      return previousItemIndex;
    }

    return TabPanel.isItemCanBeFocusedWithKeyboard(children[lastChildIndex]) ? lastChildIndex : lastChildIndex - 1;
  };

  _proto.getNextTab = function getNextTab() {
    var rawChildren = this.props.children;
    var children = cleanEmptyChildren(rawChildren);
    var focusedItemIndex = this.state.focusedItemIndex;
    var nextItemIndex = focusedItemIndex + 1;
    var isNextChildPresent = nextItemIndex < children.length;

    if (isNextChildPresent && TabPanel.isItemCanBeFocusedWithKeyboard(children[nextItemIndex])) {
      return nextItemIndex;
    }

    return 0;
  };

  _proto.render = function render() {
    var _this$props3 = this.props,
        testAutomationId = _this$props3.testAutomationId,
        centered = _this$props3.centered,
        noBorder = _this$props3.noBorder,
        topMenu = _this$props3.topMenu,
        clearRightPadding = _this$props3.clearRightPadding,
        clearLeftPadding = _this$props3.clearLeftPadding,
        clearLeftWrapperPadding = _this$props3.clearLeftWrapperPadding,
        clearRightWrapperPadding = _this$props3.clearRightWrapperPadding,
        fullWidthBorder = _this$props3.fullWidthBorder,
        noPadding = _this$props3.noPadding,
        className = _this$props3.className,
        children = _this$props3.children,
        preserveBottomBorder = _this$props3.preserveBottomBorder,
        props = _objectWithoutPropertiesLoose(_this$props3, ["testAutomationId", "centered", "noBorder", "topMenu", "clearRightPadding", "clearLeftPadding", "clearLeftWrapperPadding", "clearRightWrapperPadding", "fullWidthBorder", "noPadding", "className", "children", "preserveBottomBorder"]);

    className = classnames({
      'rc-nav-centered': centered,
      'rc-nav-noHorizontalPadding': noPadding,
      'rc-nav-noBorder': noBorder,
      'rc-nav-fullWidthBorder': !noBorder && fullWidthBorder,
      'rc-nav-topMenu': topMenu,
      'rc-nav-clearRightPadding': clearRightPadding,
      'rc-nav-clearLeftPadding': clearLeftPadding,
      'rc-nav-clearLeftWrapperPadding': clearLeftWrapperPadding,
      'rc-nav-clearRightWrapperPadding': clearRightWrapperPadding,
      'rc-nav-preserveBottomBorder': preserveBottomBorder
    }, className);
    return React.createElement(Nav, _extends({
      bsStyle: "tabs",
      className: className,
      "data-test-automation-id": testAutomationId,
      role: "tablist",
      tabIndex: 0,
      onClick: this.handleClick,
      onKeyDown: this.handleKeyDown
    }, props), children);
  };

  return TabPanel;
}(React.Component);

_defineProperty(TabPanel, "propTypes", {
  testAutomationId: PropTypes.string,
  children: PropTypes.node.isRequired,
  centered: PropTypes.bool,
  noBorder: PropTypes.bool,
  topMenu: PropTypes.bool,
  clearRightPadding: PropTypes.bool,
  clearLeftPadding: PropTypes.bool,
  clearLeftWrapperPadding: PropTypes.bool,
  clearRightWrapperPadding: PropTypes.bool,
  fullWidthBorder: PropTypes.bool,
  noPadding: PropTypes.bool,
  preserveBottomBorder: PropTypes.bool,
  className: PropTypes.string,
  activeKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
  bsStyle: PropTypes.oneOf([TAB_PANEL_STYLES.TABS, TAB_PANEL_STYLES.MENU, TAB_PANEL_STYLES.PILLS])
});

_defineProperty(TabPanel, "defaultProps", {
  testAutomationId: 'tabs',
  centered: false,
  noBorder: false,
  topMenu: false,
  clearRightPadding: false,
  clearLeftPadding: false,
  clearLeftWrapperPadding: false,
  clearRightWrapperPadding: false,
  fullWidthBorder: false,
  preserveBottomBorder: false,
  noPadding: false,
  className: null,
  activeKey: null,
  bsStyle: TAB_PANEL_STYLES.TABS
});

_defineProperty(TabPanel, "contextTypes", {
  router: PropTypes.object
});

_defineProperty(TabPanel, "childContextTypes", {
  isStyledAsTab: PropTypes.func
});