'use strict';

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

exports.__esModule = true;
exports.AutosuggestControl = void 0;

var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));

var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));

var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose"));

var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));

var _react = _interopRequireDefault(require("react"));

var _propTypes = _interopRequireDefault(require("prop-types"));

var _lodash = _interopRequireDefault(require("lodash"));

var _FormControl2 = require("./FormControl");

var _reactAutosuggest = _interopRequireDefault(require("react-autosuggest"));

var _TextInputControl = require("./TextInputControl");

var _utils = require("../list/utils");

var _Store = _interopRequireDefault(require("../../data/Store"));

var _playMessage = require("../../utils/playMessage");

var _utils2 = require("../../../utils");

var ENTER_CHAR_CODE = 13;
var READ_KEY_DOWN_TIMEOUT = 1000;

var AutosuggestControl =
/*#__PURE__*/
function (_FormControl) {
  (0, _inheritsLoose2.default)(AutosuggestControl, _FormControl);

  function AutosuggestControl(_props, context) {
    var _this;

    _this = _FormControl.call(this, _props, context) || this;
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleFocus", function () {
      _this.setState({
        isInputFocused: true
      });
    });
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleBlur", function (event) {
      _this.onSubmitChanges(event.target.value);

      _this.setState({
        isInputFocused: false
      });
    });
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "playSuggestionPromptMessage", _lodash.default.debounce(function (count) {
      var isInputFocused = _this.state.isInputFocused;

      if (!isInputFocused) {
        return;
      }

      var _this$props = _this.props,
          suggestionPromptLabel = _this$props.suggestionPromptLabel,
          noSuggestionPromptLabel = _this$props.noSuggestionPromptLabel;
      var message = count === 0 ? (0, _utils2.translate)(noSuggestionPromptLabel, {
        count: count
      }) : (0, _utils2.translate)(suggestionPromptLabel, {
        count: count
      });
      (0, _playMessage.playMessage)(message);
    }, READ_KEY_DOWN_TIMEOUT));
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "filterSuggestions", function (query, values) {
      if (query.length >= _this.props.minCharactersToShowSuggestions) {
        var regex = _Store.default.searchStringToRegExp(query);

        var filteredValues = values.filter(function (value) {
          regex.lastIndex = 0;
          return regex.test(_this.props.getSuggestionText(value));
        });
        return _lodash.default.take(filteredValues, _this.props.maxSuggestionsCount);
      } else {
        return [];
      }
    });
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "renderInputComponent", function (props) {
      return _react.default.createElement(_TextInputControl.TextInputControl, props);
    });
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "renderSuggestionsContainer", function (renderOptions) {
      var containerProps = renderOptions.containerProps,
          children = renderOptions.children;
      return _react.default.createElement("div", (0, _extends2.default)({}, containerProps, {
        role: null
      }), children);
    });

    var propsFromContext = _this.getPropsFromContext();

    _this.state = {
      suggestions: [],
      isInputFocused: false,
      value: propsFromContext.value ? propsFromContext.getSuggestionValue(propsFromContext.value) : ''
    };
    return _this;
  }

  var _proto = AutosuggestControl.prototype;

  _proto.componentWillReceiveProps = function componentWillReceiveProps(nextProps) {
    var propsFromContext = this.getPropsFromContext();

    if (nextProps.value !== undefined) {
      this.setState({
        value: nextProps.value === null ? '' : propsFromContext.getSuggestionValue(nextProps.value)
      });
    }
  };

  _proto.componentDidUpdate = function componentDidUpdate(oldProps, oldState) {
    _FormControl.prototype.componentDidUpdate.call(this);

    var getCount = function getCount(list) {
      return _lodash.default.isEmpty(list) ? 0 : list.length;
    };

    var oldSuggestions = oldState.suggestions;
    var suggestions = this.state.suggestions;
    var oldCount = getCount(oldSuggestions);
    var newCount = getCount(suggestions);

    if (oldCount !== newCount) {
      this.playSuggestionPromptMessage(newCount);
    }
  };

  _proto.onChange = function onChange(event, _ref) {
    var newValue = _ref.newValue;
    this.setState({
      value: newValue
    });
    this.props.onInputChange(newValue);
  };

  _proto.onSubmitChanges = function onSubmitChanges(newValue) {
    var _this2 = this;

    var values = this.props.values || this.state.suggestions || [];
    var propsFromContext = this.getPropsFromContext();
    var matchedValue = values.find(function (value) {
      return _this2.props.valueMatcher.call(_this2, newValue, value);
    });
    var allowMismatching = this.props.allowMismatching || this.props.getSuggestions;
    var mismatchedValue = allowMismatching ? newValue : '';
    this.setState({
      value: matchedValue ? propsFromContext.getSuggestionValue(matchedValue) : mismatchedValue
    });
    var updateValue = matchedValue || mismatchedValue || null;
    propsFromContext.onChange(updateValue);

    if (_lodash.default.isFunction(this.props.onSubmitChanges)) {
      this.props.onSubmitChanges(updateValue);
    }
  };

  _proto.onKeyPress = function onKeyPress(event) {
    if (event.charCode === ENTER_CHAR_CODE) {
      this.onSubmitChanges(event.target.value);
    }
  };

  _proto.onSuggestionSelected = function onSuggestionSelected(event, _ref2) {
    var suggestionValue = _ref2.suggestionValue;
    this.onSubmitChanges(suggestionValue);
  };

  _proto.onSuggestionsFetchRequested = function onSuggestionsFetchRequested(_ref3) {
    var _this3 = this;

    var value = _ref3.value;
    return Promise.resolve(this.getSuggestions(value)).then(function (suggestions) {
      return _this3.setState({
        suggestions: suggestions
      });
    });
  };

  _proto.onSuggestionsClearRequested = function onSuggestionsClearRequested() {
    this.setState({
      suggestions: []
    });
  };

  _proto.getSuggestions = function getSuggestions(query) {
    var _this4 = this;

    if (_lodash.default.isFunction(this.props.getSuggestions)) {
      return this.props.getSuggestions(query,
      /**innerFilter*/
      function (values) {
        return _this4.filterSuggestions(query, values);
      });
    } else {
      return this.filterSuggestions(query, this.props.values);
    }
  };

  _proto.renderSuggestion = function renderSuggestion(value, _ref4) {
    var query = _ref4.query;

    var regex = _Store.default.searchStringToRegExp(query);

    regex.lastIndex = 0;
    return (0, _utils.highlight)(regex, this.props.getSuggestionText(value));
  };

  _proto.render = function render() {
    var suggestions = this.state.suggestions;
    var inputProps = {
      placeholder: this.props.placeholder,
      name: this.props.name,
      onChange: this.onChange.bind(this),
      value: this.state.value,
      disabled: this.props.disabled,
      onBlur: this.handleBlur,
      onFocus: this.handleFocus,
      onKeyPress: this.onKeyPress.bind(this),
      autoFocus: this.props.autoFocus,
      maxLength: this.props.maxLength
    };
    var ariaDescId = this.props['aria-describedby'];

    if (ariaDescId) {
      inputProps['aria-describedby'] = ariaDescId;
    }

    var ariaLabel = this.props['aria-label'];

    if (ariaLabel) {
      inputProps['aria-label'] = ariaLabel;
    }

    var theme = {
      container: 'autosuggest-container',
      containerOpen: 'autosuggest-container-open',
      input: 'autosuggest-input',
      suggestionsContainer: 'autosuggest-suggestions-container',
      suggestionsList: 'autosuggest-suggestions-list',
      suggestion: 'autosuggest-suggestion',
      itemHighlighted: 'autosuggest-suggestion-focused',
      sectionContainer: 'autosuggest-section-container',
      sectionTitle: 'autosuggest-section-title'
    };
    return _react.default.createElement(_reactAutosuggest.default, {
      ref: "autoSuggest",
      suggestions: suggestions,
      onSuggestionsFetchRequested: this.onSuggestionsFetchRequested.bind(this),
      onSuggestionsClearRequested: this.onSuggestionsClearRequested.bind(this),
      getSuggestionValue: this.props.getSuggestionValue.bind(this),
      onSuggestionSelected: this.onSuggestionSelected.bind(this),
      renderSuggestion: this.renderSuggestion.bind(this),
      renderInputComponent: this.renderInputComponent,
      renderSuggestionsContainer: this.renderSuggestionsContainer,
      inputProps: inputProps,
      theme: theme
    });
  };

  return AutosuggestControl;
}(_FormControl2.FormControl);

exports.AutosuggestControl = AutosuggestControl;
(0, _defineProperty2.default)(AutosuggestControl, "propTypes", Object.assign({}, _FormControl2.FormControl.propTypes, {
  /* if getSuggestions() is provided values is not necessary */
  values: _propTypes.default.array,
  getSuggestionValue: _propTypes.default.func.isRequired,
  getSuggestionText: _propTypes.default.func.isRequired,
  valueMatcher: _propTypes.default.func,
  placeholder: _propTypes.default.string,
  maxSuggestionsCount: _propTypes.default.number,
  minCharactersToShowSuggestions: _propTypes.default.number,
  disabled: _propTypes.default.bool,
  allowMismatching: _propTypes.default.bool,

  /**
   * @function (query: String, innerFilter: function(values))
   * @returns { Array| Promise<Array>}
   * */
  getSuggestions: _propTypes.default.func,
  onSubmitChanges: _propTypes.default.func,
  autoFocus: _propTypes.default.bool,
  onInputChange: _propTypes.default.func,
  suggestionPromptLabel: _propTypes.default.string,
  noSuggestionPromptLabel: _propTypes.default.string
}));
(0, _defineProperty2.default)(AutosuggestControl, "defaultProps", Object.assign({}, _FormControl2.FormControl.defaultProps, {
  maxSuggestionsCount: 10,
  minCharactersToShowSuggestions: 2,
  valueMatcher: function valueMatcher(inputValue, value) {
    return inputValue === this.props.getSuggestionValue(value);
  },
  allowMismatching: false,
  onInputChange: function onInputChange(v) {
    return v;
  },
  suggestionPromptLabel: 'TRANSLATE:AUTO_SUGGEST_SUGGESTION_PROMPT_LABEL',
  noSuggestionPromptLabel: 'TRANSLATE:NO_SUGGESTION_PROMPT_LABEL'
}));