/**
 * @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 {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(
        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 =
          {...item.account, _pendingAdd: true};
      this.push('accounts', account);
      itemTypeAdded = 'account';
    } else if (item.group) {
      if (item.confirm) {
        this.pendingConfirmation = item;
        return;
      }
      const group = {...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 = {
      ...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);
