/**
 * @license
 * Copyright 2015 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '../../plugins/gr-endpoint-decorator/gr-endpoint-decorator';
import '../../plugins/gr-endpoint-param/gr-endpoint-param';
import '../../plugins/gr-endpoint-slot/gr-endpoint-slot';
import '../../shared/gr-account-chip/gr-account-chip';
import '../../shared/gr-button/gr-button';
import '../../shared/gr-icon/gr-icon';
import '../../shared/gr-formatted-text/gr-formatted-text';
import '../../shared/gr-account-list/gr-account-list';
import '../gr-label-scores/gr-label-scores';
import '../gr-thread-list/gr-thread-list';
import '../../../styles/shared-styles';
import {GrReviewerSuggestionsProvider} from '../../../services/gr-reviewer-suggestions-provider/gr-reviewer-suggestions-provider';
import {getAppContext} from '../../../services/app-context';
import {
  ChangeStatus,
  DraftsAction,
  ReviewerState,
  SpecialFilePath,
} from '../../../constants/constants';

import {
  AccountInfoInput,
  AccountInput,
  AccountInputDetail,
  getUserId,
  GroupInfoInput,
  isAccountNewlyAdded,
  RawAccountInput,
  removeServiceUsers,
  toReviewInput,
} from '../../../utils/account-util';
import {TargetElement} from '../../../api/plugin';
import {isDefined, ParsedChangeInfo} from '../../../types/types';
import {GrAccountList} from '../../shared/gr-account-list/gr-account-list';
import {
  AccountId,
  AccountInfo,
  AttentionSetInput,
  ChangeInfo,
  CommentThread,
  DraftInfo,
  GroupInfo,
  isAccount,
  isDetailedLabelInfo,
  isReviewerAccountSuggestion,
  isReviewerGroupSuggestion,
  ParsedJSON,
  ReviewerInput,
  ReviewInput,
  ReviewResult,
  ServerInfo,
  SuggestedReviewerGroupInfo,
  Suggestion,
  UserId,
  isDraft,
  ChangeViewChangeInfo,
} from '../../../types/common';
import {GrButton} from '../../shared/gr-button/gr-button';
import {GrLabelScores} from '../gr-label-scores/gr-label-scores';
import {GrLabelScoreRow} from '../gr-label-score-row/gr-label-score-row';
import {
  areSetsEqual,
  assertIsDefined,
  containsAll,
  difference,
  queryAndAssert,
} from '../../../utils/common-util';
import {
  getFirstComment,
  isPatchsetLevel,
  isUnresolved,
} from '../../../utils/comment-util';
import {GrAccountChip} from '../../shared/gr-account-chip/gr-account-chip';
import {
  getApprovalInfo,
  getMaxAccounts,
  StandardLabels,
} from '../../../utils/label-util';
import {pluralize} from '../../../utils/string-util';
import {
  fireAlert,
  fireError,
  fire,
  fireNoBubble,
  fireIronAnnounce,
  fireServerError,
} from '../../../utils/event-util';
import {ErrorCallback} from '../../../api/rest';
import {DelayedTask} from '../../../utils/async-util';
import {Interaction, Timing} from '../../../constants/reporting';
import {
  getMentionedReason,
  getReplyByReason,
} from '../../../utils/attention-set-util';
import {RestApiService} from '../../../services/gr-rest-api/gr-rest-api';
import {resolve} from '../../../models/dependency';
import {changeModelToken} from '../../../models/change/change-model';
import {
  ConfigInfo,
  LabelNameToValuesMap,
  PatchSetNumber,
} from '../../../api/rest-api';
import {css, html, PropertyValues, LitElement, nothing} from 'lit';
import {sharedStyles} from '../../../styles/shared-styles';
import {when} from 'lit/directives/when.js';
import {classMap} from 'lit/directives/class-map.js';
import {
  AddReviewerEvent,
  RemoveReviewerEvent,
  ValueChangedEvent,
} from '../../../types/events';
import {customElement, property, state, query} from 'lit/decorators.js';
import {subscribe} from '../../lit/subscription-controller';
import {configModelToken} from '../../../models/config/config-model';
import {hasHumanReviewer} from '../../../utils/change-util';
import {commentsModelToken} from '../../../models/comments/comments-model';
import {
  CommentEditingChangedDetail,
  GrComment,
} from '../../shared/gr-comment/gr-comment';
import {ShortcutController} from '../../lit/shortcut-controller';
import {Key, Modifier, whenVisible} from '../../../utils/dom-util';
import {GrThreadList} from '../gr-thread-list/gr-thread-list';
import {userModelToken} from '../../../models/user/user-model';
import {accountsModelToken} from '../../../models/accounts-model/accounts-model';
import {pluginLoaderToken} from '../../shared/gr-js-api-interface/gr-plugin-loader';
import {modalStyles} from '../../../styles/gr-modal-styles';
import {ironAnnouncerRequestAvailability} from '../../polymer-util';
import {GrReviewerUpdatesParser} from '../../shared/gr-rest-api-interface/gr-reviewer-updates-parser';

export enum FocusTarget {
  ANY = 'any',
  BODY = 'body',
  CCS = 'cc',
  REVIEWERS = 'reviewers',
}

enum ReviewerType {
  REVIEWER = 'REVIEWER',
  CC = 'CC',
}

enum LatestPatchState {
  LATEST = 'latest',
  CHECKING = 'checking',
  NOT_LATEST = 'not-latest',
}

const ButtonLabels = {
  START_REVIEW: 'Start review',
  SEND: 'Send',
};

const ButtonTooltips = {
  SAVE: 'Send changes and comments as work in progress but do not start review',
  START_REVIEW: 'Mark as ready for review and send reply',
  SEND: 'Send reply',
  DISABLED_COMMENT_EDITING: 'Save draft comments to enable send',
};

const EMPTY_REPLY_MESSAGE = 'Cannot send an empty reply.';

@customElement('gr-reply-dialog')
export class GrReplyDialog extends LitElement {
  FocusTarget = FocusTarget;

  private readonly reporting = getAppContext().reportingService;

  private readonly getChangeModel = resolve(this, changeModelToken);

  private readonly getCommentsModel = resolve(this, commentsModelToken);

  // TODO: update type to only ParsedChangeInfo
  @property({type: Object})
  change?: ParsedChangeInfo | ChangeInfo;

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

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

  @state()
  draftCommentThreads: CommentThread[] = [];

  @property({type: Object})
  permittedLabels?: LabelNameToValuesMap;

  @property({type: Object})
  projectConfig?: ConfigInfo;

  @query('#patchsetLevelComment') patchsetLevelGrComment?: GrComment;

  @query('#reviewers') reviewersList?: GrAccountList;

  @query('#ccs') ccsList?: GrAccountList;

  @query('#cancelButton') cancelButton?: GrButton;

  @query('#sendButton') sendButton?: GrButton;

  @query('#labelScores') labelScores?: GrLabelScores;

  @query('#reviewerConfirmationModal')
  reviewerConfirmationModal?: HTMLDialogElement;

  @state() latestPatchNum?: PatchSetNumber;

  @state() serverConfig?: ServerInfo;

  @state()
  patchsetLevelDraftMessage = '';

  @state()
  filterReviewerSuggestion: (input: Suggestion) => boolean;

  @state()
  filterCCSuggestion: (input: Suggestion) => boolean;

  @state()
  knownLatestState?: LatestPatchState;

  @state()
  underReview = true;

  @state()
  account?: AccountInfo;

  get ccs() {
    return [
      ...this._ccs,
      ...this.mentionedUsers.filter(v => !this.isAlreadyReviewerOrCC(v)),
    ];
  }

  /**
   * We pass the ccs object to AccountInput for modifying where it needs to
   * add a value to CC. The returned value contains both mentionedUsers and
   * normal ccs hence separate the two when setting ccs.
   */
  set ccs(ccs: AccountInput[]) {
    this._ccs = ccs.filter(
      cc =>
        !this.mentionedUsers.some(
          mentionedCC => getUserId(mentionedCC) === getUserId(cc)
        )
    );
    this.requestUpdate('ccs', ccs);
  }

  @state()
  _ccs: AccountInput[] = [];

  /**
   * Maintain a separate list of users added to cc due to being mentioned in
   * unresolved drafts.
   * If the draft is discarded or edited to remove the mention then we want to
   * remove the user from being added to CC.
   * Instead of figuring out when we should remove the mentioned user ie when
   * they get removed from the last comment, we recompute this property when
   * any of the draft comments change.
   * If we add the user to the existing ccs object then we cannot differentiate
   * if the user was added manually to CC or added due to being mentioned hence
   * we cannot reset the mentioned ccs when drafts change.
   */
  @state()
  mentionedUsers: AccountInput[] = [];

  @state()
  mentionedUsersInUnresolvedDrafts: AccountInfo[] = [];

  @state()
  attentionCcsCount = 0;

  @state()
  ccPendingConfirmation: SuggestedReviewerGroupInfo | null = null;

  @state()
  messagePlaceholder?: string;

  @state()
  uploader?: AccountInfo;

  @state()
  pendingConfirmationDetails: SuggestedReviewerGroupInfo | null = null;

  @state()
  includeComments = true;

  @state() reviewers: AccountInput[] = [];

  @state()
  reviewerPendingConfirmation: SuggestedReviewerGroupInfo | null = null;

  @state()
  savingComments = false;

  @state()
  reviewersMutated = false;

  /**
   * Signifies that the user has changed their vote on a label or (if they have
   * not yet voted on a label) if a selected vote is different from the default
   * vote.
   */
  @state()
  labelsChanged = false;

  @state()
  readonly saveTooltip: string = ButtonTooltips.SAVE;

  @state()
  pluginMessage = '';

  @state()
  commentEditing = false;

  @state()
  attentionExpanded = false;

  @state()
  currentAttentionSet: Set<UserId> = new Set();

  @state()
  newAttentionSet: Set<UserId> = new Set();

  @state()
  patchsetLevelDraftIsResolved = true;

  @state()
  patchsetLevelComment?: DraftInfo;

  @state()
  isOwner = false;

  private readonly restApiService: RestApiService =
    getAppContext().restApiService;

  private readonly getPluginLoader = resolve(this, pluginLoaderToken);

  private readonly getConfigModel = resolve(this, configModelToken);

  private readonly getAccountsModel = resolve(this, accountsModelToken);

  private readonly getUserModel = resolve(this, userModelToken);

  storeTask?: DelayedTask;

  private isLoggedIn = false;

  private readonly shortcuts = new ShortcutController(this);

  static override get styles() {
    return [
      sharedStyles,
      modalStyles,
      css`
        :host {
          background-color: var(--dialog-background-color);
          display: block;
          max-height: 90vh;
          --label-score-padding-left: var(--spacing-xl);
        }
        :host([disabled]) {
          pointer-events: none;
        }
        :host([disabled]) .container {
          opacity: 0.5;
        }
        section {
          border-top: 1px solid var(--border-color);
          flex-shrink: 0;
          padding: var(--spacing-m) var(--spacing-xl);
          width: 100%;
        }
        section.labelsContainer {
          /* We want the :hover highlight to extend to the border of the dialog. */
          padding: var(--spacing-m) 0;
        }
        .stickyBottom {
          background-color: var(--dialog-background-color);
          box-shadow: 0px 0px 8px 0px rgba(60, 64, 67, 0.15);
          margin-top: var(--spacing-s);
          bottom: 0;
          position: sticky;
          /* @see Issue 8602 */
          z-index: 1;
        }
        .stickyBottom.newReplyDialog {
          margin-top: unset;
        }
        .actions {
          display: flex;
          justify-content: space-between;
        }
        .actions .right gr-button {
          margin-left: var(--spacing-l);
        }
        .peopleContainer,
        .labelsContainer {
          flex-shrink: 0;
        }
        .peopleContainer {
          border-top: none;
          display: table;
        }
        .peopleList {
          display: flex;
        }
        .peopleListLabel {
          color: var(--deemphasized-text-color);
          margin-top: var(--spacing-xs);
          min-width: 6em;
          padding-right: var(--spacing-m);
        }
        gr-account-list {
          display: flex;
          flex-wrap: wrap;
          flex: 1;
        }
        #reviewerConfirmationModal {
          padding: var(--spacing-l);
          text-align: center;
        }
        .reviewerConfirmationButtons {
          margin-top: var(--spacing-l);
        }
        .groupName {
          font-weight: var(--font-weight-bold);
        }
        .groupSize {
          font-style: italic;
        }
        .textareaContainer {
          min-height: 12em;
          position: relative;
        }
        .newReplyDialog.textareaContainer {
          min-height: unset;
        }
        textareaContainer,
        gr-endpoint-decorator[name='reply-text'] {
          display: flex;
          width: 100%;
        }
        gr-endpoint-decorator[name='reply-text'] {
          flex-direction: column;
        }
        #checkingStatusLabel,
        #notLatestLabel {
          margin-left: var(--spacing-l);
        }
        #checkingStatusLabel {
          color: var(--deemphasized-text-color);
          font-style: italic;
        }
        #notLatestLabel,
        #savingLabel {
          color: var(--error-text-color);
        }
        #savingLabel {
          display: none;
        }
        #savingLabel.saving {
          display: inline;
        }
        #pluginMessage {
          color: var(--deemphasized-text-color);
          margin-left: var(--spacing-l);
          margin-bottom: var(--spacing-m);
        }
        #pluginMessage:empty {
          display: none;
        }
        .attention .edit-attention-button {
          vertical-align: top;
          --gr-button-padding: 0px 4px;
        }
        .attention .edit-attention-button gr-icon {
          color: inherit;
          /* The line-height:26px hack (see below) requires us to do this.
           Normally the gr-icon would account for a proper positioning
           within the standard line-height:20px context. */
          top: 5px;
        }
        .attention a,
        .attention-detail a {
          text-decoration: none;
        }
        .attentionSummary {
          display: flex;
          justify-content: space-between;
        }
        .attentionSummary {
          /* The account label for selection is misbehaving currently: It consumes
          26px height instead of 20px, which is the default line-height and thus
          the max that can be nicely fit into an inline layout flow. We
          acknowledge that using a fixed 26px value here is a hack and not a
          great solution. */
          line-height: 26px;
        }
        .attentionSummary gr-account-label,
        .attention-detail gr-account-label {
          --account-max-length: 120px;
          display: inline-block;
          padding: var(--spacing-xs) var(--spacing-m);
          user-select: none;
          --label-border-radius: 8px;
        }
        .attentionSummary gr-account-label {
          margin: 0 var(--spacing-xs);
          line-height: var(--line-height-normal);
          vertical-align: top;
        }
        .attention-detail .peopleListValues {
          line-height: calc(var(--line-height-normal) + 10px);
        }
        .attention-detail gr-account-label {
          line-height: var(--line-height-normal);
        }
        .attentionSummary gr-account-label:focus,
        .attention-detail gr-account-label:focus {
          outline: none;
        }
        .attentionSummary gr-account-label:hover,
        .attention-detail gr-account-label:hover {
          box-shadow: var(--elevation-level-1);
          cursor: pointer;
        }
        .attention-detail .attentionDetailsTitle {
          display: flex;
          justify-content: space-between;
        }
        .attention-detail .selectUsers {
          color: var(--deemphasized-text-color);
          margin-bottom: var(--spacing-m);
        }
        .attentionTip {
          padding: var(--spacing-m);
          border: 1px solid var(--border-color);
          border-radius: var(--border-radius);
          margin-top: var(--spacing-m);
          background-color: var(--line-item-highlight-color);
        }
        .attentionTip div gr-icon {
          margin-right: var(--spacing-s);
        }
        .patchsetLevelContainer {
          width: calc(min(80ch, 100%));
          border-radius: var(--border-radius);
          box-shadow: var(--elevation-level-2);
        }
        .patchsetLevelContainer.resolved {
          background-color: var(--comment-background-color);
        }
        .patchsetLevelContainer.unresolved {
          background-color: var(--unresolved-comment-background-color);
        }
        .privateVisiblityInfo {
          display: flex;
          justify-content: center;
          background-color: var(--info-background);
          padding: var(--spacing-s) 0;
        }
        .privateVisiblityInfo gr-icon {
          margin-right: var(--spacing-m);
          color: var(--info-foreground);
        }
      `,
    ];
  }

  constructor() {
    super();
    this.filterReviewerSuggestion =
      this.filterReviewerSuggestionGenerator(false);
    this.filterCCSuggestion = this.filterReviewerSuggestionGenerator(true);

    this.shortcuts.addLocal({key: Key.ESC}, () => this.cancel());
    this.shortcuts.addLocal(
      {key: Key.ENTER, modifiers: [Modifier.CTRL_KEY]},
      () => this.submit()
    );
    this.shortcuts.addLocal(
      {key: Key.ENTER, modifiers: [Modifier.META_KEY]},
      () => this.submit()
    );

    subscribe(
      this,
      () => this.getUserModel().loggedIn$,
      isLoggedIn => (this.isLoggedIn = isLoggedIn)
    );
    subscribe(
      this,
      () => this.getUserModel().account$,
      account => {
        this.account = account;
      }
    );
    subscribe(
      this,
      () => this.getConfigModel().serverConfig$,
      config => {
        this.serverConfig = config;
      }
    );
    subscribe(
      this,
      () => this.getChangeModel().change$,
      x => (this.change = x)
    );
    subscribe(
      this,
      () => this.getChangeModel().latestPatchNum$,
      x => (this.latestPatchNum = x)
    );
    subscribe(
      this,
      () => this.getChangeModel().isOwner$,
      x => (this.isOwner = x)
    );
    subscribe(
      this,
      () => this.getCommentsModel().mentionedUsersInDrafts$,
      x => {
        this.mentionedUsers = x;
        this.reviewersMutated =
          this.reviewersMutated || this.mentionedUsers.length > 0;
      }
    );
    subscribe(
      this,
      () => this.getCommentsModel().mentionedUsersInUnresolvedDrafts$,
      x => {
        this.mentionedUsersInUnresolvedDrafts = x.filter(
          v => !this.isAlreadyReviewerOrCC(v)
        );
      }
    );
    subscribe(
      this,
      () => this.getCommentsModel().patchsetLevelDrafts$,
      x => (this.patchsetLevelComment = x[0])
    );
    subscribe(
      this,
      () => this.getCommentsModel().draftThreadsSaved$,
      threads =>
        (this.draftCommentThreads = threads.filter(
          t => !(isDraft(getFirstComment(t)) && isPatchsetLevel(t))
        ))
    );
  }

  override connectedCallback() {
    super.connectedCallback();
    ironAnnouncerRequestAvailability();

    this.getPluginLoader().jsApiService.addElement(
      TargetElement.REPLY_DIALOG,
      this
    );

    this.addEventListener(
      'comment-editing-changed',
      (e: CustomEvent<CommentEditingChangedDetail>) => {
        // Patchset level comment is always in editing mode which means it would
        // set commentEditing = true and the send button would be permanently
        // disabled.
        if (e.detail.path === SpecialFilePath.PATCHSET_LEVEL_COMMENTS) return;
        const commentList = queryAndAssert<GrThreadList>(this, '#commentList');
        // It can be one or more comments were in editing mode. Wwitching one
        // thread in editing, we need to check if there are still other threads
        // in editing.
        this.commentEditing = Array.from(commentList.threadElements ?? []).some(
          thread => thread.editing
        );
      }
    );

    // Plugins on reply-reviewers endpoint can take advantage of these
    // events to add / remove reviewers

    this.addEventListener('add-reviewer', (e: AddReviewerEvent) => {
      const reviewer = e.detail.reviewer;
      // Only support account type, see more from:
      // elements/shared/gr-account-list/gr-account-list.js#addAccountItem
      this.reviewersList?.addAccountItem({
        account: reviewer,
        count: 1,
      });
    });

    this.addEventListener('remove-reviewer', (e: RemoveReviewerEvent) => {
      const reviewer = e.detail.reviewer;
      this.reviewersList?.removeAccount(reviewer);
    });
  }

  override willUpdate(changedProperties: PropertyValues) {
    if (changedProperties.has('ccPendingConfirmation')) {
      this.pendingConfirmationUpdated(this.ccPendingConfirmation);
    }
    if (changedProperties.has('reviewerPendingConfirmation')) {
      this.pendingConfirmationUpdated(this.reviewerPendingConfirmation);
    }
    if (changedProperties.has('change')) {
      this.computeUploader();
      this.rebuildReviewerArrays();
    }
    if (changedProperties.has('canBeStarted')) {
      this.computeMessagePlaceholder();
    }
    if (changedProperties.has('attentionExpanded')) {
      this.onAttentionExpandedChange();
    }
    if (
      changedProperties.has('account') ||
      changedProperties.has('reviewers') ||
      changedProperties.has('ccs') ||
      changedProperties.has('change') ||
      changedProperties.has('draftCommentThreads') ||
      changedProperties.has('mentionedUsersInUnresolvedDrafts') ||
      changedProperties.has('includeComments') ||
      changedProperties.has('labelsChanged') ||
      changedProperties.has('patchsetLevelDraftMessage') ||
      changedProperties.has('mentionedCCs')
    ) {
      this.computeNewAttention();
    }
  }

  override disconnectedCallback() {
    this.storeTask?.flush();
    super.disconnectedCallback();
  }

  override render() {
    if (!this.change) return;
    return html`
      <div tabindex="-1">
        <section class="peopleContainer">
          <gr-endpoint-decorator name="reply-reviewers">
            <gr-endpoint-param
              name="change"
              .value=${this.change}
            ></gr-endpoint-param>
            <gr-endpoint-param name="reviewers" .value=${[...this.reviewers]}>
            </gr-endpoint-param>
            ${this.renderReviewerList()}
            <gr-endpoint-slot name="below"></gr-endpoint-slot>
          </gr-endpoint-decorator>
          ${this.renderCCList()} ${this.renderReviewConfirmation()}
          ${this.renderPrivateVisiblityInfo()}
        </section>
        <section class="labelsContainer">${this.renderLabels()}</section>
        <section class="newReplyDialog textareaContainer">
          ${this.renderReplyText()}
        </section>
        ${this.renderDraftsSection()}
        <div class="stickyBottom newReplyDialog">
          <gr-endpoint-decorator name="reply-bottom">
            <gr-endpoint-param
              name="change"
              .value=${this.change}
            ></gr-endpoint-param>
            ${this.renderAttentionSummarySection()}
            ${this.renderAttentionDetailsSection()}
            <gr-endpoint-slot name="above-actions"></gr-endpoint-slot>
            ${this.renderActionsSection()}
          </gr-endpoint-decorator>
        </div>
      </div>
    `;
  }

  private renderReviewerList() {
    return html`
      <div class="peopleList">
        <div class="peopleListLabel">Reviewers</div>
        <gr-account-list
          id="reviewers"
          .accounts=${[...this.reviewers]}
          .change=${this.change}
          .reviewerState=${ReviewerState.REVIEWER}
          @account-added=${this.handleAccountAdded}
          @accounts-changed=${this.handleReviewersChanged}
          .removableValues=${this.change?.removable_reviewers}
          .filter=${this.filterReviewerSuggestion}
          .pendingConfirmation=${this.reviewerPendingConfirmation}
          @pending-confirmation-changed=${this
            .handleReviewersConfirmationChanged}
          .placeholder=${'Add reviewer...'}
          @account-text-changed=${this.handleAccountTextEntry}
          .suggestionsProvider=${this.getReviewerSuggestionsProvider(
            this.change
          )}
        >
        </gr-account-list>
        <gr-endpoint-slot name="right"></gr-endpoint-slot>
      </div>
    `;
  }

  private renderCCList() {
    return html`
      <div class="peopleList">
        <div class="peopleListLabel">CC</div>
        <gr-account-list
          id="ccs"
          .accounts=${[...this.ccs]}
          .change=${this.change}
          .reviewerState=${ReviewerState.CC}
          @account-added=${this.handleAccountAdded}
          @accounts-changed=${this.handleCcsChanged}
          .filter=${this.filterCCSuggestion}
          .pendingConfirmation=${this.ccPendingConfirmation}
          @pending-confirmation-changed=${this.handleCcsConfirmationChanged}
          allow-any-input
          .placeholder=${'Add CC...'}
          @account-text-changed=${this.handleAccountTextEntry}
          .suggestionsProvider=${this.getCcSuggestionsProvider(this.change)}
        >
        </gr-account-list>
      </div>
    `;
  }

  private renderReviewConfirmation() {
    return html`
      <dialog
        tabindex="-1"
        id="reviewerConfirmationModal"
        @close=${this.cancelPendingReviewer}
      >
        <div class="reviewerConfirmation">
          Group
          <span class="groupName">
            ${this.pendingConfirmationDetails?.group.name}
          </span>
          has
          <span class="groupSize">
            ${this.pendingConfirmationDetails?.count}
          </span>
          members.
          <br />
          Are you sure you want to add them all?
        </div>
        <div class="reviewerConfirmationButtons">
          <gr-button @click=${this.confirmPendingReviewer}>Yes</gr-button>
          <gr-button @click=${this.cancelPendingReviewer}>No</gr-button>
        </div>
      </dialog>
    `;
  }

  private renderPrivateVisiblityInfo() {
    const addedAccounts = [
      ...(this.reviewersList?.additions() ?? []),
      ...(this.ccsList?.additions() ?? []),
    ];
    if (!this.change?.is_private || !addedAccounts.length) return nothing;
    return html`
      <div class="privateVisiblityInfo">
        <gr-icon icon="info"></gr-icon>
        <div>
          Adding a reviewer/CC will make this private change visible to them
        </div>
      </div>
    `;
  }

  private renderLabels() {
    if (!this.change || !this.account || !this.permittedLabels) return;
    return html`
      <gr-endpoint-decorator name="reply-label-scores">
        <gr-label-scores
          id="labelScores"
          .account=${this.account}
          .change=${this.change}
          @labels-changed=${this._handleLabelsChanged}
          .permittedLabels=${this.permittedLabels}
        ></gr-label-scores>
        <gr-endpoint-param
          name="change"
          .value=${this.change}
        ></gr-endpoint-param>
      </gr-endpoint-decorator>
      <div id="pluginMessage">${this.pluginMessage}</div>
    `;
  }

  private renderPatchsetLevelComment() {
    if (!this.patchsetLevelComment) return nothing;
    return html`
      <gr-comment
        id="patchsetLevelComment"
        .comment=${this.patchsetLevelComment}
        .comments=${[this.patchsetLevelComment]}
        @comment-unresolved-changed=${(e: ValueChangedEvent<boolean>) => {
          this.patchsetLevelDraftIsResolved = !e.detail.value;
        }}
        @comment-text-changed=${(e: ValueChangedEvent<string>) => {
          this.patchsetLevelDraftMessage = e.detail.value;
          // See `addReplyTextChangedCallback` in `ChangeReplyPluginApi`.
          fire(e.currentTarget as HTMLElement, 'value-changed', e.detail);
        }}
        .messagePlaceholder=${this.messagePlaceholder}
        hide-header
        permanent-editing-mode
      ></gr-comment>
    `;
  }

  private renderReplyText() {
    if (!this.change) return;
    return html`
      <div
        class=${classMap({
          patchsetLevelContainer: true,
          [this.getUnresolvedPatchsetLevelClass(
            this.patchsetLevelDraftIsResolved
          )]: true,
        })}
      >
        <gr-endpoint-decorator name="reply-text">
          ${this.renderPatchsetLevelComment()}
          <gr-endpoint-param name="change" .value=${this.change}>
          </gr-endpoint-param>
        </gr-endpoint-decorator>
      </div>
    `;
  }

  private renderDraftsSection() {
    const threads = this.draftCommentThreads;
    if (!threads || threads.length === 0) return;
    return html`
      <section class="draftsContainer">
        <div class="includeComments">
          <input
            type="checkbox"
            id="includeComments"
            @change=${this.handleIncludeCommentsChanged}
            ?checked=${this.includeComments}
          />
          <label for="includeComments"
            >Publish ${this.computeDraftsTitle(threads)}</label
          >
        </div>
        ${when(
          this.includeComments,
          () => html`
            <gr-thread-list id="commentList" .threads=${threads} hide-dropdown>
            </gr-thread-list>
          `
        )}
        <span
          id="savingLabel"
          class=${this.computeSavingLabelClass(this.savingComments)}
        >
          Saving comments...
        </span>
      </section>
    `;
  }

  private renderAttentionSummarySection() {
    if (this.attentionExpanded) return;
    return html`
      <section class="attention">
        <div class="attentionSummary">
          <div>
            ${when(
              this.computeShowNoAttentionUpdate(),
              () => html` <span>${this.computeDoNotUpdateMessage()}</span> `
            )}
            ${when(
              !this.computeShowNoAttentionUpdate(),
              () => html`
                <span>Bring to attention of</span>
                ${this.computeNewAttentionAccounts().map(
                  account => html`
                    <gr-account-label
                      .account=${account}
                      .forceAttention=${this.computeHasNewAttention(account)}
                      .selected=${this.computeHasNewAttention(account)}
                      .hideHovercard=${true}
                      .selectionChipStyle=${true}
                      @click=${this.handleAttentionClick}
                    ></gr-account-label>
                  `
                )}
              `
            )}
            <gr-tooltip-content
              has-tooltip
              title=${this.computeAttentionButtonTitle()}
            >
              <gr-button
                class="edit-attention-button"
                @click=${this.handleAttentionModify}
                ?disabled=${this.isSendDisabled()}
                link
                position-below
                data-label="Edit"
                data-action-type="change"
                data-action-key="edit"
                role="button"
                tabindex="0"
              >
                <div>
                  <gr-icon icon="edit" filled small></gr-icon>
                  <span>Modify</span>
                </div>
              </gr-button>
            </gr-tooltip-content>
          </div>
          <div>
            <a
              href="https://gerrit-review.googlesource.com/Documentation/user-attention-set.html"
              target="_blank"
              rel="noopener noreferrer"
            >
              <gr-icon icon="help" title="read documentation"></gr-icon>
            </a>
          </div>
        </div>
      </section>
    `;
  }

  private renderAttentionDetailsSection() {
    if (!this.attentionExpanded) return;
    return html`
      <section class="attention-detail">
        <div class="attentionDetailsTitle">
          <div>
            <span>Modify attention to</span>
          </div>
          <div></div>
          <div>
            <a
              href="https://gerrit-review.googlesource.com/Documentation/user-attention-set.html"
              target="_blank"
              rel="noopener noreferrer"
            >
              <gr-icon icon="help" title="read documentation"></gr-icon>
            </a>
          </div>
        </div>
        <div class="selectUsers">
          <span
            >Select chips to set who will be in the attention set after sending
            this reply</span
          >
        </div>
        <div class="peopleList">
          <div class="peopleListLabel">Owner</div>
          <div class="peopleListValues">
            <gr-account-label
              .account=${this.change?.owner}
              ?forceAttention=${this.computeHasNewAttention(this.change?.owner)}
              .selected=${this.computeHasNewAttention(this.change?.owner)}
              .hideHovercard=${true}
              .selectionChipStyle=${true}
              @click=${this.handleAttentionClick}
            >
            </gr-account-label>
          </div>
        </div>
        ${when(
          this.uploader,
          () => html`
            <div class="peopleList">
              <div class="peopleListLabel">Uploader</div>
              <div class="peopleListValues">
                <gr-account-label
                  .account=${this.uploader}
                  ?forceAttention=${this.computeHasNewAttention(this.uploader)}
                  .selected=${this.computeHasNewAttention(this.uploader)}
                  .hideHovercard=${true}
                  .selectionChipStyle=${true}
                  @click=${this.handleAttentionClick}
                >
                </gr-account-label>
              </div>
            </div>
          `
        )}
        <div class="peopleList">
          <div class="peopleListLabel">Reviewers</div>
          <div class="peopleListValues">
            ${removeServiceUsers(this.reviewers).map(
              account => html`
                <gr-account-label
                  .account=${account}
                  ?forceAttention=${this.computeHasNewAttention(account)}
                  .selected=${this.computeHasNewAttention(account)}
                  .hideHovercard=${true}
                  .selectionChipStyle=${true}
                  @click=${this.handleAttentionClick}
                >
                </gr-account-label>
              `
            )}
          </div>
        </div>

        ${when(
          this.attentionCcsCount,
          () => html`
            <div class="peopleList">
              <div class="peopleListLabel">CC</div>
              <div class="peopleListValues">
                ${removeServiceUsers(this.ccs).map(
                  account => html`
                    <gr-account-label
                      .account=${account}
                      ?forceAttention=${this.computeHasNewAttention(account)}
                      .selected=${this.computeHasNewAttention(account)}
                      .hideHovercard=${true}
                      .selectionChipStyle=${true}
                      @click=${this.handleAttentionClick}
                    >
                    </gr-account-label>
                  `
                )}
              </div>
            </div>
          `
        )}
        ${when(
          this.computeShowAttentionTip(),
          () => html`
            <div class="attentionTip">
              <gr-icon icon="lightbulb"></gr-icon>
              Please be mindful of requiring attention from too many users.
            </div>
          `
        )}
      </section>
    `;
  }

  private renderActionsSection() {
    return html`
      <section class="actions">
        <div class="left">
          ${when(
            this.knownLatestState === LatestPatchState.CHECKING,
            () => html`
              <span id="checkingStatusLabel">
                Checking whether patch ${this.latestPatchNum} is latest...
              </span>
            `
          )}
          ${when(
            this.knownLatestState === LatestPatchState.NOT_LATEST,
            () => html`
              <span id="notLatestLabel">
                ${this.computePatchSetWarning()}
                <gr-button link @click=${this._reload}>Reload</gr-button>
              </span>
            `
          )}
        </div>
        <div class="right">
          <gr-button
            link
            id="cancelButton"
            class="action cancel"
            @click=${this.cancelTapHandler}
            >Cancel</gr-button
          >
          ${when(
            this.canBeStarted,
            () => html`
              <!-- Use 'Send' here as the change may only about reviewers / ccs
            and when this button is visible, the next button will always
            be 'Start review' -->
              <gr-tooltip-content has-tooltip title=${this.saveTooltip}>
                <gr-button
                  link
                  ?disabled=${this.knownLatestState ===
                  LatestPatchState.NOT_LATEST}
                  class="action save"
                  @click=${this.saveClickHandler}
                  >Send As WIP</gr-button
                >
              </gr-tooltip-content>
            `
          )}
          <gr-tooltip-content
            has-tooltip
            title=${this.computeSendButtonTooltip(
              this.canBeStarted,
              this.commentEditing
            )}
          >
            <gr-button
              id="sendButton"
              primary
              ?disabled=${this.isSendDisabled()}
              class="action send"
              @click=${this.sendClickHandler}
              >${this.canBeStarted
                ? ButtonLabels.SEND + ' and ' + ButtonLabels.START_REVIEW
                : ButtonLabels.SEND}
            </gr-button>
          </gr-tooltip-content>
        </div>
      </section>
    `;
  }

  /**
   * Note that this method is not actually *opening* the dialog. Opening and
   * showing the dialog is dealt with by the overlay. This method is used by the
   * change view for initializing the dialog after opening the overlay. Maybe it
   * should be called `onOpened()` or `initialize()`?
   */
  open(focusTarget?: FocusTarget) {
    assertIsDefined(this.change, 'change');
    this.knownLatestState = LatestPatchState.CHECKING;
    this.getChangeModel()
      .fetchChangeUpdates(this.change)
      .then(result => {
        this.knownLatestState = result.isLatest
          ? LatestPatchState.LATEST
          : LatestPatchState.NOT_LATEST;
      });

    this.focusOn(focusTarget);
    if (this.restApiService.hasPendingDiffDrafts()) {
      this.savingComments = true;
      this.restApiService.awaitPendingDiffDrafts().then(() => {
        fire(this, 'comment-refresh', {});
        this.savingComments = false;
      });
    }
  }

  hasDrafts() {
    return (
      this.patchsetLevelDraftMessage.length > 0 ||
      this.draftCommentThreads.length > 0
    );
  }

  override focus() {
    this.focusOn(FocusTarget.ANY);
  }

  private handleIncludeCommentsChanged(e: Event) {
    if (!(e.target instanceof HTMLInputElement)) return;
    this.includeComments = e.target.checked;
  }

  setLabelValue(label: string, value: string): void {
    const selectorEl =
      this.getLabelScores().shadowRoot?.querySelector<GrLabelScoreRow>(
        `gr-label-score-row[name="${label}"]`
      );
    selectorEl?.setSelectedValue(value);
  }

  getLabelValue(label: string) {
    const selectorEl =
      this.getLabelScores().shadowRoot?.querySelector<GrLabelScoreRow>(
        `gr-label-score-row[name="${label}"]`
      );
    return selectorEl?.selectedValue;
  }

  // TODO: Combine logic into handleReviewersChanged & handleCCsChanged and
  // remove account-added event from GrAccountList.
  handleAccountAdded(e: CustomEvent<AccountInputDetail>) {
    const account = e.detail.account;
    const key = getUserId(account);
    const reviewerType =
      (e.target as GrAccountList).getAttribute('id') === 'ccs'
        ? ReviewerType.CC
        : ReviewerType.REVIEWER;
    const isReviewer = ReviewerType.REVIEWER === reviewerType;
    const reviewerList = isReviewer ? this.ccsList : this.reviewersList;
    // Remove any accounts that already exist as a CC for reviewer
    // or vice versa.
    if (reviewerList?.removeAccount(account)) {
      const moveFrom = isReviewer ? 'CC' : 'reviewer';
      const moveTo = isReviewer ? 'reviewer' : 'CC';
      const id = account.name || key;
      const message = `${id} moved from ${moveFrom} to ${moveTo}.`;
      fireAlert(this, message);
    }
  }

  getUnresolvedPatchsetLevelClass(patchsetLevelDraftIsResolved: boolean) {
    return patchsetLevelDraftIsResolved ? 'resolved' : 'unresolved';
  }

  computeReviewers() {
    const reviewers: ReviewerInput[] = [];
    const reviewerAdditions = this.reviewersList?.additions() ?? [];
    reviewers.push(
      ...reviewerAdditions.map(v => toReviewInput(v, ReviewerState.REVIEWER))
    );

    const ccAdditions = this.ccsList?.additions() ?? [];
    reviewers.push(...ccAdditions.map(v => toReviewInput(v, ReviewerState.CC)));

    // ignore removal from reviewer request if being added as CC
    let removals = difference(
      this.reviewersList?.removals() ?? [],
      ccAdditions,
      (a, b) => getUserId(a) === getUserId(b)
    ).map(v => toReviewInput(v, ReviewerState.REMOVED));
    reviewers.push(...removals);

    // ignore removal from CC request if being added as reviewer
    removals = difference(
      this.ccsList?.removals() ?? [],
      reviewerAdditions,
      (a, b) => getUserId(a) === getUserId(b)
    ).map(v => toReviewInput(v, ReviewerState.REMOVED));
    reviewers.push(...removals);

    // The owner is returned as a reviewer in the ChangeInfo object in some
    // cases, and trying to remove the owner as a reviewer returns in a
    // 500 server error.
    return reviewers.filter(
      reviewerInput =>
        !(
          this.change?.owner._account_id === reviewerInput.reviewer &&
          reviewerInput.state === ReviewerState.REMOVED
        )
    );
  }

  // visible for testing
  async send(includeComments: boolean, startReview: boolean) {
    // The change model will end this timing when the change was reloaded.
    this.reporting.time(Timing.SEND_REPLY);
    const labels = this.getLabelScores().getLabelValues();

    const reviewInput: ReviewInput = {
      drafts: includeComments
        ? DraftsAction.PUBLISH_ALL_REVISIONS
        : DraftsAction.KEEP,
      labels,
    };

    if (startReview) {
      reviewInput.ready = true;
    } else if (this.change?.work_in_progress) {
      const addedAccounts = [
        ...(this.reviewersList?.additions() ?? []),
        ...(this.ccsList?.additions() ?? []),
      ];
      if (addedAccounts.length > 0) {
        fireAlert(this, 'Reviewers are not notified for WIP changes');
      }
    }

    this.disabled = true;

    const reason = getReplyByReason(this.account, this.serverConfig);

    reviewInput.ignore_automatic_attention_set_rules = true;
    reviewInput.add_to_attention_set = [];
    const allAccounts = this.allAccounts();

    const newAttentionSetAdditions: AccountInfo[] = Array.from(
      this.newAttentionSet
    )
      .filter(user => !this.currentAttentionSet.has(user))
      .map(user => allAccounts.find(a => getUserId(a) === user))
      .filter(isDefined);

    const newAttentionSetUsers = (
      await Promise.all(
        newAttentionSetAdditions.map(a =>
          this.getAccountsModel().fillDetails(a)
        )
      )
    ).filter(isDefined);

    for (const user of newAttentionSetUsers) {
      const reason =
        getMentionedReason(
          this.draftCommentThreads,
          this.account,
          user,
          this.serverConfig
        ) ?? '';
      reviewInput.add_to_attention_set.push({user: getUserId(user), reason});
    }
    reviewInput.remove_from_attention_set = [];
    for (const user of this.currentAttentionSet) {
      if (!this.newAttentionSet.has(user)) {
        reviewInput.remove_from_attention_set.push({user, reason});
      }
    }
    this.reportAttentionSetChanges(
      this.attentionExpanded,
      reviewInput.add_to_attention_set,
      reviewInput.remove_from_attention_set
    );

    if (this.patchsetLevelGrComment) {
      this.patchsetLevelGrComment.disableAutoSaving = true;
      await this.restApiService.awaitPendingDiffDrafts();
      const comment = this.patchsetLevelGrComment.convertToCommentInput();
      if (comment && comment.path && comment.message) {
        reviewInput.comments ??= {};
        reviewInput.comments[comment.path] ??= [];
        reviewInput.comments[comment.path].push(comment);
      }
    }

    assertIsDefined(this.change, 'change');
    reviewInput.reviewers = this.computeReviewers();

    const errFn = (r?: Response | null) => this.handle400Error(r);
    return this.saveReview(reviewInput, errFn)
      .then(result => {
        this.getChangeModel().updateStateChange(
          GrReviewerUpdatesParser.parse(
            result?.change_info as ChangeViewChangeInfo
          )
        );

        this.patchsetLevelDraftMessage = '';
        this.includeComments = true;
        fireNoBubble(this, 'send', {});
        fireIronAnnounce(this, 'Reply sent');
      })
      .finally(() => {
        this.disabled = false;
        if (this.patchsetLevelGrComment) {
          this.patchsetLevelGrComment.disableAutoSaving = false;
        }
        // By this point in time the change has loaded, we're only waiting for the comments.
        this.reporting.timeEnd(Timing.SEND_REPLY);
      });
  }

  focusOn(section?: FocusTarget) {
    // Safeguard- always want to focus on something.
    if (!section || section === FocusTarget.ANY) {
      section = this.chooseFocusTarget();
    }
    whenVisible(this, () => {
      if (section === FocusTarget.REVIEWERS) {
        const reviewerEntry = this.reviewersList?.focusStart;
        reviewerEntry?.focus();
      } else if (section === FocusTarget.CCS) {
        const ccEntry = this.ccsList?.focusStart;
        ccEntry?.focus();
      } else {
        this.patchsetLevelGrComment?.focus();
      }
    });
  }

  chooseFocusTarget() {
    if (!this.isOwner) return FocusTarget.BODY;
    if (hasHumanReviewer(this.change)) return FocusTarget.BODY;
    return FocusTarget.REVIEWERS;
  }

  handle400Error(r?: Response | null) {
    if (!r) throw new Error('Response is empty.');
    let response: Response = r;
    // A call to saveReview could fail with a server error if erroneous
    // reviewers were requested. This is signalled with a 400 Bad Request
    // status. The default gr-rest-api error handling would result in a large
    // JSON response body being displayed to the user in the gr-error-manager
    // toast.
    //
    // We can modify the error handling behavior by passing this function
    // through to restAPI as a custom error handling function. Since we're
    // short-circuiting restAPI we can do our own response parsing and fire
    // the server-error ourselves.
    //
    this.disabled = false;

    // Using response.clone() here, because getResponseObject() and
    // potentially the generic error handler will want to call text() on the
    // response object, which can only be done once per object.
    const jsonPromise = this.restApiService.getResponseObject(response.clone());
    return jsonPromise.then((parsed: ParsedJSON) => {
      const result = parsed as ReviewResult;
      // Only perform custom error handling for 400s and a parsable
      // ReviewResult response.
      if (response.status === 400 && result && result.reviewers) {
        const errors: string[] = [];
        const addReviewers = Object.values(result.reviewers);
        addReviewers.forEach(r => errors.push(r.error ?? 'no explanation'));
        response = {
          ...response,
          ok: false,
          text: () => Promise.resolve(errors.join(', ')),
        };
      }
      fireServerError(response);
    });
  }

  computeDraftsTitle(draftCommentThreads?: CommentThread[]) {
    const total = draftCommentThreads ? draftCommentThreads.length : 0;
    return pluralize(total, 'Draft');
  }

  computeMessagePlaceholder() {
    this.messagePlaceholder = this.canBeStarted
      ? 'Add a note for your reviewers...'
      : 'Say something nice...';
  }

  rebuildReviewerArrays() {
    if (!this.change?.owner || !this.change?.reviewers) return;
    const getAccounts = (state: ReviewerState) =>
      Object.values(this.change?.reviewers[state] ?? []).filter(
        account => account._account_id !== this.change!.owner._account_id
      );

    this.ccs = getAccounts(ReviewerState.CC);
    this.reviewers = getAccounts(ReviewerState.REVIEWER);
  }

  handleAttentionModify() {
    this.attentionExpanded = true;
  }

  onAttentionExpandedChange() {
    // If the attention-detail section is expanded without dispatching this
    // event, then the dialog may expand beyond the screen's bottom border.
    fire(this, 'iron-resize', {});
  }

  computeAttentionButtonTitle() {
    return this.isSendDisabled()
      ? 'Modify the attention set by adding a comment or use the account ' +
          'hovercard in the change page.'
      : 'Edit attention set changes';
  }

  handleAttentionClick(e: Event) {
    const targetAccount = (e.target as GrAccountChip)?.account;
    if (!targetAccount) return;
    const id = getUserId(targetAccount);
    if (!id || !this.account || !this.change?.owner) return;

    const self = id === getUserId(this.account) ? '_SELF' : '';
    const role = id === getUserId(this.change.owner) ? 'OWNER' : '_REVIEWER';

    if (this.newAttentionSet.has(id)) {
      this.newAttentionSet.delete(id);
      this.reporting.reportInteraction(Interaction.ATTENTION_SET_CHIP, {
        action: `REMOVE${self}${role}`,
      });
    } else {
      this.newAttentionSet.add(id);
      this.reporting.reportInteraction(Interaction.ATTENTION_SET_CHIP, {
        action: `ADD${self}${role}`,
      });
    }

    this.requestUpdate();
  }

  computeHasNewAttention(account?: AccountInfo) {
    return !!(account && this.newAttentionSet?.has(getUserId(account)));
  }

  computeNewAttention() {
    if (
      this.account?._account_id === undefined ||
      this.change === undefined ||
      this.includeComments === undefined
    ) {
      return;
    }
    // The draft comments are only relevant for the attention set as long as the
    // user actually plans to publish their drafts.
    const draftCommentThreads = this.includeComments
      ? this.draftCommentThreads
      : [];
    const hasVote = !!this.labelsChanged;
    const isUploader = this.uploader?._account_id === this.account._account_id;

    this.attentionCcsCount = removeServiceUsers(this.ccs).length;
    this.currentAttentionSet = new Set(
      Object.keys(this.change.attention_set || {}).map(
        id => Number(id) as AccountId
      )
    );
    const newAttention = new Set(this.currentAttentionSet);

    for (const user of this.mentionedUsersInUnresolvedDrafts) {
      newAttention.add(getUserId(user));
    }

    if (this.change.status === ChangeStatus.NEW) {
      // Add everyone that the user is replying to in a comment thread.
      this.computeCommentAccounts(draftCommentThreads).forEach(id =>
        newAttention.add(id)
      );
      // Remove the current user.
      newAttention.delete(this.account._account_id);
      // Add all new reviewers, but not the current reviewer, if they are also
      // sending a draft or a label vote.
      const notIsReviewerAndHasDraftOrLabel = (r: AccountInfo) =>
        !(
          r._account_id === this.account!._account_id &&
          (this.hasDrafts() || hasVote)
        );
      this.reviewers
        .filter(r => isAccount(r))
        .filter(
          r =>
            isAccountNewlyAdded(r, ReviewerState.REVIEWER, this.change) ||
            (this.canBeStarted && this.isOwner)
        )
        .filter(notIsReviewerAndHasDraftOrLabel)
        .forEach(r => newAttention.add((r as AccountInfo)._account_id!));
      // Add owner and uploader, if someone else replies.
      if (this.hasDrafts() || hasVote) {
        if (this.uploader?._account_id && !isUploader) {
          newAttention.add(this.uploader._account_id);
        }
        if (this.change.owner?._account_id && !this.isOwner) {
          newAttention.add(this.change.owner._account_id);
        }
      }
    } else {
      // The only reason for adding someone to the attention set for merged or
      // abandoned changes is that someone makes a comment thread unresolved.
      const hasUnresolvedDraft = draftCommentThreads.some(isUnresolved);
      if (this.change.owner && hasUnresolvedDraft) {
        // A change owner must have an account_id.
        newAttention.add(this.change.owner._account_id!);
      }
      // Remove the current user.
      newAttention.delete(this.account._account_id);
    }
    // Finally make sure that everyone in the attention set is still active as
    // owner, reviewer or cc.
    const allAccountIds = this.allAccounts()
      .map(a => getUserId(a))
      .filter(id => !!id);
    this.newAttentionSet = new Set([
      ...[...newAttention].filter(id => allAccountIds.includes(id)),
    ]);

    this.attentionExpanded = this.computeShowAttentionTip();
  }

  computeShowAttentionTip() {
    if (!this.currentAttentionSet || !this.newAttentionSet) return false;
    const addedIds = [...this.newAttentionSet].filter(
      id => !this.currentAttentionSet.has(id)
    );
    return this.isOwner && addedIds.length > 2;
  }

  computeCommentAccounts(threads: CommentThread[]) {
    const crLabel = this.change?.labels?.[StandardLabels.CODE_REVIEW];
    const maxCrVoteAccountIds = getMaxAccounts(crLabel).map(a => a._account_id);
    const accountIds = new Set<AccountId>();
    threads.forEach(thread => {
      const unresolved = isUnresolved(thread);
      thread.comments.forEach(comment => {
        if (comment.author) {
          // A comment author must have an account_id.
          const authorId = comment.author._account_id!;
          const hasGivenMaxReviewVote = maxCrVoteAccountIds.includes(authorId);
          if (unresolved || !hasGivenMaxReviewVote) accountIds.add(authorId);
        }
      });
    });
    return accountIds;
  }

  computeShowNoAttentionUpdate() {
    return (
      this.isSendDisabled() || this.computeNewAttentionAccounts().length === 0
    );
  }

  computeDoNotUpdateMessage() {
    if (!this.currentAttentionSet || !this.newAttentionSet) return '';
    if (
      this.isSendDisabled() ||
      areSetsEqual(this.currentAttentionSet, this.newAttentionSet)
    ) {
      return 'No changes to the attention set.';
    }
    if (containsAll(this.currentAttentionSet, this.newAttentionSet)) {
      return 'No additions to the attention set.';
    }
    this.reporting.error(
      'computeDoNotUpdateMessage',
      new Error(
        'computeDoNotUpdateMessage()' +
          'should not be called when users were added to the attention set.'
      )
    );
    return '';
  }

  computeNewAttentionAccounts(): AccountInfo[] {
    if (
      this.currentAttentionSet === undefined ||
      this.newAttentionSet === undefined
    ) {
      return [];
    }
    return [...this.newAttentionSet]
      .filter(id => !this.currentAttentionSet.has(id))
      .map(id => this.findAccountById(id))
      .filter(account => !!account) as AccountInfo[];
  }

  findAccountById(userId: UserId) {
    return this.allAccounts().find(r => getUserId(r) === userId);
  }

  allAccounts() {
    let allAccounts: (AccountInfoInput | GroupInfoInput)[] = [];
    if (this.change && this.change.owner) allAccounts.push(this.change.owner);
    if (this.uploader) allAccounts.push(this.uploader);
    if (this.reviewers) allAccounts = [...allAccounts, ...this.reviewers];
    if (this.ccs) allAccounts = [...allAccounts, ...this.ccs];
    return removeServiceUsers(allAccounts.filter(isAccount));
  }

  computeUploader() {
    if (
      !this.change?.current_revision ||
      !this.change?.revisions?.[this.change.current_revision]
    ) {
      this.uploader = undefined;
      return;
    }
    const rev = this.change.revisions[this.change.current_revision];

    if (
      !rev.uploader ||
      this.change?.owner._account_id === rev.uploader._account_id
    ) {
      this.uploader = undefined;
      return;
    }
    this.uploader = rev.uploader;
  }

  /**
   * Generates a function to filter out reviewer/CC entries. When isCCs is
   * truthy, the function filters out entries that already exist in this.ccs.
   * When falsy, the function filters entries that exist in this.reviewers.
   */
  filterReviewerSuggestionGenerator(
    isCCs: boolean
  ): (input: Suggestion) => boolean {
    return suggestion => {
      let entry: AccountInfo | GroupInfo;
      if (isReviewerAccountSuggestion(suggestion)) {
        entry = suggestion.account;
        if (entry._account_id === this.change?.owner?._account_id) {
          return false;
        }
      } else if (isReviewerGroupSuggestion(suggestion)) {
        entry = suggestion.group;
      } else {
        this.reporting.error(
          'Reviewer Suggestion',
          new Error(`Suggestion is neither account nor group: ${suggestion}`)
        );
        return false;
      }

      const key = getUserId(entry);
      const finder = (entry: AccountInfo | GroupInfo) =>
        getUserId(entry) === key;
      if (isCCs) {
        return this.ccs.find(finder) === undefined;
      }
      return this.reviewers.find(finder) === undefined;
    };
  }

  cancelTapHandler(e: Event) {
    e.preventDefault();
    this.cancel();
  }

  async cancel() {
    assertIsDefined(this.change, 'change');
    if (!this.change?.owner) throw new Error('missing required owner property');
    fireNoBubble(this, 'cancel', {});
    await this.patchsetLevelGrComment?.save();
    this.rebuildReviewerArrays();
  }

  private saveClickHandler(e: Event) {
    e.preventDefault();
    this.submit(false);
  }

  private sendClickHandler(e: Event) {
    e.preventDefault();
    this.submit(this.canBeStarted);
  }

  private submit(startReview?: boolean) {
    if (startReview === undefined) {
      startReview = this.isOwner && this.canBeStarted;
    }
    if (!this.ccsList?.submitEntryText()) {
      // Do not proceed with the send if there is an invalid email entry in
      // the text field of the CC entry.
      return;
    }
    if (this.isSendDisabled()) {
      fireAlert(this, EMPTY_REPLY_MESSAGE);
      return;
    }
    return this.send(this.includeComments, startReview).catch(err => {
      fireError(this, `Error submitting review ${err}`);
    });
  }

  saveReview(review: ReviewInput, errFn?: ErrorCallback) {
    assertIsDefined(this.change, 'change');
    assertIsDefined(this.latestPatchNum, 'latestPatchNum');
    return this.restApiService.saveChangeReview(
      this.change._number,
      this.latestPatchNum,
      review,
      errFn,
      true
    );
  }

  pendingConfirmationUpdated(reviewer: RawAccountInput | null) {
    if (reviewer === null) {
      this.reviewerConfirmationModal?.close();
    } else {
      this.pendingConfirmationDetails =
        this.ccPendingConfirmation || this.reviewerPendingConfirmation;
      this.reviewerConfirmationModal?.showModal();
    }
  }

  confirmPendingReviewer() {
    this.reviewerConfirmationModal?.close();
    if (this.ccPendingConfirmation) {
      this.ccsList?.confirmGroup(this.ccPendingConfirmation.group);
      this.focusOn(FocusTarget.CCS);
      return;
    }
    if (this.reviewerPendingConfirmation) {
      this.reviewersList?.confirmGroup(this.reviewerPendingConfirmation.group);
      this.focusOn(FocusTarget.REVIEWERS);
      return;
    }
    this.reporting.error(
      'confirmPendingReviewer',
      new Error('confirmPendingReviewer called without pending confirm')
    );
  }

  cancelPendingReviewer() {
    this.reviewerConfirmationModal?.close();
    this.ccPendingConfirmation = null;
    this.reviewerPendingConfirmation = null;

    const target = this.ccPendingConfirmation
      ? FocusTarget.CCS
      : FocusTarget.REVIEWERS;
    this.focusOn(target);
  }

  handleAccountTextEntry() {
    // When either of the account entries has input added to the autocomplete,
    // it should trigger the save button to enable/
    //
    // Note: if the text is removed, the save button will not get disabled.
    this.reviewersMutated = true;
  }

  private alreadyExists(ccs: AccountInput[], user: AccountInfoInput) {
    return ccs
      .filter(cc => isAccount(cc))
      .some(cc => getUserId(cc) === getUserId(user));
  }

  private isAlreadyReviewerOrCC(user: AccountInfo) {
    return (
      this.alreadyExists(this.reviewers, user) ||
      this.alreadyExists(this._ccs, user)
    );
  }

  getLabelScores(): GrLabelScores {
    return this.labelScores || queryAndAssert(this, 'gr-label-scores');
  }

  _handleLabelsChanged() {
    this.labelsChanged =
      Object.keys(this.getLabelScores().getLabelValues(false)).length !== 0;
  }

  handleReviewersChanged(e: ValueChangedEvent<(AccountInfo | GroupInfo)[]>) {
    this.reviewers = [...e.detail.value];
    this.reviewersMutated = true;
  }

  handleCcsChanged(e: ValueChangedEvent<(AccountInfo | GroupInfo)[]>) {
    this.ccs = [...e.detail.value];
    this.reviewersMutated = true;
  }

  handleReviewersConfirmationChanged(
    e: ValueChangedEvent<SuggestedReviewerGroupInfo | null>
  ) {
    this.reviewerPendingConfirmation = e.detail.value;
  }

  handleCcsConfirmationChanged(
    e: ValueChangedEvent<SuggestedReviewerGroupInfo | null>
  ) {
    this.ccPendingConfirmation = e.detail.value;
  }

  _reload() {
    this.getChangeModel().navigateToChangeResetReload();
    this.cancel();
  }

  computeSendButtonTooltip(canBeStarted?: boolean, commentEditing?: boolean) {
    if (commentEditing) {
      return ButtonTooltips.DISABLED_COMMENT_EDITING;
    }
    return canBeStarted ? ButtonTooltips.START_REVIEW : ButtonTooltips.SEND;
  }

  computeSavingLabelClass(savingComments: boolean) {
    return savingComments ? 'saving' : '';
  }

  // visible for testing
  isSendDisabled() {
    if (
      this.canBeStarted === undefined ||
      this.patchsetLevelDraftMessage === undefined ||
      this.reviewersMutated === undefined ||
      this.labelsChanged === undefined ||
      this.includeComments === undefined ||
      this.disabled === undefined ||
      this.commentEditing === undefined ||
      this.change?.labels === undefined ||
      this.account === undefined
    ) {
      return undefined;
    }
    if (this.commentEditing || this.disabled) {
      return true;
    }
    if (this.canBeStarted === true) {
      return false;
    }
    const existingVote = Object.values(this.change.labels).some(
      label =>
        isDetailedLabelInfo(label) && getApprovalInfo(label, this.account!)
    );
    const revotingOrNewVote = this.labelsChanged || existingVote;
    const hasDrafts =
      (this.includeComments && this.draftCommentThreads.length > 0) ||
      this.patchsetLevelDraftMessage.length > 0;
    return (
      !hasDrafts &&
      !this.patchsetLevelDraftMessage.length &&
      !this.reviewersMutated &&
      !revotingOrNewVote
    );
  }

  computePatchSetWarning() {
    let str = `Patch ${this.latestPatchNum} is not latest.`;
    if (this.labelsChanged) {
      str += ' Voting may have no effect.';
    }
    return str;
  }

  setPluginMessage(message: string) {
    this.pluginMessage = message;
  }

  getReviewerSuggestionsProvider(change?: ChangeInfo | ParsedChangeInfo) {
    if (!change) return;
    const provider = new GrReviewerSuggestionsProvider(
      this.restApiService,
      ReviewerState.REVIEWER,
      this.serverConfig,
      this.isLoggedIn,
      change
    );
    return provider;
  }

  getCcSuggestionsProvider(change?: ChangeInfo | ParsedChangeInfo) {
    if (!change) return;
    const provider = new GrReviewerSuggestionsProvider(
      this.restApiService,
      ReviewerState.CC,
      this.serverConfig,
      this.isLoggedIn,
      change
    );
    return provider;
  }

  reportAttentionSetChanges(
    modified: boolean,
    addedSet?: AttentionSetInput[],
    removedSet?: AttentionSetInput[]
  ) {
    const actions = modified ? ['MODIFIED'] : ['NOT_MODIFIED'];
    const ownerId =
      (this.change && this.change.owner && this.change.owner._account_id) || -1;
    const selfId = (this.account && this.account._account_id) || -1;
    for (const added of addedSet || []) {
      const addedId = added.user;
      const self = addedId === selfId ? '_SELF' : '';
      const role = addedId === ownerId ? 'OWNER' : '_REVIEWER';
      actions.push('ADD' + self + role);
    }
    for (const removed of removedSet || []) {
      const removedId = removed.user;
      const self = removedId === selfId ? '_SELF' : '';
      const role = removedId === ownerId ? 'OWNER' : '_REVIEWER';
      actions.push('REMOVE' + self + role);
    }
    this.reporting.reportInteraction('attention-set-actions', {actions});
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-reply-dialog': GrReplyDialog;
  }
  interface HTMLElementEventMap {
    /** Fired when the user presses the cancel button. */
    // prettier-ignore
    'cancel': CustomEvent<{}>;
    /**
     * Fires when the reply dialog believes that the server side diff drafts
     * have been updated and need to be refreshed.
     */
    'comment-refresh': CustomEvent<{}>;
    /** Fired when a reply is successfully sent. */
    // prettier-ignore
    'send': CustomEvent<{}>;
    /** Fires when the state of the send button (enabled/disabled) changes. */
    'send-disabled-changed': CustomEvent<{}>;
  }
}
