/**
 * @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 '../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';
import {appContext} from '../../../services/app-context.js';

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

/**
 * @extends PolymerElement
 */
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,
      },
    };
  }

  constructor() {
    super();
    this.reporting = appContext.reportingService;
  }

  /** @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.
    let itemTypeAdded = 'unknown';
    if (item.account) {
      const account =
          Object.assign({}, item.account, {_pendingAdd: true});
      this.push('accounts', account);
      itemTypeAdded = '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);
      itemTypeAdded = '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);
        itemTypeAdded = 'email';
      }
    }

    this.reporting.reportInteraction(`Add to ${this.id}`, {itemTypeAdded});
    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);
        this.reporting.reportInteraction(`Remove from ${this.id}`);
        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);
