/**
 * @license
 * Copyright 2022 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import {css, html, LitElement, nothing} from 'lit';
import {customElement, query, state} from 'lit/decorators.js';
import {ProgressStatus, ReviewerState} from '../../../constants/constants';
import {bulkActionsModelToken} from '../../../models/bulk-actions/bulk-actions-model';
import {configModelToken} from '../../../models/config/config-model';
import {resolve} from '../../../models/dependency';
import {
  AccountDetailInfo,
  AccountInfo,
  ChangeInfo,
  NumericChangeId,
  ServerInfo,
  SuggestedReviewerGroupInfo,
} from '../../../types/common';
import {subscribe} from '../../lit/subscription-controller';
import '../../shared/gr-dialog/gr-dialog';
import '../../shared/gr-button/gr-button';
import '../../shared/gr-icon/gr-icon';
import {getAppContext} from '../../../services/app-context';
import {
  GrReviewerSuggestionsProvider,
  ReviewerSuggestionsProvider,
} from '../../../services/gr-reviewer-suggestions-provider/gr-reviewer-suggestions-provider';
import '../../shared/gr-account-list/gr-account-list';
import {getOverallStatus} from '../../../utils/bulk-flow-util';
import {allSettled} from '../../../utils/async-util';
import {listForSentence, pluralize} from '../../../utils/string-util';
import {getDisplayName} from '../../../utils/display-name-util';
import {GrAccountList} from '../../shared/gr-account-list/gr-account-list';
import {getReplyByReason} from '../../../utils/attention-set-util';
import {intersection} from '../../../utils/common-util';
import {AccountInput, accountKey, getUserId} from '../../../utils/account-util';
import {ValueChangedEvent} from '../../../types/events';
import {fireAlert, fireReload} from '../../../utils/event-util';
import {GrDialog} from '../../shared/gr-dialog/gr-dialog';
import {Interaction} from '../../../constants/reporting';
import {userModelToken} from '../../../models/user/user-model';
import {modalStyles} from '../../../styles/gr-modal-styles';

@customElement('gr-change-list-reviewer-flow')
export class GrChangeListReviewerFlow extends LitElement {
  @state() private selectedChanges: ChangeInfo[] = [];

  // contents are given to gr-account-lists to mutate
  // private but used in tests
  @state() updatedAccountsByReviewerState: Map<ReviewerState, AccountInput[]> =
    new Map([
      [ReviewerState.REVIEWER, []],
      [ReviewerState.CC, []],
    ]);

  @state() private suggestionsProviderByReviewerState: Map<
    ReviewerState,
    ReviewerSuggestionsProvider
  > = new Map();

  @state() private progressByChangeNum = new Map<
    NumericChangeId,
    ProgressStatus
  >();

  @state() private isOverlayOpen = false;

  @state() private serverConfig?: ServerInfo;

  @state()
  private groupPendingConfirmationByReviewerState: Map<
    ReviewerState,
    SuggestedReviewerGroupInfo | null
  > = new Map([
    [ReviewerState.REVIEWER, null],
    [ReviewerState.CC, null],
  ]);

  @query('dialog#flow') private modal?: HTMLDialogElement;

  @query('gr-account-list#reviewer-list') private reviewerList?: GrAccountList;

  @query('gr-account-list#cc-list') private ccList?: GrAccountList;

  @query('dialog#confirm-reviewer')
  private reviewerConfirmModal?: HTMLDialogElement;

  @query('dialog#confirm-cc') private ccConfirmModal?: HTMLDialogElement;

  @query('gr-dialog') dialog?: GrDialog;

  private readonly reportingService = getAppContext().reportingService;

  private readonly getBulkActionsModel = resolve(this, bulkActionsModelToken);

  private readonly getConfigModel = resolve(this, configModelToken);

  private readonly getUserModel = resolve(this, userModelToken);

  private restApiService = getAppContext().restApiService;

  private isLoggedIn = false;

  private account?: AccountDetailInfo;

  static override get styles() {
    return [
      modalStyles,
      css`
        gr-dialog {
          width: 60em;
        }
        .grid {
          display: grid;
          grid-template-columns: min-content 1fr;
          column-gap: var(--spacing-l);
        }
        gr-account-list {
          display: flex;
          flex-wrap: wrap;
        }
        .warning,
        .error {
          display: flex;
          align-items: center;
          gap: var(--spacing-xl);
          padding: var(--spacing-l);
          padding-left: var(--spacing-xl);
          background-color: var(--yellow-50);
        }
        .error {
          background-color: var(--error-background);
        }
        .grid + .warning,
        .error {
          margin-top: var(--spacing-l);
        }
        .warning + .warning {
          margin-top: var(--spacing-s);
        }
        gr-icon {
          color: var(--orange-800);
          font-size: 18px;
        }
        dialog#confirm-cc,
        dialog#confirm-reviewer {
          padding: var(--spacing-l);
          text-align: center;
        }
        .confirmation-buttons {
          margin-top: var(--spacing-l);
        }
      `,
    ];
  }

  constructor() {
    super();
    subscribe(
      this,
      () => this.getBulkActionsModel().selectedChanges$,
      selectedChanges => (this.selectedChanges = selectedChanges)
    );
    subscribe(
      this,
      () => this.getConfigModel().serverConfig$,
      serverConfig => (this.serverConfig = serverConfig)
    );
    subscribe(
      this,
      () => this.getUserModel().loggedIn$,
      isLoggedIn => (this.isLoggedIn = isLoggedIn)
    );
    subscribe(
      this,
      () => this.getUserModel().account$,
      account => (this.account = account)
    );
  }

  override render() {
    return html`
      <gr-button
        id="start-flow"
        .disabled=${this.isFlowDisabled()}
        flatten
        @click=${() => this.openOverlay()}
        >add reviewer/cc</gr-button
      >
      <dialog id="flow" tabindex="-1">
        ${this.isOverlayOpen ? this.renderDialog() : nothing}
      </dialog>
    `;
  }

  private renderDialog() {
    const overallStatus = getOverallStatus(this.progressByChangeNum);
    return html`
      <gr-dialog
        @cancel=${() => this.closeOverlay()}
        @confirm=${() => this.onConfirm(overallStatus)}
        .confirmLabel=${'Add'}
        .disabled=${overallStatus === ProgressStatus.RUNNING}
        .loadingLabel=${'Adding Reviewer and CC in progress...'}
        ?loading=${getOverallStatus(this.progressByChangeNum) ===
        ProgressStatus.RUNNING}
      >
        <div slot="header">Add reviewer / CC</div>
        <div slot="main">
          <div class="grid">
            <span>Reviewers</span>
            ${this.renderAccountList(
              ReviewerState.REVIEWER,
              'reviewer-list',
              'Add reviewer'
            )}
            <span>CC</span>
            ${this.renderAccountList(ReviewerState.CC, 'cc-list', 'Add CC')}
          </div>
          ${this.renderAnyOverwriteWarnings()} ${this.renderErrors()}
        </div>
      </gr-dialog>
    `;
  }

  private renderAccountList(
    reviewerState: ReviewerState,
    id: string,
    placeholder: string
  ) {
    const updatedAccounts =
      this.updatedAccountsByReviewerState.get(reviewerState);
    const suggestionsProvider =
      this.suggestionsProviderByReviewerState.get(reviewerState);
    if (!updatedAccounts || !suggestionsProvider) {
      return;
    }
    return html`
      <gr-account-list
        id=${id}
        .accounts=${updatedAccounts}
        .removableValues=${[]}
        .suggestionsProvider=${suggestionsProvider}
        .placeholder=${placeholder}
        .pendingConfirmation=${this.groupPendingConfirmationByReviewerState.get(
          reviewerState
        )}
        @accounts-changed=${() => this.onAccountsChanged(reviewerState)}
        @pending-confirmation-changed=${(
          ev: ValueChangedEvent<SuggestedReviewerGroupInfo | null>
        ) => this.onPendingConfirmationChanged(reviewerState, ev)}
      >
      </gr-account-list>
      ${this.renderConfirmationDialog(reviewerState)}
    `;
  }

  private renderConfirmationDialog(reviewerState: ReviewerState) {
    const id =
      reviewerState === ReviewerState.CC ? 'confirm-cc' : 'confirm-reviewer';
    const suggestion =
      this.groupPendingConfirmationByReviewerState.get(reviewerState);
    return html`
      <dialog
        tabindex="-1"
        id=${id}
        @close=${() => this.cancelPendingGroup(reviewerState)}
      >
        <div class="confirmation-text">
          Group
          <span class="groupName"> ${suggestion?.group.name} </span>
          has
          <span class="groupSize"> ${suggestion?.count} </span>
          members.
          <br />
          Are you sure you want to add them all?
        </div>
        <div class="confirmation-buttons">
          <gr-button
            @click=${() => this.confirmPendingGroup(reviewerState, suggestion)}
            >Yes</gr-button
          >
          <gr-button @click=${() => this.cancelPendingGroup(reviewerState)}
            >No</gr-button
          >
        </div>
      </dialog>
    `;
  }

  private renderAnyOverwriteWarnings() {
    return html`
      ${this.renderAnyOverwriteWarning(ReviewerState.REVIEWER)}
      ${this.renderAnyOverwriteWarning(ReviewerState.CC)}
    `;
  }

  private renderErrors() {
    if (getOverallStatus(this.progressByChangeNum) !== ProgressStatus.FAILED)
      return nothing;
    const failedAccounts = [
      ...(this.updatedAccountsByReviewerState.get(ReviewerState.REVIEWER) ??
        []),
      ...(this.updatedAccountsByReviewerState.get(ReviewerState.CC) ?? []),
    ].map(account => getDisplayName(this.serverConfig, account));
    if (failedAccounts.length === 0) {
      return nothing;
    }
    return html`
      <div class="error">
        <gr-icon icon="error" filled role="img" aria-label="Error"></gr-icon>
        Failed to add ${listForSentence(failedAccounts)} to changes.
      </div>
    `;
  }

  private renderAnyOverwriteWarning(currentReviewerState: ReviewerState) {
    const updatedReviewerState =
      currentReviewerState === ReviewerState.CC
        ? ReviewerState.REVIEWER
        : ReviewerState.CC;
    const overwrittenNames =
      this.getOverwrittenDisplayNames(currentReviewerState);
    if (overwrittenNames.length === 0) {
      return nothing;
    }
    const pluralizedVerb = overwrittenNames.length === 1 ? 'is a' : 'are';
    const currentLabel = `${
      currentReviewerState === ReviewerState.CC ? 'CC' : 'reviewer'
    }${overwrittenNames.length > 1 ? 's' : ''}`;
    const updatedLabel =
      updatedReviewerState === ReviewerState.CC ? 'CC' : 'reviewer';
    return html`
      <div class="warning">
        <gr-icon
          icon="warning"
          filled
          role="img"
          aria-label="Warning"
        ></gr-icon>
        ${listForSentence(overwrittenNames)} ${pluralizedVerb} ${currentLabel}
        on some selected changes and will be moved to ${updatedLabel} on all
        changes.
      </div>
    `;
  }

  private getAccountsInCurrentState(currentReviewerState: ReviewerState) {
    return this.selectedChanges
      .flatMap(
        change =>
          change.reviewers[currentReviewerState]?.filter(isNotOwner(change)) ??
          []
      )
      .filter(account => account?._account_id !== undefined);
  }

  private getOverwrittenDisplayNames(
    currentReviewerState: ReviewerState
  ): string[] {
    const updatedReviewerState =
      currentReviewerState === ReviewerState.CC
        ? ReviewerState.REVIEWER
        : ReviewerState.CC;
    const accountsInCurrentState =
      this.getAccountsInCurrentState(currentReviewerState);
    return this.updatedAccountsByReviewerState
      .get(updatedReviewerState)!
      .filter(account =>
        accountsInCurrentState.some(
          otherAccount => getUserId(otherAccount) === getUserId(account)
        )
      )
      .map(reviewer => getDisplayName(this.serverConfig, reviewer));
  }

  private async openOverlay() {
    this.resetFlow();
    this.isOverlayOpen = true;
    // Must await the overlay opening because the dialog is lazily rendered.
    await this.modal?.showModal();
  }

  private closeOverlay() {
    this.isOverlayOpen = false;
    this.modal?.close();
  }

  private resetFlow() {
    this.progressByChangeNum = new Map(
      this.selectedChanges.map(change => [
        change._number,
        ProgressStatus.NOT_STARTED,
      ])
    );
    for (const state of [ReviewerState.REVIEWER, ReviewerState.CC] as const) {
      this.updatedAccountsByReviewerState.set(
        state,
        this.getCurrentAccounts(state)
      );
      if (this.selectedChanges.length > 0) {
        this.suggestionsProviderByReviewerState.set(
          state,
          this.createSuggestionsProvider(state)
        );
      }
    }
    this.requestUpdate();
  }

  /*
   * Removes accounts from one list when they are added to the other. Also
   * trigger re-render so warnings will update as accounts are added, removed,
   * and confirmed.
   */
  private onAccountsChanged(reviewerState: ReviewerState) {
    const reviewerStateKeys = this.updatedAccountsByReviewerState
      .get(reviewerState)!
      .map(getUserId);
    const oppositeReviewerState =
      reviewerState === ReviewerState.CC
        ? ReviewerState.REVIEWER
        : ReviewerState.CC;
    const oppositeUpdatedAccounts = this.updatedAccountsByReviewerState.get(
      oppositeReviewerState
    )!;

    const notOverwrittenOppositeAccounts = oppositeUpdatedAccounts.filter(
      acc => !reviewerStateKeys.includes(getUserId(acc))
    );
    if (
      notOverwrittenOppositeAccounts.length !== oppositeUpdatedAccounts.length
    ) {
      this.updatedAccountsByReviewerState.set(
        oppositeReviewerState,
        notOverwrittenOppositeAccounts
      );
    }
    this.requestUpdate();
  }

  private async onPendingConfirmationChanged(
    reviewerState: ReviewerState,
    ev: ValueChangedEvent<SuggestedReviewerGroupInfo | null>
  ) {
    this.groupPendingConfirmationByReviewerState.set(
      reviewerState,
      ev.detail.value
    );
    this.requestUpdate();
    await this.updateComplete;

    const modal =
      reviewerState === ReviewerState.CC
        ? this.ccConfirmModal
        : this.reviewerConfirmModal;
    if (ev.detail.value === null) {
      modal?.close();
    } else {
      await modal?.showModal();
    }
  }

  private cancelPendingGroup(reviewerState: ReviewerState) {
    const modal =
      reviewerState === ReviewerState.CC
        ? this.ccConfirmModal
        : this.reviewerConfirmModal;
    modal?.close();
    this.groupPendingConfirmationByReviewerState.set(reviewerState, null);
    this.requestUpdate();
  }

  private confirmPendingGroup(
    reviewerState: ReviewerState,
    suggestion: SuggestedReviewerGroupInfo | null | undefined
  ) {
    if (!suggestion) return;
    const accountList =
      reviewerState === ReviewerState.CC ? this.ccList : this.reviewerList;
    accountList?.confirmGroup(suggestion.group);
  }

  private onConfirm(overallStatus: ProgressStatus) {
    switch (overallStatus) {
      case ProgressStatus.NOT_STARTED:
        this.saveReviewers();
        break;
      case ProgressStatus.SUCCESSFUL:
        this.modal?.close();
        break;
      case ProgressStatus.FAILED:
        this.modal?.close();
        break;
    }
  }

  private fireSuccessToasts() {
    const numReviewersAdded =
      (this.updatedAccountsByReviewerState.get(ReviewerState.REVIEWER)
        ?.length ?? 0) - this.getCurrentAccounts(ReviewerState.REVIEWER).length;
    const numCcsAdded =
      (this.updatedAccountsByReviewerState.get(ReviewerState.CC)?.length ?? 0) -
      this.getCurrentAccounts(ReviewerState.CC).length;
    let alert = '';
    if (numReviewersAdded && numCcsAdded) {
      alert = `${pluralize(numReviewersAdded, 'reviewer')} and ${pluralize(
        numCcsAdded,
        'CC'
      )} added`;
    } else if (numReviewersAdded) {
      alert = `${pluralize(numReviewersAdded, 'reviewer')} added`;
    } else {
      alert = `${pluralize(numCcsAdded, 'CC')} added`;
    }
    fireAlert(this, alert);
  }

  private async saveReviewers() {
    this.reportingService.reportInteraction(Interaction.BULK_ACTION, {
      type: 'add-reviewer',
      selectedChangeCount: this.selectedChanges.length,
    });
    this.progressByChangeNum = new Map(
      this.selectedChanges.map(change => [
        change._number,
        ProgressStatus.RUNNING,
      ])
    );
    const inFlightActions = this.getBulkActionsModel().addReviewers(
      this.updatedAccountsByReviewerState,
      getReplyByReason(this.account, this.serverConfig)
    );

    await allSettled(
      inFlightActions.map((promise, index) => {
        const change = this.selectedChanges[index];
        return promise
          .then(() => {
            this.progressByChangeNum.set(
              change._number,
              ProgressStatus.SUCCESSFUL
            );
            this.requestUpdate();
          })
          .catch(() => {
            this.progressByChangeNum.set(change._number, ProgressStatus.FAILED);
            this.requestUpdate();
          });
      })
    );
    if (getOverallStatus(this.progressByChangeNum) === ProgressStatus.FAILED) {
      this.reportingService.reportInteraction('bulk-action-failure', {
        type: 'add-reviewer',
        count: Array.from(this.progressByChangeNum.values()).filter(
          status => status === ProgressStatus.FAILED
        ).length,
      });
    } else {
      this.fireSuccessToasts();
      this.closeOverlay();
      fireReload(this);
    }
  }

  private isFlowDisabled() {
    // No additional checks are necessary. If the user has visibility enough to
    // see the change, they have permission enough to add reviewers/cc.
    return this.selectedChanges.length === 0;
  }

  // private but used in tests
  getCurrentAccounts(reviewerState: ReviewerState) {
    const reviewersPerChange = this.selectedChanges.map(
      change =>
        change.reviewers[reviewerState]?.filter(isNotOwner(change)) ?? []
    );
    return intersection(
      reviewersPerChange,
      (account1, account2) => accountKey(account1) === accountKey(account2)
    );
  }

  private createSuggestionsProvider(
    state: ReviewerState.CC | ReviewerState.REVIEWER
  ): ReviewerSuggestionsProvider {
    const suggestionsProvider = new GrReviewerSuggestionsProvider(
      this.restApiService,
      state,
      this.serverConfig,
      this.isLoggedIn,
      ...this.selectedChanges
    );
    return suggestionsProvider;
  }
}

function isNotOwner(change: ChangeInfo) {
  return (account: AccountInfo) =>
    accountKey(change.owner) !== accountKey(account);
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-change-list-reviewer-flow': GrChangeListReviewerFlow;
  }
}
