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 PropTypes from 'prop-types';
import _ from 'lodash';
import { TabPanel } from './TabPanel';
import { Icon } from './Icon';
import { NavDropdown } from './NavDropdown';
import ReactDOM from 'react-dom';
import Measure from 'react-measure';
import { getElementBorder, getElementMargin, getElementPadding } from './utils';
import { cleanEmptyChildren } from '../utils/functions';
var DROPDOWN_STYLES = {
  visibility: 'hidden',
  position: 'absolute',
  left: '-100%'
};
var TAB_PANEL_STYLES = {
  whiteSpace: 'nowrap'
};
var a11yIdCounter = 1;
export var TabPanelOverflowContainer =
/*#__PURE__*/
function (_React$Component) {
  _inheritsLoose(TabPanelOverflowContainer, _React$Component);

  function TabPanelOverflowContainer(props, context) {
    var _this;

    _this = _React$Component.call(this, props, context) || this;

    _defineProperty(_assertThisInitialized(_this), "handleResizeRootContainer", function (contentRect) {
      _this.setState({
        dimensions: contentRect.bounds,
        visibleAmount: -1 // reset to recalculate visible amount

      });
    });

    _this.tabPanelRef = React.createRef();
    _this.dropdownRef = React.createRef();
    _this.dropdownA11yId = 'dropdown' + a11yIdCounter++;
    _this.state = {
      visibleAmount: -1,
      dropdownWidth: -1,
      // assume it's static and does not changed
      dimensions: {
        width: -1,
        right: -1
      }
    };
    return _this;
  }

  var _proto = TabPanelOverflowContainer.prototype;

  _proto.componentDidUpdate = function componentDidUpdate(prevProps, prevState) {
    var _this$state = this.state,
        visibleAmount = _this$state.visibleAmount,
        dimensions = _this$state.dimensions;
    var dropdownNode = ReactDOM.findDOMNode(this.dropdownRef.current);

    if (dropdownNode) {
      var dropdownWidth = dropdownNode.getBoundingClientRect().width;

      if (this.state.dropdownWidth !== dropdownWidth) {
        this.setState({
          dropdownWidth: dropdownWidth
        });
      }
    }

    var nextVisibleAmount = this.calculateVisibleAmount();
    var actualWidth = dimensions.width;
    var prevWidth = prevState.dimensions.width;
    var isDimensionsChanged = prevWidth !== actualWidth;
    var isChildrenChanged = prevProps.children.length !== this.props.children.length;

    if (isChildrenChanged || isDimensionsChanged) {
      // force to show all items to measure
      nextVisibleAmount = cleanEmptyChildren(this.props.children).length;
    }

    if (visibleAmount !== nextVisibleAmount) {
      this.setState({
        visibleAmount: nextVisibleAmount
      });
    }
  };

  _proto.calculateVisibleAmount = function calculateVisibleAmount() {
    var rootNode = ReactDOM.findDOMNode(this.tabPanelRef.current);
    var dropdownNode = ReactDOM.findDOMNode(this.dropdownRef.current);

    if (!rootNode) {
      return -1;
    }

    var children = Array.from(rootNode.children).filter(function (child) {
      return child !== dropdownNode;
    });
    var dropdownNodeWidth = this.state.dropdownWidth;
    var rootNodePaddingRight = getElementPadding(rootNode).paddingRight;
    var rootNodeBorderRight = getElementBorder(rootNode).borderRight;
    var allowedRightBoundaryPoint = this.state.dimensions.right - rootNodePaddingRight - rootNodeBorderRight;
    var lastVisibleIndex = this.findLastVisibleIndex(children, allowedRightBoundaryPoint);
    var isOverflow = lastVisibleIndex !== cleanEmptyChildren(this.props.children).length - 1;

    if (isOverflow) {
      // in case of overflow, recalculate, taking into consideration that dropdown is on the screen
      var lastVisibleIndexIncludingDropdown = this.findLastVisibleIndex(children, allowedRightBoundaryPoint - dropdownNodeWidth);
      lastVisibleIndex = Math.min(lastVisibleIndex, lastVisibleIndexIncludingDropdown);
    }

    return lastVisibleIndex + 1;
  };

  _proto.findLastVisibleIndex = function findLastVisibleIndex(nodes, allowedRightBoundaryPoint) {
    var childIndex = nodes.length - 1;
    var visibleIndex = nodes.length - 1;

    while (childIndex >= 0) {
      var child = nodes[childIndex];
      childIndex--;
      var boundaryRect = child.getBoundingClientRect();
      var rightBoundaryPoint = boundaryRect.right;
      var childRightMargin = getElementMargin(child).marginRight;

      if (rightBoundaryPoint + childRightMargin > allowedRightBoundaryPoint) {
        visibleIndex--;
      } else {
        break;
      }
    }

    return visibleIndex;
  };

  _proto.render = function render() {
    var _this$props = this.props,
        rawChildren = _this$props.children,
        props = _objectWithoutPropertiesLoose(_this$props, ["children"]);

    var _this$state2 = this.state,
        visibleAmount = _this$state2.visibleAmount,
        dropdownWidth = _this$state2.dropdownWidth;
    var children = cleanEmptyChildren(rawChildren);
    visibleAmount = visibleAmount === -1 ? children.length : visibleAmount;

    var head = _.take(children, visibleAmount);

    var tail = _.takeRight(children, children.length - visibleAmount);

    var isOverflow = tail.length > 0;
    var resultChildren = head;
    var dropdown = null;

    if (dropdownWidth === -1 || isOverflow) {
      // show it to measure dropdown size, but out of viewport to avoid UI flicker
      var dropdownStyles = null;

      if (dropdownWidth === -1) {
        dropdownStyles = DROPDOWN_STYLES;
      }

      var id = this.dropdownA11yId;
      dropdown = React.createElement(NavDropdown, {
        role: "tab",
        testAutomationId: "menuItemMore",
        id: id,
        ref: this.dropdownRef,
        className: "pull-right",
        title: React.createElement(Icon, {
          name: "three-dots"
        }),
        style: dropdownStyles
      }, tail);

      if (!isOverflow) {
        dropdown = null;
      }

      if (dropdown) {
        resultChildren.push(dropdown);
      }
    }

    var tabPanel = React.createElement(TabPanel, _extends({
      ref: this.tabPanelRef
    }, props, {
      style: TAB_PANEL_STYLES
    }), resultChildren);
    return React.createElement(Measure, {
      bounds: true,
      onResize: this.handleResizeRootContainer
    }, function (_ref) {
      var measureRef = _ref.measureRef;
      return React.createElement("div", {
        ref: measureRef
      }, tabPanel);
    });
  };

  return TabPanelOverflowContainer;
}(React.Component);

_defineProperty(TabPanelOverflowContainer, "propTypes", {
  children: PropTypes.node
});

_defineProperty(TabPanelOverflowContainer, "defaultProps", {
  children: null
});