'use strict';

exports.__esModule = true;
exports.getObjByValue = undefined;

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _propTypes = require('prop-types');

var _propTypes2 = _interopRequireDefault(_propTypes);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var _InputCheckBox = require('../InputCheckBox');

var _InputCheckBox2 = _interopRequireDefault(_InputCheckBox);

var _Tags = require('../../molecules/Tags');

var _Tags2 = _interopRequireDefault(_Tags);

require('./style.css');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

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

var getObjByValue = exports.getObjByValue = function getObjByValue(arr, value, key) {
  var i = 0;
  var arrayMax = arr.length;
  for (; i < arrayMax; i += 1) {
    var item = arr[i];
    if (item[key] === value) {
      return item;
    }
  }
  return undefined;
};

var MultiSelectDropDown = function (_React$Component) {
  _inherits(MultiSelectDropDown, _React$Component);

  function MultiSelectDropDown(props) {
    _classCallCheck(this, MultiSelectDropDown);

    var _this = _possibleConstructorReturn(this, _React$Component.call(this, props));

    _this.onBlur = function () {
      // Time out to wait for React processing delay on activeElement
      _this._timeoutID = setTimeout(function () {
        if (document.activeElement !== null) {
          if (!_this.wrapperRef.contains(document.activeElement)) {
            _this.setState({
              dropwDownExpand: false
            });
          }
        }
      }, 0);
    };

    _this.handleTagClick = function (target, e) {
      e.stopPropagation();
      var val = target.getAttribute('data-ma-filter-value');
      var values = _this.state.values;

      values.splice(values.indexOf(val), 1);
      _this.setState({
        values: values,
        dropwDownExpand: true
      });
    };

    _this.handleClearAll = function () {
      _this.setState({
        values: []
      });
      _this.focusOnComboBox();
    };

    _this.handleClickOutside = function (event) {
      // Close the panel if the user clicks outside the component.
      var node = _this.wrapperRef;
      if (node && !node.contains(event.target)) {
        if (_this.state.dropwDownExpand) {
          _this.closeDropDown();
        }
      }
    };

    _this.handleDropDownKeyDown = function (event) {
      if (event.key === 'Enter') {
        _this.handleSelect(event);
      }
    };

    _this.handleSelect = function (event) {
      var value = event.target.value;
      var values = _this.state.values;

      if (values.indexOf(value) > -1) {
        values.splice(values.indexOf(value), 1);
      } else {
        values.push(value);
      }
      _this.setState({
        values: values
      });
    };

    _this.handleKeyDown = function (event) {
      // Detect onBlur using tab key
      if (event.key === 'Tab') {
        _this.onBlur();
      }
      // If the user pressed escape collapse list.
      if (event.key === 'Escape') {
        _this.closeDropDown();
        _this.focusOnComboBox();
      }

      var index = -1;
      var tagName = event.target.tagName;

      if (tagName === 'INPUT') {
        var targetId = event.target.id;
        index = Number(targetId.split('-').pop());
      }
      var nextIndex = index + 1;
      var prevIndex = index - 1;

      if (event.key === 'ArrowUp') {
        if (prevIndex === -1) {
          _this.focusOnComboBox();
        }
        if (prevIndex >= 0) {
          var prevItem = document.getElementById('input-checkbox-' + prevIndex);
          if (prevItem) {
            prevItem.focus();
          }
        }
      }

      if (event.key === 'ArrowDown' && nextIndex < _this.props.dropdownItems.length) {
        var nextItem = document.getElementById('input-checkbox-' + nextIndex);
        if (nextItem) {
          nextItem.focus();
        }
      }
    };

    _this.focusOnComboBox = function () {
      var comboBox = document.getElementById(_this.props.fieldName + '-multiselect-combobox');
      comboBox.focus();
    };

    _this.handleClick = function () {
      _this.toggleDropDown();
    };

    _this.handleComboBoxKeyDown = function (event) {
      event.stopPropagation();
      if (event.key === 'Enter') {
        _this.toggleDropDown();
      }
    };

    _this.toggleDropDown = function () {
      _this.setState(function (prevState) {
        return { dropwDownExpand: !prevState.dropwDownExpand };
      });
    };

    _this.closeDropDown = function () {
      _this.setState({ dropwDownExpand: false });
    };

    _this.state = {
      values: [],
      dropwDownExpand: false
    };
    return _this;
  }

  MultiSelectDropDown.prototype.componentDidMount = function componentDidMount() {
    var _this2 = this;

    this.buttonClicked = false;
    document.addEventListener('mousedown', function (e) {
      return _this2.handleClickOutside(e);
    });
    this.wrapperRef.addEventListener('keydown', function (e) {
      return _this2.handleKeyDown(e);
    });
  };

  MultiSelectDropDown.prototype.componentWillUnmount = function componentWillUnmount() {
    var _this3 = this;

    document.removeEventListener('mousedown', function () {
      return _this3.handleClickOutside();
    });
    this.wrapperRef.removeEventListener('keydown', function () {
      return _this3.handleKeyDown();
    });
    this.wrapperRef.removeEventListener('onblur', function (e) {
      return _this3.handleKeyDown(e);
    });
  };

  MultiSelectDropDown.prototype.render = function render() {
    var _classNames,
        _this4 = this;

    var _props = this.props,
        dropdownItems = _props.dropdownItems,
        fieldName = _props.fieldName,
        title = _props.title,
        titleClasses = _props.titleClasses,
        defaultText = _props.defaultText;
    var _state = this.state,
        values = _state.values,
        dropwDownExpand = _state.dropwDownExpand;

    var tags = values.map(function (val) {
      return getObjByValue(dropdownItems, val, 'value');
    });
    var tagsProps = {
      tags: tags.map(function (tag) {
        return {
          value: tag.value,
          text: tag.label,
          type: fieldName
        };
      }),
      onClearThisCallback: this.handleTagClick,
      onClearCallback: this.handleClearAll
    };

    var titleCls = (0, _classnames2.default)((_classNames = {}, _classNames[titleClasses.join(' ')] = true, _classNames));

    return _react2.default.createElement(
      'div',
      {
        className: 'ma__multiselect-dropdown',
        ref: function ref(node) {
          _this4.wrapperRef = node;
        }
      },
      _react2.default.createElement(
        'fieldset',
        { className: 'group' },
        _react2.default.createElement(
          'legend',
          { className: titleClasses.length > 0 ? titleCls : null },
          title
        ),
        _react2.default.createElement(
          'div',
          {
            role: 'combobox',
            tabIndex: 0,
            'aria-expanded': dropwDownExpand,
            'aria-controls': fieldName + '-multiselect',
            id: fieldName + '-multiselect-combobox',
            'aria-haspopup': true,
            className: 'ma__select-box__field',
            onClick: this.handleClick,
            onKeyDown: this.handleComboBoxKeyDown
          },
          _react2.default.createElement(
            'div',
            { className: 'ma__select-box__link' },
            _react2.default.createElement(
              'span',
              { className: 'js-dropdown-link' },
              values.length > 0 ? _react2.default.createElement(_Tags2.default, tagsProps) : defaultText
            ),
            _react2.default.createElement('span', { className: 'ma__select-box__icon' })
          )
        ),
        dropwDownExpand && _react2.default.createElement(
          'div',
          {
            id: fieldName + '-multiselect',
            className: 'ma__multiselect-dropdown-menu ma__multiselect-dropdown-menu--expanded'
          },
          dropdownItems.map(function (item, i) {
            return _react2.default.createElement(_InputCheckBox2.default, {
              id: 'input-checkbox-' + i
              /* eslint-disable-next-line react/no-array-index-key */
              , key: 'input-checkbox-' + i,
              name: fieldName,
              value: item.value,
              label: item.label,
              onChange: _this4.handleSelect,
              onKeyDown: _this4.handleDropDownKeyDown,
              classes: ['ma__multiselect-dropdown-item'],
              defaultValue: values.indexOf(item.value) > -1 ? item.value : false,
              tabIndex: -1
            });
          })
        )
      )
    );
  };

  return MultiSelectDropDown;
}(_react2.default.Component);

MultiSelectDropDown.propTypes = process.env.NODE_ENV !== "production" ? {
  /** The legend title of the multiple select dropdown, can be a string, an element or a React component. */
  title: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.object]).isRequired,
  /** Legend classes. */
  titleClasses: _propTypes2.default.arrayOf(_propTypes2.default.string),
  /** Default display in dropdown field. */
  defaultText: _propTypes2.default.string,
  /** Custom callback on dropdown item selection. */
  onItemSelect: _propTypes2.default.func,
  /** Custom callback on dropdown click. */
  onDropDownClick: _propTypes2.default.func,
  /** An array of dropdown multiselect items */
  dropdownItems: _propTypes2.default.arrayOf(_propTypes2.default.shape({
    text: _propTypes2.default.string,
    href: _propTypes2.default.string
  })),
  /** Field name attribute that is used for grouping DOM submission and identify tags type */
  fieldName: _propTypes2.default.string
} : {};

MultiSelectDropDown.defaultProps = {
  titleClasses: []
};

exports.default = MultiSelectDropDown;