/**
 * @license
 * Copyright (C) 2015 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 '../../shared/gr-account-chip/gr-account-chip';
import '../../shared/gr-button/gr-button';
import '../../../styles/shared-styles';
import {dom, EventApi} from '@polymer/polymer/lib/legacy/polymer.dom';
import {PolymerElement} from '@polymer/polymer/polymer-element';
import {htmlTemplate} from './gr-reviewer-list_html';
import {isSelf, isServiceUser} from '../../../utils/account-util';
import {hasAttention} from '../../../utils/attention-set-util';
import {customElement, property, computed, observe} from '@polymer/decorators';
import {
  ChangeInfo,
  ServerInfo,
  LabelNameToValueMap,
  AccountInfo,
  ApprovalInfo,
  Reviewers,
  AccountId,
  DetailedLabelInfo,
  EmailAddress,
  AccountDetailInfo,
} from '../../../types/common';
import {PolymerDeepPropertyChange} from '@polymer/polymer/interfaces';
import {GrAccountChip} from '../../shared/gr-account-chip/gr-account-chip';
import {hasOwnProperty} from '../../../utils/common-util';
import {isRemovableReviewer} from '../../../utils/change-util';
import {ReviewerState} from '../../../constants/constants';
import {appContext} from '../../../services/app-context';
import {KnownExperimentId} from '../../../services/flags/flags';

@customElement('gr-reviewer-list')
export class GrReviewerList extends PolymerElement {
  static get template() {
    return htmlTemplate;
  }

  /**
   * Fired when the "Add reviewer..." button is tapped.
   *
   * @event show-reply-dialog
   */

  @property({type: Object})
  change?: ChangeInfo;

  @property({type: Object})
  account?: AccountDetailInfo;

  @property({type: Object})
  serverConfig?: ServerInfo;

  @property({type: Boolean, reflectToAttribute: true})
  disabled = false;

  @property({type: Boolean})
  mutable = false;

  @property({type: Boolean})
  reviewersOnly = false;

  @property({type: Boolean})
  ccsOnly = false;

  @property({type: Array})
  _displayedReviewers: AccountInfo[] = [];

  @property({type: Array})
  _reviewers: AccountInfo[] = [];

  @property({type: Boolean})
  _showInput = false;

  @property({type: Object})
  _xhrPromise?: Promise<Response | undefined>;

  @property({type: Boolean})
  _isNewChangeSummaryUiEnabled = false;

  private readonly restApiService = appContext.restApiService;

  private readonly flagsService = appContext.flagsService;

  /** @override */
  ready() {
    super.ready();
    this._isNewChangeSummaryUiEnabled = this.flagsService.isEnabled(
      KnownExperimentId.NEW_CHANGE_SUMMARY_UI
    );
  }

  @computed('ccsOnly')
  get _addLabel() {
    return this.ccsOnly ? 'Add CC' : 'Add reviewer';
  }

  @computed('_reviewers', '_displayedReviewers')
  get _hiddenReviewerCount() {
    // Polymer 2: check for undefined
    if (
      this._reviewers === undefined ||
      this._displayedReviewers === undefined
    ) {
      return undefined;
    }
    return this._reviewers.length - this._displayedReviewers.length;
  }

  /**
   * Converts change.permitted_labels to an array of hashes of label keys to
   * numeric scores.
   * Example:
   * [{
   *   'Code-Review': ['-1', ' 0', '+1']
   * }]
   * will be converted to
   * [{
   *   label: 'Code-Review',
   *   scores: [-1, 0, 1]
   * }]
   */
  _permittedLabelsToNumericScores(labels: LabelNameToValueMap | undefined) {
    if (!labels) return [];
    return Object.keys(labels).map(label => {
      return {
        label,
        scores: labels[label].map(v => Number(v)),
      };
    });
  }

  /**
   * Returns hash of labels to max permitted score.
   *
   * @returns labels to max permitted scores hash
   */
  _getMaxPermittedScores(change: ChangeInfo) {
    return this._permittedLabelsToNumericScores(change.permitted_labels)
      .map(({label, scores}) => {
        return {
          [label]: scores.reduce((a, b) => Math.max(a, b)),
        };
      })
      .reduce((acc, i) => Object.assign(acc, i), {});
  }

  /**
   * Returns max permitted score for reviewer.
   */
  _getReviewerPermittedScore(
    reviewer: AccountInfo,
    change: ChangeInfo,
    label: string
  ) {
    // Note (issue 7874): sometimes the "all" list is not included in change
    // detail responses, even when DETAILED_LABELS is included in options.
    if (!change.labels) {
      return NaN;
    }
    const detailedLabel = change.labels[label] as DetailedLabelInfo;
    if (!detailedLabel.all) {
      return NaN;
    }
    const detailed = detailedLabel.all
      .filter(
        (approval: ApprovalInfo) =>
          reviewer._account_id === approval._account_id
      )
      .pop();
    if (!detailed) {
      return NaN;
    }
    if (hasOwnProperty(detailed, 'permitted_voting_range')) {
      if (!detailed.permitted_voting_range) return NaN;
      return detailed.permitted_voting_range.max;
    } else if (hasOwnProperty(detailed, 'value')) {
      // If preset, user can vote on the label.
      return 0;
    }
    return NaN;
  }

  _computeVoteableText(reviewer: AccountInfo, change: ChangeInfo) {
    if (!change || !change.labels) {
      return '';
    }
    const maxScores = [];
    const maxPermitted = this._getMaxPermittedScores(change);
    for (const label of Object.keys(change.labels)) {
      const maxScore = this._getReviewerPermittedScore(reviewer, change, label);
      if (isNaN(maxScore) || maxScore < 0) {
        continue;
      }
      if (maxScore > 0 && maxScore === maxPermitted[label]) {
        maxScores.push(`${label}: +${maxScore}`);
      } else {
        maxScores.push(`${label}`);
      }
    }
    return maxScores.join(', ');
  }

  @observe('change.reviewers.*', 'change.owner', 'serverConfig')
  _reviewersChanged(
    changeRecord: PolymerDeepPropertyChange<Reviewers, Reviewers>,
    owner: AccountInfo,
    serverConfig: ServerInfo
  ) {
    // Polymer 2: check for undefined
    if (
      changeRecord === undefined ||
      owner === undefined ||
      serverConfig === undefined ||
      this.change === undefined
    ) {
      return;
    }
    let result: AccountInfo[] = [];
    const reviewers = changeRecord.base;
    for (const key of Object.keys(reviewers)) {
      if (this.reviewersOnly && key !== 'REVIEWER') {
        continue;
      }
      if (this.ccsOnly && key !== 'CC') {
        continue;
      }
      if (key === 'REVIEWER' || key === 'CC') {
        result = result.concat(reviewers[key]!);
      }
    }
    this._reviewers = result
      .filter(reviewer => reviewer._account_id !== owner._account_id)
      // Sort order:
      // 1. The user themselves
      // 2. Human users in the attention set.
      // 3. Other human users.
      // 4. Service users.
      .sort((r1, r2) => {
        if (this.account) {
          if (isSelf(r1, this.account)) return -1;
          if (isSelf(r2, this.account)) return 1;
        }
        const a1 = hasAttention(serverConfig, r1, this.change!) ? 1 : 0;
        const a2 = hasAttention(serverConfig, r2, this.change!) ? 1 : 0;
        const s1 = isServiceUser(r1) ? -2 : 0;
        const s2 = isServiceUser(r2) ? -2 : 0;
        return a2 - a1 + s2 - s1;
      });

    if (this._reviewers.length > 8) {
      this._displayedReviewers = this._reviewers.slice(0, 6);
    } else {
      this._displayedReviewers = this._reviewers;
    }
  }

  _computeCanRemoveReviewer(reviewer: AccountInfo, mutable: boolean) {
    return mutable && isRemovableReviewer(this.change, reviewer);
  }

  _handleRemove(e: Event) {
    e.preventDefault();
    const target = (dom(e) as EventApi).rootTarget as GrAccountChip;
    if (!target.account || !this.change) {
      return;
    }
    const accountID = target.account._account_id || target.account.email;
    this.disabled = true;
    if (!accountID) return;
    this._xhrPromise = this._removeReviewer(accountID)
      .then((response: Response | undefined) => {
        this.disabled = false;
        if (!response || !response.ok) {
          return response;
        }
        if (!this.change || !this.change.reviewers) return;
        const reviewers = this.change.reviewers;
        for (const type of [ReviewerState.REVIEWER, ReviewerState.CC]) {
          const reviewerStateByType = reviewers[type] || [];
          reviewers[type] = reviewerStateByType;
          for (let i = 0; i < reviewerStateByType.length; i++) {
            if (
              reviewerStateByType[i]._account_id === accountID ||
              reviewerStateByType[i].email === accountID
            ) {
              this.splice('change.reviewers.' + type, i, 1);
              break;
            }
          }
        }
        return;
      })
      .catch((err: Error) => {
        this.disabled = false;
        throw err;
      });
  }

  _handleAddTap(e: Event) {
    e.preventDefault();
    const value = {
      reviewersOnly: false,
      ccsOnly: false,
    };
    if (this.reviewersOnly) {
      value.reviewersOnly = true;
    }
    if (this.ccsOnly) {
      value.ccsOnly = true;
    }
    this.dispatchEvent(
      new CustomEvent('show-reply-dialog', {
        detail: {value},
        composed: true,
        bubbles: true,
      })
    );
  }

  _handleViewAll() {
    this._displayedReviewers = this._reviewers;
  }

  _removeReviewer(id: AccountId | EmailAddress): Promise<Response | undefined> {
    if (!this.change) return Promise.resolve(undefined);
    return this.restApiService.removeChangeReviewer(this.change._number, id);
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-reviewer-list': GrReviewerList;
  }
}
