'use strict';

import _extends from "@babel/runtime/helpers/extends";
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 { FormControl } from './FormControl';
import { default as ReactAutosuggest } from 'react-autosuggest';
import { TextInputControl } from './TextInputControl';
import { highlight } from '../list/utils';
import { default as Store } from '../../data/Store';
import { playMessage } from '../../utils/playMessage';
import { translate } from '../../../utils';
var ENTER_CHAR_CODE = 13;
var READ_KEY_DOWN_TIMEOUT = 1000;
export var AutosuggestControl =
/*#__PURE__*/
function (_FormControl) {
  _inheritsLoose(AutosuggestControl, _FormControl);

  function AutosuggestControl(_props, context) {
    var _this;

    _this = _FormControl.call(this, _props, context) || this;

    _defineProperty(_assertThisInitialized(_this), "handleFocus", function () {
      _this.setState({
        isInputFocused: true
      });
    });

    _defineProperty(_assertThisInitialized(_this), "handleBlur", function (event) {
      _this.onSubmitChanges(event.target.value);

      _this.setState({
        isInputFocused: false
      });
    });

    _defineProperty(_assertThisInitialized(_this), "playSuggestionPromptMessage", _.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 ? translate(noSuggestionPromptLabel, {
        count: count
      }) : translate(suggestionPromptLabel, {
        count: count
      });
      playMessage(message);
    }, READ_KEY_DOWN_TIMEOUT));

    _defineProperty(_assertThisInitialized(_this), "filterSuggestions", function (query, values) {
      if (query.length >= _this.props.minCharactersToShowSuggestions) {
        var regex = Store.searchStringToRegExp(query);
        var filteredValues = values.filter(function (value) {
          regex.lastIndex = 0;
          return regex.test(_this.props.getSuggestionText(value));
        });
        return _.take(filteredValues, _this.props.maxSuggestionsCount);
      } else {
        return [];
      }
    });

    _defineProperty(_assertThisInitialized(_this), "renderInputComponent", function (props) {
      return React.createElement(TextInputControl, props);
    });

    _defineProperty(_assertThisInitialized(_this), "renderSuggestionsContainer", function (renderOptions) {
      var containerProps = renderOptions.containerProps,
          children = renderOptions.children;
      return React.createElement("div", _extends({}, 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 _.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 (_.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 (_.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.searchStringToRegExp(query);
    regex.lastIndex = 0;
    return 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.createElement(ReactAutosuggest, {
      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;
}(FormControl);

_defineProperty(AutosuggestControl, "propTypes", Object.assign({}, FormControl.propTypes, {
  /* if getSuggestions() is provided values is not necessary */
  values: PropTypes.array,
  getSuggestionValue: PropTypes.func.isRequired,
  getSuggestionText: PropTypes.func.isRequired,
  valueMatcher: PropTypes.func,
  placeholder: PropTypes.string,
  maxSuggestionsCount: PropTypes.number,
  minCharactersToShowSuggestions: PropTypes.number,
  disabled: PropTypes.bool,
  allowMismatching: PropTypes.bool,

  /**
   * @function (query: String, innerFilter: function(values))
   * @returns { Array| Promise<Array>}
   * */
  getSuggestions: PropTypes.func,
  onSubmitChanges: PropTypes.func,
  autoFocus: PropTypes.bool,
  onInputChange: PropTypes.func,
  suggestionPromptLabel: PropTypes.string,
  noSuggestionPromptLabel: PropTypes.string
}));

_defineProperty(AutosuggestControl, "defaultProps", Object.assign({}, 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'
}));