/**
 * @license
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
(function() {
  'use strict';

  const TOKENIZE_REGEX = /(?:[^\s"]+|"[^"]*")+/g;
  const DEBOUNCE_WAIT_MS = 200;

  Polymer({
    is: 'gr-autocomplete',

    /**
     * Fired when a value is chosen.
     *
     * @event commit
     */

    /**
     * Fired when the user cancels.
     *
     * @event cancel
     */

    /**
     * Fired on keydown to allow for custom hooks into autocomplete textbox
     * behavior.
     *
     * @event input-keydown
     */

    properties: {

      /**
       * Query for requesting autocomplete suggestions. The function should
       * accept the input as a string parameter and return a promise. The
       * promise yields an array of suggestion objects with "name", "label",
       * "value" properties. The "name" property will be displayed in the
       * suggestion entry. The "label" property will, when specified, appear
       * next to the "name" as label text. The "value" property will be emitted
       * if that suggestion is selected.
       *
       * @type {function(string): Promise<?>}
       */
      query: {
        type: Function,
        value() {
          return function() {
            return Promise.resolve([]);
          };
        },
      },

      /**
       * The number of characters that must be typed before suggestions are
       * made. If threshold is zero, default suggestions are enabled.
       */
      threshold: {
        type: Number,
        value: 1,
      },

      allowNonSuggestedValues: Boolean,
      borderless: Boolean,
      disabled: Boolean,
      showSearchIcon: {
        type: Boolean,
        value: false,
      },
      // Vertical offset needed for a 1em font-size with no vertical padding.
      // Inputs with additional padding will need to increase vertical offset.
      verticalOffset: {
        type: Number,
        value: 20,
      },

      text: {
        type: String,
        value: '',
        notify: true,
      },

      placeholder: String,

      clearOnCommit: {
        type: Boolean,
        value: false,
      },

      /**
       * When true, tab key autocompletes but does not fire the commit event.
       * When false, tab key not caught, and focus is removed from the element.
       * See Issue 4556, Issue 6645.
       */
      tabComplete: {
        type: Boolean,
        value: false,
      },

      value: {
        type: String,
        notify: true,
      },

      /**
       * Multi mode appends autocompleted entries to the value.
       * If false, autocompleted entries replace value.
       */
      multi: {
        type: Boolean,
        value: false,
      },

      /**
       * When true and uncommitted text is left in the autocomplete input after
       * blurring, the text will appear red.
       */
      warnUncommitted: {
        type: Boolean,
        value: false,
      },

      /**
       * When true, querying for suggestions is not debounced w/r/t keypresses
       */
      noDebounce: {
        type: Boolean,
        value: false,
      },

      /** @type {?} */
      _suggestions: {
        type: Array,
        value() { return []; },
      },

      _suggestionEls: {
        type: Array,
        value() { return []; },
      },

      _index: Number,
      _disableSuggestions: {
        type: Boolean,
        value: false,
      },
      _focused: {
        type: Boolean,
        value: false,
      },

      /** The DOM element of the selected suggestion. */
      _selected: Object,
    },

    behaviors: [
      Gerrit.FireBehavior,
      Gerrit.KeyboardShortcutBehavior,
    ],

    observers: [
      '_maybeOpenDropdown(_suggestions, _focused)',
      '_updateSuggestions(text, threshold, noDebounce)',
    ],

    get _nativeInput() {
      // In Polymer 2 inputElement isn't nativeInput anymore
      return this.$.input.$.nativeInput || this.$.input.inputElement;
    },

    attached() {
      this.listen(document.body, 'click', '_handleBodyClick');
    },

    detached() {
      this.unlisten(document.body, 'click', '_handleBodyClick');
      this.cancelDebouncer('update-suggestions');
    },

    get focusStart() {
      return this.$.input;
    },

    focus() {
      this._nativeInput.focus();
    },

    selectAll() {
      const nativeInputElement = this._nativeInput;
      if (!this.$.input.value) { return; }
      nativeInputElement.setSelectionRange(0, this.$.input.value.length);
    },

    clear() {
      this.text = '';
    },

    _handleItemSelect(e) {
      // Let _handleKeydown deal with keyboard interaction.
      if (e.detail.trigger !== 'click') { return; }
      this._selected = e.detail.selected;
      this._commit();
    },

    get _inputElement() {
      // Polymer2: this.$ can be undefined when this is first evaluated.
      return this.$ && this.$.input;
    },

    /**
     * Set the text of the input without triggering the suggestion dropdown.
     * @param {string} text The new text for the input.
     */
    setText(text) {
      this._disableSuggestions = true;
      this.text = text;
      this._disableSuggestions = false;
    },

    _onInputFocus() {
      this._focused = true;
      this._updateSuggestions(this.text, this.threshold, this.noDebounce);
      this.$.input.classList.remove('warnUncommitted');
      // Needed so that --paper-input-container-input updated style is applied.
      this.updateStyles();
    },

    _onInputBlur() {
      this.$.input.classList.toggle('warnUncommitted',
          this.warnUncommitted && this.text.length && !this._focused);
      // Needed so that --paper-input-container-input updated style is applied.
      this.updateStyles();
    },

    _updateSuggestions(text, threshold, noDebounce) {
      // Polymer 2: check for undefined
      if ([text, threshold, noDebounce].some(arg => arg === undefined)) {
        return;
      }

      if (this._disableSuggestions) { return; }
      if (text.length < threshold) {
        this._suggestions = [];
        this.value = '';
        return;
      }

      const update = () => {
        this.query(text).then(suggestions => {
          if (text !== this.text) {
            // Late response.
            return;
          }
          for (const suggestion of suggestions) {
            suggestion.text = suggestion.name;
          }
          this._suggestions = suggestions;
          Polymer.dom.flush();
          if (this._index === -1) {
            this.value = '';
          }
        });
      };

      if (noDebounce) {
        update();
      } else {
        this.debounce('update-suggestions', update, DEBOUNCE_WAIT_MS);
      }
    },

    _maybeOpenDropdown(suggestions, focused) {
      if (suggestions.length > 0 && focused) {
        return this.$.suggestions.open();
      }
      return this.$.suggestions.close();
    },

    _computeClass(borderless) {
      return borderless ? 'borderless' : '';
    },

    /**
     * _handleKeydown used for key handling in the this.$.input AND all child
     * autocomplete options.
     */
    _handleKeydown(e) {
      this._focused = true;
      switch (e.keyCode) {
        case 38: // Up
          e.preventDefault();
          this.$.suggestions.cursorUp();
          break;
        case 40: // Down
          e.preventDefault();
          this.$.suggestions.cursorDown();
          break;
        case 27: // Escape
          e.preventDefault();
          this._cancel();
          break;
        case 9: // Tab
          if (this._suggestions.length > 0 && this.tabComplete) {
            e.preventDefault();
            this._handleInputCommit(true);
            this.focus();
          } else {
            this._focused = false;
          }
          break;
        case 13: // Enter
          if (this.modifierPressed(e)) { break; }
          e.preventDefault();
          this._handleInputCommit();
          break;
        default:
          // For any normal keypress, return focus to the input to allow for
          // unbroken user input.
          this.focus();

          // Since this has been a normal keypress, the suggestions will have
          // been based on a previous input. Clear them. This prevents an
          // outdated suggestion from being used if the input keystroke is
          // immediately followed by a commit keystroke. @see Issue 8655
          this._suggestions = [];
      }
      this.fire('input-keydown', {keyCode: e.keyCode, input: this.$.input});
    },

    _cancel() {
      if (this._suggestions.length) {
        this.set('_suggestions', []);
      } else {
        this.fire('cancel');
      }
    },

    /**
     * @param {boolean=} opt_tabComplete
     */
    _handleInputCommit(opt_tabComplete) {
      // Nothing to do if the dropdown is not open.
      if (!this.allowNonSuggestedValues
          && this.$.suggestions.isHidden) { return; }

      this._selected = this.$.suggestions.getCursorTarget();
      this._commit(opt_tabComplete);
    },

    _updateValue(suggestion, suggestions) {
      if (!suggestion) { return; }
      const completed = suggestions[suggestion.dataset.index].value;
      if (this.multi) {
        // Append the completed text to the end of the string.
        // Allow spaces within quoted terms.
        const tokens = this.text.match(TOKENIZE_REGEX);
        tokens[tokens.length - 1] = completed;
        this.value = tokens.join(' ');
      } else {
        this.value = completed;
      }
    },

    _handleBodyClick(e) {
      const eventPath = Polymer.dom(e).path;
      for (let i = 0; i < eventPath.length; i++) {
        if (eventPath[i] === this) {
          return;
        }
      }
      this._focused = false;
    },

    _handleSuggestionTap(e) {
      e.stopPropagation();
      this.$.cursor.setCursor(e.target);
      this._commit();
    },

    /**
     * Commits the suggestion, optionally firing the commit event.
     *
     * @param {boolean=} opt_silent Allows for silent committing of an
     *     autocomplete suggestion in order to handle cases like tab-to-complete
     *     without firing the commit event.
     */
    _commit(opt_silent) {
      // Allow values that are not in suggestion list iff suggestions are empty.
      if (this._suggestions.length > 0) {
        this._updateValue(this._selected, this._suggestions);
      } else {
        this.value = this.text || '';
      }

      const value = this.value;

      // Value and text are mirrors of each other in multi mode.
      if (this.multi) {
        this.setText(this.value);
      } else {
        if (!this.clearOnCommit && this._selected) {
          this.setText(this._suggestions[this._selected.dataset.index].name);
        } else {
          this.clear();
        }
      }

      this._suggestions = [];
      if (!opt_silent) {
        this.fire('commit', {value});
      }

      this._textChangedSinceCommit = false;
    },

    _computeShowSearchIconClass(showSearchIcon) {
      return showSearchIcon ? 'showSearchIcon' : '';
    },
  });
})();
