/**
 * @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.
 */
import '../../../scripts/bundled-polymer.js';

import '../gr-account-chip/gr-account-chip.js';
import '../gr-account-entry/gr-account-entry.js';
import '../../../styles/shared-styles.js';
import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners.js';
import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin.js';
import {PolymerElement} from '@polymer/polymer/polymer-element.js';
import {htmlTemplate} from './gr-account-list_html.js';

const VALID_EMAIL_ALERT = 'Please input a valid email.';

/**
 * @extends Polymer.Element
 */
class GrAccountList extends GestureEventListeners(
    LegacyElementMixin(PolymerElement)) {
  static get template() { return htmlTemplate; }

  static get is() { return 'gr-account-list'; }
  /**
   * Fired when user inputs an invalid email address.
   *
   * @event show-alert
   */

  static get properties() {
    return {
      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);
        },
      },

      /**
       * Set to true to disable suggestions on empty input.
       */
      skipSuggestOnEmpty: {
        type: Boolean,
        value: false,
      },
    };
  }

  /** @override */
  created() {
    super.created();
    this.addEventListener('remove',
        e => this._handleRemove(e));
  }

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

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

  _getSuggestions(input) {
    if (this.skipSuggestOnEmpty && !input) {
      return Promise.resolve([]);
    }
    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 => account._pendingAdd)
        .map(account => {
          if (account._group) {
            return {group: account};
          } else {
            return {account};
          }
        });
  }

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

customElements.define(GrAccountList.is, GrAccountList);
