/**
 * @license
 * Copyright 2022 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import {customElement, query, state} from 'lit/decorators';
import {LitElement, html, css, nothing} from 'lit';
import {GrOverlay} from '../../shared/gr-overlay/gr-overlay';
import {resolve} from '../../../models/dependency';
import {bulkActionsModelToken} from '../../../models/bulk-actions/bulk-actions-model';
import {subscribe} from '../../lit/subscription-controller';
import {ChangeInfo, AccountInfo, NumericChangeId} from '../../../api/rest-api';
import {
  getTriggerVotes,
  computeLabels,
  computeOrderedLabelValues,
  mergeLabelInfoMaps,
  getDefaultValue,
  mergeLabelMaps,
  Label,
  StandardLabels,
} from '../../../utils/label-util';
import {getAppContext} from '../../../services/app-context';
import {fontStyles} from '../../../styles/gr-font-styles';
import {queryAndAssert} from '../../../utils/common-util';
import {
  LabelNameToValuesMap,
  ReviewInput,
  LabelNameToValueMap,
} from '../../../types/common';
import {GrLabelScoreRow} from '../../change/gr-label-score-row/gr-label-score-row';
import {ProgressStatus} from '../../../constants/constants';
import {fireAlert, fireReload} from '../../../utils/event-util';
import '../../shared/gr-dialog/gr-dialog';
import '../../shared/gr-icon/gr-icon';
import '../../change/gr-label-score-row/gr-label-score-row';
import {getOverallStatus} from '../../../utils/bulk-flow-util';
import {allSettled} from '../../../utils/async-util';
import {pluralize} from '../../../utils/string-util';
import {GerritNav} from '../../core/gr-navigation/gr-navigation';
import {GrDialog} from '../../shared/gr-dialog/gr-dialog';
import {Interaction} from '../../../constants/reporting';

@customElement('gr-change-list-bulk-vote-flow')
export class GrChangeListBulkVoteFlow extends LitElement {
  private readonly getBulkActionsModel = resolve(this, bulkActionsModelToken);

  private readonly userModel = getAppContext().userModel;

  private readonly reportingService = getAppContext().reportingService;

  @state() selectedChanges: ChangeInfo[] = [];

  @state() progressByChange: Map<NumericChangeId, ProgressStatus> = new Map();

  @query('#actionOverlay') actionOverlay!: GrOverlay;

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

  @state() account?: AccountInfo;

  static override get styles() {
    return [
      fontStyles,
      css`
        gr-dialog {
          width: 840px;
        }
        .scoresTable {
          display: table;
          width: 100%;
        }
        .scoresTable.newSubmitRequirements {
          table-layout: fixed;
        }
        gr-label-score-row:hover {
          background-color: var(--hover-background-color);
        }
        gr-label-score-row {
          display: table-row;
        }
        /* TODO(dhruvsri): Consider using flex column with gap */
        .scoresTable:not(:first-of-type) {
          margin-top: var(--spacing-m);
        }
        .vote-type {
          margin-bottom: var(--spacing-s);
          margin-top: 0;
          display: table-caption;
        }
        .main-heading {
          margin-bottom: var(--spacing-m);
          font-weight: var(--font-weight-h2);
        }
        .error-container {
          background-color: var(--error-background);
          margin-top: var(--spacing-l);
        }
        .code-review-message-container gr-icon,
        .error-container gr-icon {
          padding: 10px var(--spacing-xl);
        }
        .error-container gr-icon {
          color: var(--error-foreground);
        }
        .code-review-message-container gr-icon {
          color: var(--selected-foreground);
        }
        .error-container .error-text,
        .code-review-message-container .warning-text {
          position: relative;
          top: 10px;
        }
        .code-review-message-container {
          display: table-caption;
          background-color: var(--code-review-warning-background);
          margin-bottom: var(--spacing-m);
        }
        .code-review-message-layout-container {
          display: flex;
        }
        .code-review-message-container gr-button {
          margin-top: 6px;
          margin-right: var(--spacing-xl);
        }
        .flex-space {
          flex-grow: 1;
        }
      `,
    ];
  }

  constructor() {
    super();
    subscribe(
      this,
      () => this.getBulkActionsModel().selectedChanges$,
      selectedChanges => {
        this.selectedChanges = selectedChanges;
        this.resetFlow();
      }
    );
    subscribe(
      this,
      () => this.userModel.account$,
      account => (this.account = account)
    );
  }

  override render() {
    const permittedLabels = this.computePermittedLabels();
    const triggerLabels = this.computeCommonTriggerLabels(permittedLabels);
    const nonTriggerLabels = this.computeCommonPermittedLabels(
      permittedLabels
    ).filter(label => !triggerLabels.some(l => l.name === label.name));
    return html`
      <gr-button id="voteFlowButton" flatten @click=${this.openOverlay}
        >Vote</gr-button
      >
      <gr-overlay id="actionOverlay" with-backdrop="">
        <gr-dialog
          .disableCancel=${!this.isCancelEnabled()}
          .disabled=${!this.isConfirmEnabled()}
          ?loading=${this.isLoading()}
          .loadingLabel=${'Voting in progress...'}
          @confirm=${() => this.handleConfirm()}
          @cancel=${() => this.handleClose()}
          .confirmLabel=${'Vote'}
          .cancelLabel=${'Cancel'}
        >
          <div slot="header">
            <span class="main-heading"> Vote on selected changes </span>
          </div>
          <div slot="main">
            ${this.renderLabels(
              nonTriggerLabels,
              'Submit requirements votes',
              permittedLabels,
              true
            )}
            ${this.renderLabels(
              triggerLabels,
              'Trigger Votes',
              permittedLabels
            )}
            ${this.renderErrors()}
          </div>
        </gr-dialog>
      </gr-overlay>
    `;
  }

  private renderCodeReviewMessage() {
    return html`
      <div class="code-review-message-container">
        <div class="code-review-message-layout-container">
          <div>
            <gr-icon icon="info" aria-label="Information" role="img"></gr-icon>
            <span class="warning-text">
              Code Review vote is only available on the individual change page
            </span>
          </div>
          <div class="flex-space"></div>
          <div>
            <gr-button
              aria-label=${`Open ${pluralize(
                this.selectedChanges.length,
                'change'
              )} in different tabs`}
              flatten
              link
              @click=${this.handleOpenChanges}
              >Open ${pluralize(this.selectedChanges.length, 'change')}
            </gr-button>
          </div>
        </div>
      </div>
    `;
  }

  private handleOpenChanges() {
    for (const change of this.selectedChanges) {
      window.open(GerritNav.getUrlForChange(change));
    }
  }

  private async openOverlay() {
    await this.actionOverlay.open();
    this.actionOverlay.setFocusStops({
      start: queryAndAssert(this.dialog, 'header'),
      end: queryAndAssert(this.dialog, 'footer'),
    });
  }

  private renderErrors() {
    if (getOverallStatus(this.progressByChange) !== ProgressStatus.FAILED) {
      return nothing;
    }
    return html`
      <div class="error-container">
        <gr-icon icon="error" filled role="img" aria-label="Error"></gr-icon>
        <span class="error-text">
          <!-- prettier-ignore -->
          Failed to vote on ${pluralize(
            Array.from(this.progressByChange.values()).filter(
              status => status === ProgressStatus.FAILED
            ).length,
            'change'
          )}
        </span>
      </div>
    `;
  }

  private renderLabels(
    labels: Label[],
    heading: string,
    permittedLabels?: LabelNameToValuesMap,
    showCodeReviewWarning?: boolean
  ) {
    return html` <div class="scoresTable newSubmitRequirements">
      <h3 class="heading-4 vote-type">${labels.length ? heading : nothing}</h3>
      ${showCodeReviewWarning ? this.renderCodeReviewMessage() : nothing}
      ${labels
        .filter(
          label =>
            permittedLabels?.[label.name] &&
            permittedLabels?.[label.name].length > 0
        )
        .map(
          label => html`<gr-label-score-row
            .label=${label}
            .name=${label.name}
            .labels=${this.computeLabelNameToInfoMap()}
            .permittedLabels=${permittedLabels}
            .orderedLabelValues=${computeOrderedLabelValues(permittedLabels)}
          ></gr-label-score-row>`
        )}
    </div>`;
  }

  private resetFlow() {
    this.progressByChange = new Map(
      this.selectedChanges.map(change => [
        change._number,
        ProgressStatus.NOT_STARTED,
      ])
    );
  }

  private isLoading() {
    return getOverallStatus(this.progressByChange) === ProgressStatus.RUNNING;
  }

  private isConfirmEnabled() {
    // Action is allowed if none of the changes have any bulk action performed
    // on them. In case an error happens then we keep the button disabled.
    return (
      getOverallStatus(this.progressByChange) === ProgressStatus.NOT_STARTED
    );
  }

  private isCancelEnabled() {
    return getOverallStatus(this.progressByChange) !== ProgressStatus.RUNNING;
  }

  private handleClose() {
    this.actionOverlay.close();
    if (getOverallStatus(this.progressByChange) === ProgressStatus.NOT_STARTED)
      return;
    fireReload(this, true);
  }

  private async handleConfirm() {
    this.progressByChange.clear();
    this.reportingService.reportInteraction(Interaction.BULK_ACTION, {
      type: 'vote',
      selectedChangeCount: this.selectedChanges.length,
    });
    const reviewInput: ReviewInput = {
      labels: this.getLabelValues(
        this.computeCommonPermittedLabels(this.computePermittedLabels())
      ),
    };
    for (const change of this.selectedChanges) {
      this.progressByChange.set(change._number, ProgressStatus.RUNNING);
    }
    this.requestUpdate();
    const promises = this.getBulkActionsModel().voteChanges(reviewInput);

    await allSettled(
      promises.map((promise, index) => {
        const changeNum = this.selectedChanges[index]._number;
        return promise
          .then(() => {
            this.progressByChange.set(changeNum, ProgressStatus.SUCCESSFUL);
          })
          .catch(() => {
            this.progressByChange.set(changeNum, ProgressStatus.FAILED);
          })
          .finally(() => {
            this.requestUpdate();
            if (
              getOverallStatus(this.progressByChange) ===
              ProgressStatus.SUCCESSFUL
            ) {
              fireAlert(this, 'Votes added');
              this.handleClose();
            }
          });
      })
    );
    if (getOverallStatus(this.progressByChange) === ProgressStatus.FAILED) {
      this.reportingService.reportInteraction('bulk-action-failure', {
        type: 'vote',
        count: Array.from(this.progressByChange.values()).filter(
          status => status === ProgressStatus.FAILED
        ).length,
      });
    }
  }

  // private but used in tests
  getLabelValues(commonPermittedLabels: Label[]): LabelNameToValueMap {
    const labels: LabelNameToValueMap = {};

    for (const label of commonPermittedLabels) {
      const selectorEl = queryAndAssert<GrLabelScoreRow>(
        this,
        `gr-label-score-row[name="${label.name}"]`
      );
      if (!selectorEl?.selectedItem) continue;

      const selectedVal =
        typeof selectorEl.selectedValue === 'string'
          ? Number(selectorEl.selectedValue)
          : selectorEl.selectedValue;

      if (selectedVal === undefined) continue;

      const defValNum = getDefaultValue(
        this.selectedChanges[0].labels,
        label.name
      );
      if (selectedVal !== defValNum) {
        labels[label.name] = selectedVal;
      }
    }
    return labels;
  }

  // private but used in tests
  computePermittedLabels() {
    // Reduce method for empty array throws error if no initial value specified
    if (this.selectedChanges.length === 0) return {};

    const permittedLabels = this.selectedChanges
      .map(changes => changes.permitted_labels)
      .reduce(mergeLabelMaps);
    // TODO: show a warning to the user that Code Review cannot be voted upon
    if (permittedLabels?.[StandardLabels.CODE_REVIEW]) {
      delete permittedLabels[StandardLabels.CODE_REVIEW];
    }
    return permittedLabels;
  }

  private computeLabelNameToInfoMap() {
    // Reduce method for empty array throws error if no initial value specified
    if (this.selectedChanges.length === 0) return {};

    return this.selectedChanges
      .map(changes => changes.labels)
      .reduce(mergeLabelInfoMaps);
  }

  // private but used in tests
  computeCommonTriggerLabels(permittedLabels?: LabelNameToValuesMap) {
    if (this.selectedChanges.length === 0) return [];
    const triggerVotes = this.selectedChanges
      .map(change => getTriggerVotes(change))
      .reduce((prev, current) =>
        current.filter(label => prev.some(l => l === label))
      );
    return this.computeCommonPermittedLabels(permittedLabels).filter(label =>
      triggerVotes.includes(label.name)
    );
  }

  // private but used in tests
  computeCommonPermittedLabels(permittedLabels?: LabelNameToValuesMap) {
    // Reduce method for empty array throws error if no initial value specified
    if (this.selectedChanges.length === 0) return [];
    return this.selectedChanges
      .map(change => computeLabels(this.account, change))
      .reduce((prev, current) =>
        current.filter(label => prev.some(l => l.name === label.name))
      )
      .filter(
        label =>
          permittedLabels?.[label.name] &&
          permittedLabels?.[label.name].length > 0
      );
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-change-list-bulk-vote-flow': GrChangeListBulkVoteFlow;
  }
}
