import _extends from "@babel/runtime/helpers/esm/extends";
import _inheritsLoose from "@babel/runtime/helpers/esm/inheritsLoose";
var _class, _Menu;
import React from 'react';
import { globalObject, isBrowser } from '@skbkontur/global-object';
import { isKeyArrowDown, isKeyArrowUp, isKeyEnter } from "../../../lib/events/keyboard/identifiers";
import { MenuSeparator } from "../../../components/MenuSeparator";
import { ThemeFactory } from "../../../lib/theming/ThemeFactory";
import { getDOMRect } from "../../../lib/dom/getDOMRect";
import { responsiveLayout } from "../../../components/ResponsiveLayout/decorator";
import { isNonNullable } from "../../../lib/utils";
import { ScrollContainer } from "../../../components/ScrollContainer";
import { MenuItemDataTids } from "../../../components/MenuItem";
import { ThemeContext } from "../../../lib/theming/ThemeContext";
import { cx } from "../../../lib/theming/Emotion";
import { getRootNode, rootNode } from "../../../lib/rootNode";
import { isIE11 } from "../../../lib/client";
import { createPropsGetter } from "../../../lib/createPropsGetter";
import { isInstanceOf } from "../../../lib/isInstanceOf";
import { CommonWrapper } from "../../CommonWrapper";
import { styles } from "../Menu.styles";
import { MenuNavigation } from "../MenuNavigation";
import { MenuContext } from "../MenuContext";
export var MenuDataTids = {
  root: 'Menu__root'
};
export var Menu = responsiveLayout(_class = rootNode(_class = (_Menu = /*#__PURE__*/function (_React$PureComponent) {
  function Menu() {
    var _this;
    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }
    _this = _React$PureComponent.call.apply(_React$PureComponent, [this].concat(args)) || this;
    _this.getProps = createPropsGetter(Menu.defaultProps);
    _this.state = {
      highlightedIndex: -1,
      maxHeight: _this.getProps().maxHeight || 'none',
      scrollState: 'top',
      enableIconPadding: false
    };
    _this.unmounted = false;
    _this.contentRef = /*#__PURE__*/React.createRef();
    _this.menuNavigation = new MenuNavigation(_this.contentRef, MenuItemDataTids.content);
    _this.focusOnRootElement = function () {
      var rootNode = getRootNode(_this);
      if (isInstanceOf(rootNode, globalObject.HTMLElement)) {
        rootNode == null || rootNode.focus();
      }
    };
    _this.renderHeader = function () {
      var _cx;
      return /*#__PURE__*/(
        React.createElement("div", {
          className: cx((_cx = {}, _cx[styles.wrapper()] = true, _cx[styles.headerWrapper()] = true, _cx)),
          ref: function ref(el) {
            return _this.header = el;
          }
        }, /*#__PURE__*/

        React.createElement("div", {
          className: styles.contentWrapper()
        }, _this.props.header), /*#__PURE__*/
        React.createElement("div", {
          className: styles.menuSeparatorWrapper(_this.theme)
        }, _this.state.scrollState !== 'top' && _this.renderMenuSeparatorWithNoMargin()))
      );
    };
    _this.renderFooter = function () {
      var _cx2;
      return /*#__PURE__*/(
        React.createElement("div", {
          className: cx((_cx2 = {}, _cx2[styles.wrapper()] = true, _cx2[styles.footerWrapper()] = true, _cx2)),
          ref: function ref(el) {
            return _this.footer = el;
          }
        }, /*#__PURE__*/

        React.createElement("div", {
          className: styles.menuSeparatorWrapper(_this.theme)
        }, _this.state.scrollState !== 'bottom' && _this.renderMenuSeparatorWithNoMargin()), /*#__PURE__*/
        React.createElement("div", {
          className: styles.contentWrapper()
        }, _this.props.footer))
      );
    };
    _this.renderMenuSeparatorWithNoMargin = function () {
      return /*#__PURE__*/(
        React.createElement(ThemeContext.Provider, {
          value: ThemeFactory.create({
            menuSeparatorMarginY: '0'
          }, _this.theme)
        }, /*#__PURE__*/
        React.createElement(MenuSeparator, null))
      );
    };
    _this.setInitialSelection = function () {
      for (var i = _this.getProps().initialSelectedItemIndex; i > -1; i--) {
        _this.down();
      }
    };
    _this.shouldRecalculateMaxHeight = function (prevProps) {
      var _this$props = _this.props,
        header = _this$props.header,
        footer = _this$props.footer,
        children = _this$props.children;
      var maxHeight = _this.getProps().maxHeight;
      var prevMaxHeight = prevProps.maxHeight;
      var prevHeader = prevProps.header;
      var prevFooter = prevProps.footer;
      var prevChildrenCount = React.Children.count(prevProps.children);
      return maxHeight !== prevMaxHeight || footer !== prevFooter || header !== prevHeader || React.Children.count(children) !== prevChildrenCount;
    };
    _this.calculateMaxHeight = function () {
      var maxHeight = _this.getProps().maxHeight;
      var parsedMaxHeight = maxHeight;
      var rootNode = getRootNode(_this);
      if (typeof maxHeight === 'string' && isBrowser(globalObject) && rootNode) {
        var rootElementMaxHeight = globalObject.getComputedStyle == null ? void 0 : globalObject.getComputedStyle(rootNode).maxHeight;
        if (rootElementMaxHeight) {
          parsedMaxHeight = parseFloat(rootElementMaxHeight);
        }
      }
      var calculatedMaxHeight = typeof parsedMaxHeight === 'number' ? parsedMaxHeight + (_this.header && getDOMRect(_this.header).height || 0) + (_this.footer && getDOMRect(_this.footer).height || 0) : maxHeight;
      _this.setState({
        maxHeight: calculatedMaxHeight || 'none'
      });
    };
    _this.refScrollContainer = function (scrollContainer) {
      _this.scrollContainer = scrollContainer;
    };
    _this.scrollToSelected = function () {
      var highlightedItem = _this.menuNavigation.highlightedItem;
      if (_this.scrollContainer && highlightedItem) {
        var _rootNode = getRootNode(highlightedItem);
        // TODO: Remove this check once IF-647 is resolved
        if (isInstanceOf(_rootNode, globalObject.HTMLElement)) {
          _this.scrollContainer.scrollTo(_rootNode);
        }
      }
    };
    _this.scrollToTop = function () {
      if (_this.scrollContainer) {
        _this.scrollContainer.scrollToTop();
      }
    };
    _this.scrollToBottom = function () {
      if (_this.scrollContainer) {
        _this.scrollContainer.scrollToBottom();
      }
    };
    _this.scroll = function (nextIndex) {
      switch (nextIndex) {
        case 0:
          _this.scrollToTop == null || _this.scrollToTop();
          break;
        case _this.menuNavigation.items.length - 1:
          _this.scrollToBottom == null || _this.scrollToBottom();
          break;
        default:
          _this.scrollToSelected == null || _this.scrollToSelected();
      }
    };
    _this.handleKeyDown = function (event) {
      if (typeof _this.props.onKeyDown === 'function') {
        _this.props.onKeyDown(event);
      }
      if (event.defaultPrevented) {
        return;
      }
      if (isKeyArrowUp(event)) {
        event.preventDefault();
        _this.up();
      } else if (isKeyArrowDown(event)) {
        event.preventDefault();
        _this.down();
      } else if (isKeyEnter(event)) {
        _this.menuNavigation.select(event);
      }
    };
    _this.getStyle = function (props) {
      if (props.align === 'right') {
        return {
          maxWidth: props.width,
          minWidth: props.width,
          maxHeight: _this.state.maxHeight
        };
      }
      return {
        width: props.width,
        maxHeight: _this.state.maxHeight
      };
    };
    _this.handleScrollStateChange = function (scrollState) {
      if (_this.state.scrollState !== scrollState) {
        _this.setState({
          scrollState: scrollState
        });
      }
    };
    _this.setEnableIconPadding = function (isIconPaddingEnabled) {
      !_this.getProps().preventIconsOffset && _this.setState({
        enableIconPadding: isIconPaddingEnabled
      });
    };
    return _this;
  }
  _inheritsLoose(Menu, _React$PureComponent);
  var _proto = Menu.prototype;
  _proto.componentWillUnmount = function componentWillUnmount() {
    this.unmounted = true;
  };
  _proto.componentDidMount = function componentDidMount() {
    this.setInitialSelection();
    this.calculateMaxHeight();
    this.unmounted = false;
  };
  _proto.componentDidUpdate = function componentDidUpdate(prevProps) {
    if (this.shouldRecalculateMaxHeight(prevProps)) {
      this.calculateMaxHeight();
    }
    if (prevProps.maxHeight !== this.getProps().maxHeight) {
      this.setState({
        maxHeight: this.props.maxHeight || 'none'
      });
    }
  };
  _proto.focus = function focus() {
    this.focusOnRootElement();
  };
  _proto.render = function render() {
    var _this2 = this;
    return /*#__PURE__*/React.createElement(ThemeContext.Consumer, null, function (theme) {
      _this2.theme = theme;
      return _this2.renderMain();
    });
  } /**
    * @public
    */;
  _proto.up = function up() {
    this.move(-1);
  } /**
    * @public
    */;
  _proto.down = function down() {
    this.move(1);
  } /**
    * @public
    */;
  _proto.enter = function enter(event) {
    var _this$menuNavigation$;
    (_this$menuNavigation$ = this.menuNavigation.highlightedItem) == null || _this$menuNavigation$.navigate();
    return this.menuNavigation.select(event);
  } /**
    * @public
    */;
  _proto.reset = function reset() {
    this.menuNavigation.reset();
  } /**
    * @public
    */;
  _proto.hasHighlightedItem = function hasHighlightedItem() {
    return !!this.menuNavigation.highlightedItem;
  };
  _proto.highlightItem = function highlightItem(index) {
    this.menuNavigation.highlightByIndex(index);
  };
  _proto.renderMain = function renderMain() {
    var _cx3, _cx4;
    if (this.isEmpty()) {
      return null;
    }
    var _this$getProps = this.getProps(),
      hasMargin = _this$getProps.hasMargin,
      maxHeight = _this$getProps.maxHeight,
      preventWindowScroll = _this$getProps.preventWindowScroll;
    var offsetY = {
      top: "" + this.theme.scrollContainerScrollBarOffsetY,
      right: 0,
      bottom: "" + this.theme.scrollContainerScrollBarOffsetY
    };
    var isMobile = this.isMobileLayout;
    return /*#__PURE__*/React.createElement(CommonWrapper, _extends({
      rootNodeRef: this.setRootNode
    }, this.props), /*#__PURE__*/React.createElement("div", {
      "data-tid": MenuDataTids.root,
      className: cx(getAlignRightClass(this.props), (_cx3 = {}, _cx3[styles.root(this.theme)] = true, _cx3[styles.hasMargin(this.theme)] = hasMargin, _cx3[styles.mobileRoot(this.theme)] = isMobile, _cx3[styles.shadow(this.theme)] = !isMobile, _cx3)),
      style: this.getStyle(this.props),
      id: this.props.id,
      onKeyDown: this.handleKeyDown,
      tabIndex: 0
    }, this.props.header && this.renderHeader(), /*#__PURE__*/React.createElement(ScrollContainer, {
      ref: this.refScrollContainer,
      maxHeight: maxHeight,
      preventWindowScroll: preventWindowScroll,
      onScrollStateChange: this.handleScrollStateChange,
      disabled: this.props.disableScrollContainer,
      offsetY: offsetY
    }, /*#__PURE__*/React.createElement("div", {
      className: cx((_cx4 = {}, _cx4[styles.scrollContainer(this.theme)] = true, _cx4[styles.scrollContainerMobile(this.theme)] = isMobile, _cx4)),
      ref: this.contentRef
    }, /*#__PURE__*/React.createElement(MenuContext.Provider, {
      value: {
        navigation: this.menuNavigation,
        onItemClick: this.props.onItemClick,
        enableIconPadding: this.state.enableIconPadding,
        setEnableIconPadding: this.setEnableIconPadding
      }
    }, this.props.children))), this.props.footer && this.renderFooter()));
  };
  _proto.move = function move(step) {
    if (this.unmounted) {
      // NOTE workaround, because `ComboBox` call `process.nextTick` in reducer
      return;
    }
    var nextIndex = this.menuNavigation.move(step, this.getProps().cyclicSelection);
    this.scroll(nextIndex);
  };
  _proto.isEmpty = function isEmpty() {
    var children = this.props.children;
    return !children || !childrenToArray(children).filter(isNonNullable).length;
  };
  return Menu;
}(React.PureComponent), _Menu.__KONTUR_REACT_UI__ = 'Menu', _Menu.displayName = 'Menu', _Menu.defaultProps = {
  align: 'left',
  width: 'auto',
  maxHeight: 300,
  hasMargin: true,
  preventWindowScroll: true,
  cyclicSelection: true,
  initialSelectedItemIndex: -1
}, _Menu)) || _class) || _class;
function childrenToArray(children) {
  var ret = []; // Use forEach instead of map to avoid cloning for key unifying.
  React.Children.forEach(children, function (child) {
    ret.push(child);
  });
  return ret;
}
var getAlignRightClass = function getAlignRightClass(props) {
  if (props.align === 'right') {
    var _cx5;
    return cx((_cx5 = {}, _cx5[styles.alignRight()] = !isIE11, _cx5[styles.alignRightIE11()] = isIE11, _cx5[styles.alignRightIE11FixAutoWidth()] = isIE11 && props.width === 'auto', _cx5));
  }
  return null;
};