/**
 * @license
 * Copyright 2016 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '@polymer/iron-autogrow-textarea/iron-autogrow-textarea';
import '@polymer/iron-input/iron-input';
import '../../../styles/shared-styles';
import '../../shared/gr-autocomplete/gr-autocomplete';
import '../../shared/gr-dialog/gr-dialog';
import {navigationToken} from '../../core/gr-navigation/gr-navigation';
import {getAppContext} from '../../../services/app-context';
import {
  ChangeInfo,
  BranchName,
  RepoName,
  CommitId,
  ChangeInfoId,
  TopicName,
} from '../../../types/common';
import {customElement, property, query, state} from 'lit/decorators.js';
import {
  AutocompleteQuery,
  AutocompleteSuggestion,
  GrTypedAutocomplete,
} from '../../shared/gr-autocomplete/gr-autocomplete';
import {
  HttpMethod,
  ChangeStatus,
  ProgressStatus,
} from '../../../constants/constants';
import {fireEvent} from '../../../utils/event-util';
import {css, html, LitElement, PropertyValues} from 'lit';
import {sharedStyles} from '../../../styles/shared-styles';
import {choose} from 'lit/directives/choose.js';
import {when} from 'lit/directives/when.js';
import {BindValueChangeEvent} from '../../../types/events';
import {resolve} from '../../../models/dependency';
import {createSearchUrl} from '../../../models/views/search';

const SUGGESTIONS_LIMIT = 15;
const CHANGE_SUBJECT_LIMIT = 50;
enum CherryPickType {
  SINGLE_CHANGE = 1,
  TOPIC,
}

export type Statuses = {[changeId: string]: Status};

interface Status {
  status: ProgressStatus;
  msg?: string;
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-confirm-cherrypick-dialog': GrConfirmCherrypickDialog;
  }
}

@customElement('gr-confirm-cherrypick-dialog')
export class GrConfirmCherrypickDialog extends LitElement {
  /**
   * Fired when the confirm button is pressed.
   *
   * @event confirm
   */

  /**
   * Fired when the cancel button is pressed.
   *
   * @event cancel
   */

  @property({type: String})
  branch = '' as BranchName;

  @property({type: String})
  baseCommit?: string;

  @property({type: String})
  changeStatus?: ChangeStatus;

  @property({type: String})
  commitMessage?: string;

  @property({type: String})
  commitNum?: CommitId;

  @property({type: String})
  message = '';

  @property({type: String})
  project?: RepoName;

  @property({type: Array})
  changes: ChangeInfo[] = [];

  @state()
  private query: AutocompleteQuery;

  @state()
  private showCherryPickTopic = false;

  @state()
  private changesCount?: number;

  @state()
  cherryPickType = CherryPickType.SINGLE_CHANGE;

  @state()
  private duplicateProjectChanges = false;

  @state()
  // Status of each change that is being cherry picked together
  private statuses: Statuses;

  @state()
  private invalidBranch = false;

  @query('#branchInput')
  branchInput!: GrTypedAutocomplete<BranchName>;

  private selectedChangeIds = new Set<ChangeInfoId>();

  private readonly restApiService = getAppContext().restApiService;

  private readonly reporting = getAppContext().reportingService;

  private readonly getNavigation = resolve(this, navigationToken);

  constructor() {
    super();
    this.statuses = {};
    this.query = (text: string) => this.getProjectBranchesSuggestions(text);
  }

  override willUpdate(changedProperties: PropertyValues) {
    if (changedProperties.has('branch')) {
      this.updateBranch();
    }
    if (
      changedProperties.has('changeStatus') ||
      changedProperties.has('commitNum') ||
      changedProperties.has('commitMessage')
    ) {
      this.computeMessage();
    }
  }

  static override styles = [
    sharedStyles,
    css`
      :host {
        display: block;
      }
      :host([disabled]) {
        opacity: 0.5;
        pointer-events: none;
      }
      label {
        cursor: pointer;
      }
      .main {
        display: flex;
        flex-direction: column;
        width: 100%;
      }
      .main label,
      .main input[type='text'] {
        display: block;
        width: 100%;
      }
      iron-autogrow-textarea {
        font-family: var(--monospace-font-family);
        font-size: var(--font-size-mono);
        line-height: var(--line-height-mono);
        width: 73ch; /* Add a char to account for the border. */
      }
      .cherryPickTopicLayout {
        display: flex;
        align-items: center;
        margin-bottom: var(--spacing-m);
      }
      .cherryPickSingleChange,
      .cherryPickTopic {
        margin-left: var(--spacing-m);
      }
      .cherry-pick-topic-message {
        margin-bottom: var(--spacing-m);
      }
      label[for='messageInput'],
      label[for='baseInput'] {
        margin-top: var(--spacing-m);
      }
      .title {
        font-weight: var(--font-weight-bold);
      }
      tr > td {
        padding: var(--spacing-m);
      }
      th {
        color: var(--deemphasized-text-color);
      }
      table {
        border-collapse: collapse;
      }
      tr {
        border-bottom: 1px solid var(--border-color);
      }
      .error {
        color: var(--error-text-color);
      }
      .error-message {
        color: var(--error-text-color);
        margin: var(--spacing-m) 0 var(--spacing-m) 0;
      }
    `,
  ];

  override render() {
    return html`
      <gr-dialog
        confirm-label="Cherry Pick"
        .cancelLabel=${this.computeCancelLabel()}
        ?disabled=${this.computeDisableCherryPick(
          this.cherryPickType,
          this.duplicateProjectChanges,
          this.statuses,
          this.branch
        )}
        @confirm=${this.handleConfirmTap}
        @cancel=${this.handleCancelTap}
      >
        <div class="header title" slot="header">
          Cherry Pick Change to Another Branch
        </div>
        <div class="main" slot="main">
          <gr-endpoint-decorator name="cherrypick-main">
            <gr-endpoint-param name="changes" .value=${this.changes}>
            </gr-endpoint-param>
            <gr-endpoint-slot name="top"></gr-endpoint-slot>
            ${when(this.showCherryPickTopic, () =>
              this.renderCherrypickTopicLayout()
            )}
            <label for="branchInput"> Cherry Pick to branch </label>
            <gr-autocomplete
              id="branchInput"
              .text=${this.branch}
              .query=${this.query}
              placeholder="Destination branch"
              @text-changed=${(e: BindValueChangeEvent) =>
                (this.branch = e.detail.value as BranchName)}
            >
            </gr-autocomplete>
            ${when(
              this.invalidBranch,
              () => html`
                <span class="error"
                  >Branch name cannot contain space or commas.</span
                >
              `
            )}
            ${choose(this.cherryPickType, [
              [
                CherryPickType.SINGLE_CHANGE,
                () => this.renderCherrypickSingleChangeInputs(),
              ],
              [CherryPickType.TOPIC, () => this.renderCherrypickTopicTable()],
            ])}
            <gr-endpoint-slot name="bottom"></gr-endpoint-slot>
          </gr-endpoint-decorator>
        </div>
      </gr-dialog>
    `;
  }

  private renderCherrypickTopicLayout() {
    return html`
      <div class="cherryPickTopicLayout">
        <input
          name="cherryPickOptions"
          type="radio"
          id="cherryPickSingleChange"
          @change=${this.handlecherryPickSingleChangeClicked}
          checked
        />
        <label for="cherryPickSingleChange" class="cherryPickSingleChange">
          Cherry Pick single change
        </label>
      </div>
      <div class="cherryPickTopicLayout">
        <input
          name="cherryPickOptions"
          type="radio"
          id="cherryPickTopic"
          @change=${this.handlecherryPickTopicClicked}
        />
        <label for="cherryPickTopic" class="cherryPickTopic">
          Cherry Pick entire topic (${this.changesCount} Changes)
        </label>
      </div>
    `;
  }

  private renderCherrypickSingleChangeInputs() {
    return html`
      <label for="baseInput"> Provide base commit sha1 for cherry-pick </label>
      <iron-input
        .bindValue=${this.baseCommit}
        @bind-value-changed=${(e: BindValueChangeEvent) =>
          (this.baseCommit = e.detail.value)}
      >
        <input
          is="iron-input"
          id="baseCommitInput"
          maxlength="40"
          placeholder="(optional)"
        />
      </iron-input>
      <label for="messageInput"> Cherry Pick Commit Message </label>
      <iron-autogrow-textarea
        id="messageInput"
        class="message"
        autocomplete="on"
        rows="4"
        .maxRows=${15}
        .bindValue=${this.message}
        @bind-value-changed=${(e: BindValueChangeEvent) =>
          (this.message = e.detail.value ?? '')}
      ></iron-autogrow-textarea>
    `;
  }

  private renderCherrypickTopicTable() {
    return html`
      <span class="error-message">${this.computeTopicErrorMessage()}</span>
      <span class="cherry-pick-topic-message">
        Commit Message will be auto generated
      </span>
      <table>
        <thead>
          <tr>
            <th></th>
            <th>Change</th>
            <th>Status</th>
            <th>Subject</th>
            <th>Project</th>
            <th>Progress</th>
            <!-- Error Message -->
            <th></th>
          </tr>
        </thead>
        <tbody>
          ${this.changes.map(
            item => html`
              <tr>
                <td>
                  <input
                    type="checkbox"
                    data-item=${item.id as string}
                    @change=${this.toggleChangeSelected}
                    ?checked=${this.isChangeSelected(item.id)}
                  />
                </td>
                <td><span> ${this.getChangeId(item)} </span></td>
                <td><span> ${item.status} </span></td>
                <td>
                  <span> ${this.getTrimmedChangeSubject(item.subject)} </span>
                </td>
                <td><span> ${item.project} </span></td>
                <td>
                  <span class=${this.computeStatusClass(item, this.statuses)}>
                    ${this.computeStatus(item, this.statuses)}
                  </span>
                </td>
                <td>
                  <span class="error">
                    ${this.computeError(item, this.statuses)}
                  </span>
                </td>
              </tr>
            `
          )}
        </tbody>
      </table>
    `;
  }

  containsDuplicateProject(changes: ChangeInfo[]) {
    const projects: {[projectName: string]: boolean} = {};
    for (let i = 0; i < changes.length; i++) {
      const change = changes[i];
      if (projects[change.project]) {
        return true;
      }
      projects[change.project] = true;
    }
    return false;
  }

  updateChanges(changes: ChangeInfo[]) {
    this.changes = changes;
    this.statuses = {};
    changes.forEach(change => {
      this.selectedChangeIds.add(change.id);
    });
    this.duplicateProjectChanges = this.containsDuplicateProject(changes);
    this.changesCount = changes.length;
    this.showCherryPickTopic = changes.length > 1;
  }

  private updateBranch() {
    const invalidChars = [',', ' '];
    this.invalidBranch = !!(
      this.branch && invalidChars.some(c => this.branch.includes(c))
    );
  }

  private isChangeSelected(changeId: ChangeInfoId) {
    return this.selectedChangeIds.has(changeId);
  }

  private toggleChangeSelected(e: Event) {
    const changeId = (e.target as HTMLElement).dataset['item']! as ChangeInfoId;
    if (this.selectedChangeIds.has(changeId))
      this.selectedChangeIds.delete(changeId);
    else this.selectedChangeIds.add(changeId);
    const changes = this.changes.filter(change =>
      this.selectedChangeIds.has(change.id)
    );
    this.duplicateProjectChanges = this.containsDuplicateProject(changes);
  }

  private computeTopicErrorMessage() {
    if (this.duplicateProjectChanges) {
      return 'Two changes cannot be of the same project';
    }
    return '';
  }

  updateStatus(change: ChangeInfo, status: Status) {
    this.statuses = {...this.statuses, [change.id]: status};
  }

  private computeStatus(change: ChangeInfo, statuses: Statuses) {
    if (!change || !statuses || !statuses[change.id])
      return ProgressStatus.NOT_STARTED;
    return statuses[change.id].status;
  }

  computeStatusClass(change: ChangeInfo, statuses: Statuses) {
    if (!change || !statuses || !statuses[change.id]) return '';
    return statuses[change.id].status === ProgressStatus.FAILED ? 'error' : '';
  }

  private computeError(change: ChangeInfo, statuses: Statuses) {
    if (!change || !statuses || !statuses[change.id]) return '';
    if (statuses[change.id].status === ProgressStatus.FAILED) {
      return statuses[change.id].msg;
    }
    return '';
  }

  private getChangeId(change: ChangeInfo) {
    return change.change_id.substring(0, 10);
  }

  private getTrimmedChangeSubject(subject: string) {
    if (!subject) return '';
    if (subject.length < CHANGE_SUBJECT_LIMIT) return subject;
    return subject.substring(0, CHANGE_SUBJECT_LIMIT) + '...';
  }

  private computeCancelLabel() {
    const isRunningChange = Object.values(this.statuses).some(
      v => v.status === ProgressStatus.RUNNING
    );
    return isRunningChange ? 'Close' : 'Cancel';
  }

  private computeDisableCherryPick(
    cherryPickType: CherryPickType,
    duplicateProjectChanges: boolean,
    statuses: Statuses,
    branch: BranchName
  ) {
    if (!branch) return true;
    const duplicateProject =
      cherryPickType === CherryPickType.TOPIC && duplicateProjectChanges;
    if (duplicateProject) return true;
    if (!statuses) return false;
    const isRunningChange = Object.values(statuses).some(
      v => v.status === ProgressStatus.RUNNING
    );
    return isRunningChange;
  }

  private handlecherryPickSingleChangeClicked() {
    this.cherryPickType = CherryPickType.SINGLE_CHANGE;
    fireEvent(this, 'iron-resize');
  }

  private handlecherryPickTopicClicked() {
    this.cherryPickType = CherryPickType.TOPIC;
    fireEvent(this, 'iron-resize');
  }

  private computeMessage() {
    if (
      this.changeStatus === undefined ||
      this.commitNum === undefined ||
      this.commitMessage === undefined
    ) {
      return;
    }

    let newMessage = this.commitMessage;

    if (this.changeStatus === 'MERGED') {
      if (!newMessage.endsWith('\n')) {
        newMessage += '\n';
      }
      newMessage += '(cherry picked from commit ' + this.commitNum + ')';
    }
    this.message = newMessage;
  }

  private generateRandomCherryPickTopic(change: ChangeInfo) {
    const randomString = Math.random().toString(36).substr(2, 10);
    const message = `cherrypick-${change.topic}-${randomString}`;
    return message;
  }

  private handleCherryPickFailed(
    change: ChangeInfo,
    response?: Response | null
  ) {
    if (!response) return;
    response.text().then((errText: string) => {
      this.updateStatus(change, {status: ProgressStatus.FAILED, msg: errText});
    });
  }

  private handleCherryPickTopic() {
    const changes = this.changes.filter(change =>
      this.selectedChangeIds.has(change.id)
    );
    if (!changes.length) {
      const errorSpan = this.shadowRoot?.querySelector('.error-message');
      errorSpan!.innerHTML = 'No change selected';
      return;
    }
    const topic = this.generateRandomCherryPickTopic(changes[0]);
    changes.forEach(change => {
      this.updateStatus(change, {status: ProgressStatus.RUNNING});
      const payload = {
        destination: this.branch,
        base: null,
        topic,
        allow_conflicts: true,
        allow_empty: true,
      };
      const handleError = (response?: Response | null) => {
        this.handleCherryPickFailed(change, response);
      };
      // revisions and current_revision must exist hence casting
      const patchNum = change.revisions![change.current_revision!]._number;
      this.restApiService
        .executeChangeAction(
          change._number,
          HttpMethod.POST,
          '/cherrypick',
          patchNum,
          payload,
          handleError
        )
        .then(() => {
          this.updateStatus(change, {status: ProgressStatus.SUCCESSFUL});
          const failedOrPending = Object.values(this.statuses).find(
            v => v.status !== ProgressStatus.SUCCESSFUL
          );
          if (!failedOrPending) {
            // This needs some more work, as the new topic may not always be
            // created, instead we may end up creating a new patchset */
            this.getNavigation().setUrl(
              createSearchUrl({topic: topic as TopicName})
            );
          }
        });
    });
  }

  private handleConfirmTap(e: Event) {
    e.preventDefault();
    e.stopPropagation();
    if (this.cherryPickType === CherryPickType.TOPIC) {
      this.reporting.reportInteraction('cherry-pick-topic-clicked', {});
      this.handleCherryPickTopic();
      return;
    }
    // Cherry pick single change
    this.dispatchEvent(
      new CustomEvent('confirm', {
        composed: true,
        bubbles: false,
      })
    );
  }

  private handleCancelTap(e: Event) {
    e.preventDefault();
    e.stopPropagation();
    this.dispatchEvent(
      new CustomEvent('cancel', {
        composed: true,
        bubbles: false,
      })
    );
  }

  resetFocus() {
    this.branchInput.focus();
  }

  async getProjectBranchesSuggestions(
    input: string
  ): Promise<AutocompleteSuggestion[]> {
    if (!this.project) return Promise.reject(new Error('Missing project'));
    if (input.startsWith('refs/heads/')) {
      input = input.substring('refs/heads/'.length);
    }
    return this.restApiService
      .getRepoBranches(input, this.project, SUGGESTIONS_LIMIT)
      .then(response => {
        if (!response) return [];
        const branches: Array<{name: BranchName}> = [];
        for (const branchInfo of response) {
          let name: string = branchInfo.ref;
          if (name.startsWith('refs/heads/')) {
            name = name.substring('refs/heads/'.length);
          }
          branches.push({name: name as BranchName});
        }
        return branches;
      });
  }
}
