// Copyright (C) 2019 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() {
  Polymer({
    is: 'rv-reviewer',

    properties: {
      canModifyConfig: Boolean,
      pluginRestAPi: Object,
      repoName: String,
      reviewer: String,
      _reviewerSearchId: String,
      _queryReviewers: {
        type: Function,
        value() {
          return this._getReviewerSuggestions.bind(this);
        },
      },
      _originalReviewer: String,
      _deleted: Boolean,
      _editing: {
        type: Boolean,
        computed: '_computeEditing(reviewer, _originalReviewer)',
      },
    },

    attached() {
      this._originalReviewer = this.reviewer;
    },

    _computeReviewerDisabled(reviewer, _originalReviewer) {
      return !this._computeEditing(reviewer, _originalReviewer);
    },

    _computeEditing(reviewer, _originalReviewer) {
      if (_originalReviewer === '') {
        return true;
      }
      return reviewer === '';
    },

    _computeDeleteCancel(reviewer, _originalReviewer) {
      return this._computeEditing(reviewer, _originalReviewer) ?
      'Cancel' : 'Delete';
    },

    _computeHideAddButton(reviewer, _originalReviewer) {
      return !(this._computeEditing(reviewer, _originalReviewer)
      && this._reviewerSearchId);
    },

    _computeHideDeleteButton(canModifyConfig) {
      return !canModifyConfig;
    },

    _getReviewerSuggestions(input) {
      if (input.length === 0) { return Promise.resolve([]); }
      const promises = [];
      promises.push(this._getSuggestedGroups(input));
      promises.push(this._getSuggestedAccounts(input));
      return Promise.all(promises).then(result => {
        return result.flat();
      });
    },

    _getSuggestedGroups(input) {
      const suggestUrl = `/groups/?suggest=${input}&p=${this.repoName}`;
      return this.pluginRestApi.get(suggestUrl).then(groups => {
        if (!groups) { return []; }
        const groupSuggestions = [];
        for (const key in groups) {
          if (!groups.hasOwnProperty(key)) { continue; }
          groupSuggestions.push({
            name: key,
            value: key,
          });
        }
        return groupSuggestions;
      });
    },

    _getSuggestedAccounts(input) {
      const suggestUrl = `/accounts/?suggest&q=${input}`;
      return this.pluginRestApi.get(suggestUrl).then(accounts => {
        const accountSuggestions = [];
        let nameAndEmail;
        let value;
        if (!accounts) { return []; }
        for (const key in accounts) {
          if (!accounts.hasOwnProperty(key)) { continue; }
          if (accounts[key].email) {
            nameAndEmail = accounts[key].name +
              ' <' + accounts[key].email + '>';
          } else {
            nameAndEmail = accounts[key].name;
          }
          if (accounts[key].username) {
            value = accounts[key].username;
          } else if (accounts[key].email) {
            value = accounts[key].email;
          } else {
            value = accounts[key]._account_id;
          }
          accountSuggestions.push({
            name: nameAndEmail,
            value,
          });
        }
        return accountSuggestions;
      });
    },

    _handleDeleteCancel() {
      const detail = {editing: this._editing};
      if (this._editing) {
        this.remove();
      }
      this.dispatchEvent(
          new CustomEvent('reviewer-deleted', {detail, bubbles: true}));
    },

    _handleAddReviewer() {
      const detail = {reviewer: this._reviewerSearchId};
      this._originalReviewer = this.reviewer;
      this.dispatchEvent(
          new CustomEvent('reviewer-added', {detail, bubbles: true}));
    },
  });
})();
