/**
 * @license
 * Copyright 2019 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '../../../styles/shared-styles';
import '../../shared/gr-dialog/gr-dialog';
import '../../shared/gr-icon/gr-icon';
import '../../../embed/diff/gr-diff/gr-diff';
import {navigationToken} from '../../core/gr-navigation/gr-navigation';
import {
  BasePatchSetNum,
  EDIT,
  FilePathToDiffInfoMap,
  FixSuggestionInfo,
  NumericChangeId,
  PatchSetNum,
  PatchSetNumber,
} from '../../../types/common';
import {DiffInfo, DiffPreferencesInfo} from '../../../types/diff';
import {OpenFixPreviewEvent} from '../../../types/events';
import {getAppContext} from '../../../services/app-context';
import {DiffLayer, ParsedChangeInfo} from '../../../types/types';
import {GrButton} from '../../shared/gr-button/gr-button';
import {TokenHighlightLayer} from '../../../embed/diff/gr-diff-builder/token-highlight-layer';
import {css, html, LitElement, nothing} from 'lit';
import {customElement, query, state} from 'lit/decorators.js';
import {sharedStyles} from '../../../styles/shared-styles';
import {subscribe} from '../../lit/subscription-controller';
import {assert} from '../../../utils/common-util';
import {resolve} from '../../../models/dependency';
import {
  changeViewModelToken,
  createApplyFixUrl,
} from '../../../models/views/change';

import {GrDialog} from '../../shared/gr-dialog/gr-dialog';
import {userModelToken} from '../../../models/user/user-model';
import {modalStyles} from '../../../styles/gr-modal-styles';
import {GrSyntaxLayerWorker} from '../../../embed/diff/gr-syntax-layer/gr-syntax-layer-worker';
import {highlightServiceToken} from '../../../services/highlight/highlight-service';
import {fireError, fireReload} from '../../../utils/event-util';
import {when} from 'lit/directives/when.js';
import {Timing} from '../../../constants/reporting';
import {changeModelToken} from '../../../models/change/change-model';
import {getFileExtension} from '../../../utils/file-util';
import {ChangeStatus} from '../../../api/rest-api';
import {SpecialFilePath} from '../../../constants/constants';

export interface DiffPreview {
  filepath: string;
  preview: DiffInfo;
}

@customElement('gr-apply-fix-dialog')
export class GrApplyFixDialog extends LitElement {
  @query('#applyFixModal')
  applyFixModal?: HTMLDialogElement;

  @query('#applyFixDialog')
  applyFixDialog?: GrDialog;

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

  @state()
  change?: ParsedChangeInfo;

  @state()
  changeNum?: NumericChangeId;

  @state()
  patchNum?: PatchSetNum;

  @state() latestPatchNum?: PatchSetNumber;

  @state()
  currentFix?: FixSuggestionInfo;

  @state()
  currentPreviews: DiffPreview[] = [];

  @state()
  fixSuggestions?: FixSuggestionInfo[];

  @state()
  isApplyFixLoading = false;

  @state()
  selectedFixIdx = 0;

  @state()
  layers: DiffLayer[] = [];

  @state()
  diffPrefs?: DiffPreferencesInfo;

  @state()
  loading = false;

  @state()
  hasEdit = false;

  @state() isChangeMerged = false;

  @state() isChangeAbandoned = false;

  @state()
  onCloseFixPreviewCallbacks: ((fixapplied: boolean) => void)[] = [];

  @state() loggedIn = false;

  private readonly restApiService = getAppContext().restApiService;

  private readonly getUserModel = resolve(this, userModelToken);

  private readonly getChangeModel = resolve(this, changeModelToken);

  private readonly getNavigation = resolve(this, navigationToken);

  private readonly getViewModel = resolve(this, changeViewModelToken);

  private readonly reporting = getAppContext().reportingService;

  private readonly syntaxLayer = new GrSyntaxLayerWorker(
    resolve(this, highlightServiceToken),
    () => getAppContext().reportingService
  );

  constructor() {
    super();
    subscribe(
      this,
      () => this.getUserModel().preferences$,
      preferences => {
        const layers: DiffLayer[] = [this.syntaxLayer];
        if (!preferences?.disable_token_highlighting) {
          layers.push(new TokenHighlightLayer(this));
        }
        this.layers = layers;
      }
    );
    subscribe(
      this,
      () => this.getUserModel().loggedIn$,
      loggedIn => {
        this.loggedIn = loggedIn;
      }
    );
    subscribe(
      this,
      () => this.getUserModel().diffPreferences$,
      diffPreferences => {
        if (!diffPreferences) return;
        this.diffPrefs = diffPreferences;
        this.syntaxLayer.setEnabled(!!this.diffPrefs.syntax_highlighting);
      }
    );
    subscribe(
      this,
      () => this.getChangeModel().change$,
      change => (this.change = change)
    );
    subscribe(
      this,
      () => this.getChangeModel().changeNum$,
      changeNum => (this.changeNum = changeNum)
    );
    subscribe(
      this,
      () => this.getChangeModel().latestPatchNum$,
      x => (this.latestPatchNum = x)
    );
    subscribe(
      this,
      () => this.getChangeModel().status$,
      status => (this.isChangeMerged = status === ChangeStatus.MERGED)
    );
    subscribe(
      this,
      () => this.getChangeModel().status$,
      status => (this.isChangeAbandoned = status === ChangeStatus.ABANDONED)
    );
    subscribe(
      this,
      () => this.getChangeModel().revisions$,
      revisions =>
        (this.hasEdit = Object.values(revisions).some(
          info => info._number === EDIT
        ))
    );
  }

  static override get styles() {
    return [
      sharedStyles,
      modalStyles,
      css`
        .diffContainer {
          padding: var(--spacing-l) 0;
          border-bottom: 1px solid var(--border-color);
        }
        .file-name {
          display: block;
          padding: var(--spacing-s) var(--spacing-l);
          background-color: var(--background-color-secondary);
          border-bottom: 1px solid var(--border-color);
        }
        gr-button {
          margin-left: var(--spacing-m);
        }
        .fix-picker {
          display: flex;
          align-items: center;
          margin-right: var(--spacing-l);
        }
        .info {
          background-color: var(--info-background);
          padding: var(--spacing-l) var(--spacing-xl);
        }
        .info gr-icon {
          color: var(--selected-foreground);
          margin-right: var(--spacing-xl);
        }
      `,
    ];
  }

  override render() {
    return html`
      <dialog id="applyFixModal" tabindex="-1">
        <gr-dialog
          id="applyFixDialog"
          ?loading=${this.loading}
          .loadingLabel=${'Creating preview ...'}
          .confirmLabel=${this.isApplyFixLoading ? 'Saving...' : 'Apply Fix'}
          .confirmTooltip=${this.computeTooltip()}
          ?disabled=${this.computeDisableApplyFixButton()}
          @confirm=${this.handleApplyFix}
          @cancel=${this.onCancel}
        >
          ${this.renderHeader()} ${this.renderMain()} ${this.renderFooter()}
        </gr-dialog>
      </dialog>
    `;
  }

  private renderHeader() {
    return html`
      <div slot="header">${this.currentFix?.description ?? ''}</div>
    `;
  }

  private renderMain() {
    const items = this.currentPreviews.map(
      item => html`
        <div class="file-name">
          <span>${item.filepath}</span>
        </div>
        <div class="diffContainer">${this.renderDiff(item)}</div>
      `
    );
    return html`<div slot="main">${items}</div>`;
  }

  private renderDiff(preview: DiffPreview) {
    const diff = preview.preview;
    this.syntaxLayer.process(diff);
    return html`<gr-diff
      .prefs=${this.overridePartialDiffPrefs()}
      .path=${preview.filepath}
      .diff=${diff}
      .layers=${this.layers}
    ></gr-diff>`;
  }

  private renderFooter() {
    const fixCount = this.fixSuggestions?.length ?? 0;
    const reasonForDisabledApplyButton = this.computeTooltip();
    const shouldRenderNav = fixCount >= 2;
    const shouldRenderWarning = !!reasonForDisabledApplyButton;

    if (!shouldRenderNav && !shouldRenderWarning) return nothing;

    return html`
      <div slot="footer" class="fix-picker">
        ${when(shouldRenderNav, () =>
          this.renderNavForMultipleSuggestedFixes(fixCount)
        )}
        ${when(shouldRenderWarning, () =>
          this.renderWarning(reasonForDisabledApplyButton)
        )}
      </div>
    `;
  }

  private renderNavForMultipleSuggestedFixes(fixCount: number) {
    const id = this.selectedFixIdx;
    return html`
      <span>Suggested fix ${id + 1} of ${fixCount}</span>
      <gr-button
        id="prevFix"
        @click=${this.onPrevFixClick}
        ?disabled=${id === 0}
      >
        <gr-icon icon="chevron_left"></gr-icon>
      </gr-button>
      <gr-button
        id="nextFix"
        @click=${this.onNextFixClick}
        ?disabled=${id === fixCount - 1}
      >
        <gr-icon icon="chevron_right"></gr-icon>
      </gr-button>
    `;
  }

  private renderWarning(message: string) {
    if (!message) return nothing;
    return html`<span class="info"
      ><gr-icon icon="info"></gr-icon>${message}</span
    >`;
  }

  /**
   * Given event with fixSuggestions, fetch diffs associated with first
   * suggested fix and open dialog.
   */
  open(e: OpenFixPreviewEvent) {
    this.patchNum = e.detail.patchNum;
    this.fixSuggestions = e.detail.fixSuggestions;
    this.onCloseFixPreviewCallbacks = e.detail.onCloseFixPreviewCallbacks;
    assert(this.fixSuggestions.length > 0, 'no fix in the event');
    this.selectedFixIdx = 0;
    this.applyFixModal?.showModal();
    return this.showSelectedFixSuggestion(this.fixSuggestions[0]);
  }

  private async showSelectedFixSuggestion(fixSuggestion: FixSuggestionInfo) {
    this.currentFix = fixSuggestion;
    this.loading = true;
    this.reporting.time(Timing.PREVIEW_FIX_LOAD);
    await this.fetchFixPreview(fixSuggestion);
    this.reporting.timeEnd(Timing.PREVIEW_FIX_LOAD);
    this.loading = false;
  }

  private async fetchFixPreview(fixSuggestion: FixSuggestionInfo) {
    if (!this.changeNum || !this.patchNum) {
      return Promise.reject(
        new Error('Both patchNum and changeNum must be set')
      );
    }
    let res: FilePathToDiffInfoMap | undefined;
    try {
      res = await this.restApiService.getFixPreview(
        this.changeNum,
        this.patchNum,
        fixSuggestion.replacements
      );
      if (res) {
        this.currentPreviews = Object.keys(res).map(key => {
          return {filepath: key, preview: res![key]};
        });
      }
    } catch (e) {
      this.close(false);
      throw e;
    }
    return res;
  }

  private overridePartialDiffPrefs() {
    if (!this.diffPrefs) return undefined;
    // generate a smaller gr-diff than fullscreen for dialog
    return {
      ...this.diffPrefs,
      line_length: Math.min(this.diffPrefs.line_length, 100),
    };
  }

  // visible for testing
  onCancel(e: Event) {
    if (e) e.stopPropagation();
    this.close(false);
  }

  // visible for testing
  onPrevFixClick(e: Event) {
    if (e) e.stopPropagation();
    if (this.selectedFixIdx >= 1 && this.fixSuggestions) {
      this.selectedFixIdx -= 1;
      this.showSelectedFixSuggestion(this.fixSuggestions[this.selectedFixIdx]);
    }
  }

  // visible for testing
  onNextFixClick(e: Event) {
    if (e) e.stopPropagation();
    if (
      this.fixSuggestions &&
      this.selectedFixIdx < this.fixSuggestions.length
    ) {
      this.selectedFixIdx += 1;
      this.showSelectedFixSuggestion(this.fixSuggestions[this.selectedFixIdx]);
    }
  }

  private close(fixApplied: boolean) {
    this.currentFix = undefined;
    this.currentPreviews = [];
    this.isApplyFixLoading = false;

    this.onCloseFixPreviewCallbacks.forEach(fn => fn(fixApplied));
    this.applyFixModal?.close();
    if (fixApplied) fireReload(this);
  }

  private computeTooltip() {
    if (!this.change || !this.patchNum) return '';
    if (this.isChangeMerged) return 'Change is already merged';
    if (this.isChangeAbandoned) return 'Change is abandoned';
    if (this.isApplyFixLoading) return 'Fix is still loading ...';
    if (!this.loggedIn) return 'You must be logged in to apply a fix';
    if (
      this.currentPreviews[0]?.filepath === SpecialFilePath.COMMIT_MESSAGE &&
      this.patchNum !== this.latestPatchNum
    )
      return 'You cannot apply a commit message edit from a previous patch set';
    return '';
  }

  private computeDisableApplyFixButton() {
    if (!this.change || !this.patchNum) return true;
    if (this.isChangeMerged) return true;
    if (this.isChangeAbandoned) return true;
    if (!this.loggedIn) return true;
    if (
      this.currentPreviews[0]?.filepath === SpecialFilePath.COMMIT_MESSAGE &&
      this.patchNum !== this.latestPatchNum
    )
      return true;
    return this.isApplyFixLoading;
  }

  // visible for testing
  async handleApplyFix(e: Event) {
    if (e) e.stopPropagation();

    const {changeNum, patchNum, change} = this;
    if (!changeNum || !patchNum || !change || !this.currentFix) {
      throw new Error('Not all required properties are set.');
    }
    this.isApplyFixLoading = true;
    this.reporting.time(Timing.APPLY_FIX_LOAD);
    let res: Response | undefined = undefined;
    // Similar to gr-suggestion-diff-preview.ts:applyFix()
    const fixSuggestion = this.fixSuggestions?.[this.selectedFixIdx];
    if (!fixSuggestion) {
      throw new Error('No fix suggestion selected');
    }
    let errorText = '';
    let status = '';
    try {
      res = await this.restApiService.applyFixSuggestion(
        changeNum,
        patchNum,
        fixSuggestion.replacements,
        this.latestPatchNum
      );
    } catch (error) {
      if (error instanceof Error) {
        errorText = error.message;
        status = errorText.match(/\b\d{3}\b/)?.[0] || '';
      }
      fireError(this, `Applying Fix failed.\n${errorText}`);
    } finally {
      this.reporting.timeEnd(Timing.APPLY_FIX_LOAD, {
        method: 'apply-fix-dialog',
        description: this.fixSuggestions?.[0].description,
        fileExtension: getFileExtension(
          this.fixSuggestions?.[0]?.replacements?.[0].path ?? ''
        ),
        success: res?.ok ?? false,
        status: res?.status ?? status,
        errorText,
      });
    }
    if (res?.ok) {
      const currentChildView = this.getViewModel().getState()?.childView;
      const filePath =
        fixSuggestion.replacements[0]?.path ??
        this.currentPreviews[0]?.filepath;
      this.getNavigation().setUrl(
        createApplyFixUrl({
          change,
          basePatchNum: patchNum as BasePatchSetNum,
          forceReload: !this.hasEdit,
          filePath,
          currentChildView,
        })
      );
      this.close(true);
    }

    this.isApplyFixLoading = false;
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-apply-fix-dialog': GrApplyFixDialog;
  }
}
