var _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; };

function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }

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

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

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

import React, { Component } from 'react';
import { Box } from 'grommet/es6/components/Box';
import { Keyboard } from 'grommet/es6/components/Keyboard';
import { Text } from 'grommet/es6/components/Text';
import { Button } from 'grommet/es6/components/Button';
import { FormDown } from 'grommet-icons/es6/icons/FormDown';
import { FormNext } from 'grommet-icons/es6/icons/FormNext';


var isActive = function isActive(active, item) {
  return item.id === active.id || item.label === active.label;
};

var hasActiveChidlren = function hasActiveChidlren(active, item) {
  return isActive(active, item) || item.items && item.items.find(function (t) {
    return hasActiveChidlren(active, t);
  });
};
var getExpandedItems = function getExpandedItems(children, active) {
  return children.reduce(function (expandedItems, item) {
    var items = item.items,
        expanded = item.expanded,
        id = item.id,
        label = item.label;

    if (expanded || active && hasActiveChidlren(active, item)) {
      expandedItems.push(id || label);
    }
    var childrenExpandedItems = [];
    if (items) {
      childrenExpandedItems = getExpandedItems(items, active);
    }
    return expandedItems.concat(childrenExpandedItems);
  }, []);
};

var getCollapsibleItems = function getCollapsibleItems(children) {
  return children.reduce(function (collapsibleItems, _ref) {
    var items = _ref.items,
        id = _ref.id,
        label = _ref.label;

    var childrenCollapsibleItems = [];
    if (items) {
      collapsibleItems.push(id || label);

      childrenCollapsibleItems = getCollapsibleItems(items);
    }
    return collapsibleItems.concat(childrenCollapsibleItems);
  }, []);
};

var getFlatChildrenIds = function getFlatChildrenIds(children) {
  return children.reduce(function (flatChildren, item) {
    flatChildren.push(item.id || item.label);
    if (item.items) {
      // eslint-disable-next-line no-param-reassign
      flatChildren = flatChildren.concat(getFlatChildrenIds(item.items));
    }
    return flatChildren;
  }, []);
};

var getChildrenById = function getChildrenById(children, id) {
  var items = void 0;
  children.some(function (item) {
    if (item.id === id || item.label === id) {
      items = item.items;

      return true;
    }
    if (item.items) {
      items = getChildrenById(item.items, id);

      if (items) {
        return true;
      }
    }
    return false;
  });
  return items;
};

var filterItems = function filterItems(items, search) {
  if (search && search.length) {
    var searchLC = search.toLowerCase();
    return items.map(function (item) {
      return Object.assign({}, item);
    }).filter(function (item) {
      var children = item.items,
          label = item.label;

      if (label.toLowerCase().indexOf(searchLC) >= 0) {
        return true;
      }
      if (children) {
        var childItems = filterItems(children, search);
        // eslint-disable-next-line no-param-reassign
        item.items = childItems;
        if (childItems.length) {
          return true;
        }
      }
      return false;
    });
  }
  return items;
};

var VerticalMenu = function (_Component) {
  _inherits(VerticalMenu, _Component);

  function VerticalMenu() {
    var _temp, _this, _ret;

    _classCallCheck(this, VerticalMenu);

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

    return _ret = (_temp = (_this = _possibleConstructorReturn(this, _Component.call.apply(_Component, [this].concat(args))), _this), _this.state = { expandedItems: [] }, _this.onMenuChange = function (id, expanded) {
      var _this$state = _this.state,
          expandedItems = _this$state.expandedItems,
          filteredItems = _this$state.filteredItems;


      var newExpandedItems = [].concat(expandedItems);
      if (expanded) {
        var toBeCollapsed = [id].concat(getFlatChildrenIds(getChildrenById(filteredItems, id)));
        newExpandedItems = newExpandedItems.filter(function (item) {
          return toBeCollapsed.indexOf(item) < 0;
        });
      } else {
        newExpandedItems.push(id);
      }

      _this.setState({
        expandedItems: newExpandedItems
      });
    }, _this.renderItem = function (item) {
      var level = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
      var _this$props = _this.props,
          activeItem = _this$props.activeItem,
          onSelect = _this$props.onSelect,
          buttonClass = _this$props.buttonClass;
      var expandedItems = _this.state.expandedItems;

      var items = item.items,
          id = item.id,
          label = item.label,
          widget = item.widget,
          icon = item.icon,
          rest = _objectWithoutProperties(item, ['items', 'id', 'label', 'widget', 'icon']);

      var itemId = id || label;
      var isExpanded = expandedItems.includes(itemId);
      var ButtonClass = items ? Button : buttonClass || Button;
      var itemKey = 'item_' + itemId + '_' + level;

      var background = void 0;
      if (activeItem && activeItem.id === id) {
        background = {
          color: 'active',
          opacity: 'strong'
        };
      }

      var content = React.createElement(
        Box,
        {
          background: background
        },
        React.createElement(
          ButtonClass,
          _extends({
            onClick: !rest.route && !rest.path ? function () {
              return items ? _this.onMenuChange(itemId, isExpanded) : onSelect && onSelect(item);
            } : undefined,
            hoverIndicator: { color: 'active' }
          }, rest),
          React.createElement(
            Box,
            {
              direction: 'row',
              align: 'center',
              pad: 'small',
              style: {
                marginLeft: items ? 12 * level + 'px' : 16 * level + 'px'
              }
            },
            items && (isExpanded ? React.createElement(FormDown, null) : React.createElement(FormNext, null)),
            React.createElement(
              Box,
              { direction: 'row', justify: 'between', fill: 'horizontal', align: 'center' },
              React.createElement(
                Box,
                { direction: 'row', align: 'center', gap: 'small' },
                icon,
                typeof label === 'string' ? React.createElement(
                  Text,
                  null,
                  items ? React.createElement(
                    'strong',
                    null,
                    label
                  ) : label
                ) : label
              ),
              widget
            )
          )
        )
      );
      return React.createElement(
        Box,
        { key: itemKey },
        items ? React.createElement(
          Keyboard,
          {
            onDown: function onDown() {
              return _this.onMenuChange(itemId, false, false);
            },
            onRight: function onRight() {
              return _this.onMenuChange(itemId, false);
            },
            onUp: function onUp() {
              return _this.onMenuChange(itemId, true);
            },
            onLeft: function onLeft() {
              return _this.onMenuChange(itemId, true);
            }
          },
          content
        ) : content,
        items && isExpanded && items.map(function (child) {
          return _this.renderItem(child, level + 1);
        })
      );
    }, _temp), _possibleConstructorReturn(_this, _ret);
  }

  VerticalMenu.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps) {
    var prevState = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
    var items = nextProps.items,
        expandAll = nextProps.expandAll,
        activeItem = nextProps.activeItem,
        search = nextProps.search;
    var originalExpandAll = prevState.originalExpandAll,
        stateSearch = prevState.search,
        _prevState$items = prevState.items,
        stateItems = _prevState$items === undefined ? [] : _prevState$items;


    if (items.toString() !== stateItems.toString() || expandAll !== originalExpandAll || search !== stateSearch) {
      var filteredItems = filterItems(items, search);
      var collapsibleItems = getCollapsibleItems(filteredItems);
      var expandedItems = void 0;
      if (expandAll || search && search.length) {
        expandedItems = collapsibleItems;
      } else {
        expandedItems = getExpandedItems(filteredItems, activeItem);
      }

      var allExpanded = typeof expandAll !== 'undefined' ? expandAll : collapsibleItems.length === expandedItems.length;
      return {
        expandedItems: expandedItems,
        items: items,
        filteredItems: filteredItems,
        search: search,
        collapsibleItems: collapsibleItems,
        allExpanded: allExpanded,
        expandAll: expandAll,
        originalExpandAll: expandAll
      };
    }

    return null;
  };

  VerticalMenu.prototype.render = function render() {
    var _this2 = this;

    var filteredItems = this.state.filteredItems;

    return React.createElement(
      React.Fragment,
      null,
      filteredItems && filteredItems.map(function (item) {
        return _this2.renderItem(item, 1);
      })
    );
  };

  return VerticalMenu;
}(Component);

var VerticalMenuDoc = void 0;
if (process.env.NODE_ENV !== 'production') {
  VerticalMenuDoc = require('./doc').default(VerticalMenu); // eslint-disable-line global-require
}

var VerticalMenuWrapper = VerticalMenuDoc || VerticalMenu;

export { VerticalMenuWrapper as VerticalMenu };