/**
 * @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 VALID_EMAIL_ALERT = 'Please input a valid email.';

  Polymer({
    is: 'gr-account-list',

    /**
     * Fired when user inputs an invalid email address.
     *
     * @event show-alert
     */

    properties: {
      accounts: {
        type: Array,
        value() { return []; },
        notify: true,
      },
      change: Object,
      filter: Function,
      placeholder: String,
      disabled: {
        type: Function,
        value: false,
      },

      /**
       * Returns suggestions and convert them to list item
       * @type {Gerrit.GrSuggestionsProvider}
       */
      suggestionsProvider: {
        type: Object,
      },

      /**
       * Needed for template checking since value is initially set to null.
       * @type {?Object} */
      pendingConfirmation: {
        type: Object,
        value: null,
        notify: true,
      },
      readonly: {
        type: Boolean,
        value: false,
      },
      /**
       * When true, allows for non-suggested inputs to be added.
       */
      allowAnyInput: {
        type: Boolean,
        value: false,
      },

      /**
       * Array of values (groups/accounts) that are removable. When this prop is
       * undefined, all values are removable.
       */
      removableValues: Array,
      maxCount: {
        type: Number,
        value: 0,
      },

      /** Returns suggestion items
      * @type {!function(string): Promise<Array<Gerrit.GrSuggestionItem>>}
      */
      _querySuggestions: {
        type: Function,
        value() {
          return this._getSuggestions.bind(this);
        },
      },
    },

    behaviors: [
      // Used in the tests for gr-account-list and other elements tests.
      Gerrit.FireBehavior,
    ],

    listeners: {
      remove: '_handleRemove',
    },

    get accountChips() {
      return Array.from(
          Polymer.dom(this.root).querySelectorAll('gr-account-chip'));
    },

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

    _getSuggestions(input) {
      const provider = this.suggestionsProvider;
      if (!provider) {
        return Promise.resolve([]);
      }
      return provider.getSuggestions(input).then(suggestions => {
        if (!suggestions) { return []; }
        if (this.filter) {
          suggestions = suggestions.filter(this.filter);
        }
        return suggestions.map(suggestion =>
          provider.makeSuggestionItem(suggestion));
      });
    },

    _handleAdd(e) {
      this._addAccountItem(e.detail.value);
    },

    _addAccountItem(item) {
      // Append new account or group to the accounts property. We add our own
      // internal properties to the account/group here, so we clone the object
      // to avoid cluttering up the shared change object.
      if (item.account) {
        const account =
            Object.assign({}, item.account, {_pendingAdd: true});
        this.push('accounts', account);
      } else if (item.group) {
        if (item.confirm) {
          this.pendingConfirmation = item;
          return;
        }
        const group = Object.assign({}, item.group,
            {_pendingAdd: true, _group: true});
        this.push('accounts', group);
      } else if (this.allowAnyInput) {
        if (!item.includes('@')) {
          // Repopulate the input with what the user tried to enter and have
          // a toast tell them why they can't enter it.
          this.$.entry.setText(item);
          this.dispatchEvent(new CustomEvent('show-alert', {
            detail: {message: VALID_EMAIL_ALERT},
            bubbles: true,
            composed: true,
          }));
          return false;
        } else {
          const account = {email: item, _pendingAdd: true};
          this.push('accounts', account);
        }
      }
      this.pendingConfirmation = null;
      return true;
    },

    confirmGroup(group) {
      group = Object.assign(
          {}, group, {confirmed: true, _pendingAdd: true, _group: true});
      this.push('accounts', group);
      this.pendingConfirmation = null;
    },

    _computeChipClass(account) {
      const classes = [];
      if (account._group) {
        classes.push('group');
      }
      if (account._pendingAdd) {
        classes.push('pendingAdd');
      }
      return classes.join(' ');
    },

    _accountMatches(a, b) {
      if (a && b) {
        if (a._account_id) {
          return a._account_id === b._account_id;
        }
        if (a.email) {
          return a.email === b.email;
        }
      }
      return a === b;
    },

    _computeRemovable(account, readonly) {
      if (readonly) { return false; }
      if (this.removableValues) {
        for (let i = 0; i < this.removableValues.length; i++) {
          if (this._accountMatches(this.removableValues[i], account)) {
            return true;
          }
        }
        return !!account._pendingAdd;
      }
      return true;
    },

    _handleRemove(e) {
      const toRemove = e.detail.account;
      this._removeAccount(toRemove);
      this.$.entry.focus();
    },

    _removeAccount(toRemove) {
      if (!toRemove || !this._computeRemovable(toRemove, this.readonly)) {
        return;
      }
      for (let i = 0; i < this.accounts.length; i++) {
        let matches;
        const account = this.accounts[i];
        if (toRemove._group) {
          matches = toRemove.id === account.id;
        } else {
          matches = this._accountMatches(toRemove, account);
        }
        if (matches) {
          this.splice('accounts', i, 1);
          return;
        }
      }
      console.warn('received remove event for missing account', toRemove);
    },

    _getNativeInput(paperInput) {
      // In Polymer 2 inputElement isn't nativeInput anymore
      return paperInput.$.nativeInput || paperInput.inputElement;
    },

    _handleInputKeydown(e) {
      const input = this._getNativeInput(e.detail.input);
      if (input.selectionStart !== input.selectionEnd ||
          input.selectionStart !== 0) {
        return;
      }
      switch (e.detail.keyCode) {
        case 8: // Backspace
          this._removeAccount(this.accounts[this.accounts.length - 1]);
          break;
        case 37: // Left arrow
          if (this.accountChips[this.accountChips.length - 1]) {
            this.accountChips[this.accountChips.length - 1].focus();
          }
          break;
      }
    },

    _handleChipKeydown(e) {
      const chip = e.target;
      const chips = this.accountChips;
      const index = chips.indexOf(chip);
      switch (e.keyCode) {
        case 8: // Backspace
        case 13: // Enter
        case 32: // Spacebar
        case 46: // Delete
          this._removeAccount(chip.account);
          // Splice from this array to avoid inconsistent ordering of
          // event handling.
          chips.splice(index, 1);
          if (index < chips.length) {
            chips[index].focus();
          } else if (index > 0) {
            chips[index - 1].focus();
          } else {
            this.$.entry.focus();
          }
          break;
        case 37: // Left arrow
          if (index > 0) {
            chip.blur();
            chips[index - 1].focus();
          }
          break;
        case 39: // Right arrow
          chip.blur();
          if (index < chips.length - 1) {
            chips[index + 1].focus();
          } else {
            this.$.entry.focus();
          }
          break;
      }
    },

    /**
     * Submit the text of the entry as a reviewer value, if it exists. If it is
     * a successful submit of the text, clear the entry value.
     *
     * @return {boolean} If there is text in the entry, return true if the
     *     submission was successful and false if not. If there is no text,
     *     return true.
     */
    submitEntryText() {
      const text = this.$.entry.getText();
      if (!text.length) { return true; }
      const wasSubmitted = this._addAccountItem(text);
      if (wasSubmitted) { this.$.entry.clear(); }
      return wasSubmitted;
    },

    additions() {
      return this.accounts.filter(account => {
        return account._pendingAdd;
      }).map(account => {
        if (account._group) {
          return {group: account};
        } else {
          return {account};
        }
      });
    },

    _computeEntryHidden(maxCount, accountsRecord, readonly) {
      return (maxCount && maxCount <= accountsRecord.base.length) || readonly;
    },
  });
})();
