/**
 * @license
 * Copyright 2023 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '../../../embed/diff/gr-diff/gr-diff';
import {css, html, LitElement, nothing, PropertyValues} from 'lit';
import {customElement, property, state} from 'lit/decorators.js';
import {getAppContext} from '../../../services/app-context';
import {Comment, EDIT, BasePatchSetNum, RepoName} from '../../../types/common';
import {anyLineTooLong} from '../../../utils/diff-util';
import {
  DiffLayer,
  DiffPreferencesInfo,
  DiffViewMode,
  RenderPreferences,
} from '../../../api/diff';
import {when} from 'lit/directives/when.js';
import {GrSyntaxLayerWorker} from '../../../embed/diff/gr-syntax-layer/gr-syntax-layer-worker';
import {resolve} from '../../../models/dependency';
import {highlightServiceToken} from '../../../services/highlight/highlight-service';
import {FixSuggestionInfo, NumericChangeId} from '../../../api/rest-api';
import {changeModelToken} from '../../../models/change/change-model';
import {subscribe} from '../../lit/subscription-controller';
import {FilePreview} from '../../diff/gr-apply-fix-dialog/gr-apply-fix-dialog';
import {userModelToken} from '../../../models/user/user-model';
import {createUserFixSuggestion} from '../../../utils/comment-util';
import {commentModelToken} from '../gr-comment-model/gr-comment-model';
import {navigationToken} from '../../core/gr-navigation/gr-navigation';
import {fire} from '../../../utils/event-util';
import {Interaction, Timing} from '../../../constants/reporting';
import {createChangeUrl} from '../../../models/views/change';
import {getFileExtension} from '../../../utils/file-util';

declare global {
  interface HTMLElementEventMap {
    'add-generated-suggestion': AddGeneratedSuggestionEvent;
  }
}

export type AddGeneratedSuggestionEvent =
  CustomEvent<OpenUserSuggestionPreviewEventDetail>;
export interface OpenUserSuggestionPreviewEventDetail {
  code: string;
}

/**
 * Diff preview for
 * 1. code block suggestion vs commented Text
 * or 2. fixSuggestionInfo that are attached to a comment.
 *
 * It shouldn't be created with both 1. and 2. but if it is
 * it shows just for 1. (code block suggestion)
 */
@customElement('gr-suggestion-diff-preview')
export class GrSuggestionDiffPreview extends LitElement {
  @property({type: String})
  suggestion?: string;

  @property({type: Object})
  fixSuggestionInfo?: FixSuggestionInfo;

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

  @property({type: Boolean, attribute: 'previewed', reflect: true})
  previewed = false;

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

  @state()
  comment?: Comment;

  @state()
  commentedText?: string;

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

  @state()
  previewLoadedFor?: string | FixSuggestionInfo;

  @state() repo?: RepoName;

  @state()
  changeNum?: NumericChangeId;

  @state()
  preview?: FilePreview;

  @state()
  diffPrefs?: DiffPreferencesInfo;

  @state()
  renderPrefs: RenderPreferences = {
    disable_context_control_buttons: true,
    show_file_comment_button: false,
    hide_line_length_indicator: true,
  };

  private readonly reporting = getAppContext().reportingService;

  private readonly getChangeModel = resolve(this, changeModelToken);

  private readonly restApiService = getAppContext().restApiService;

  private readonly getUserModel = resolve(this, userModelToken);

  private readonly getCommentModel = resolve(this, commentModelToken);

  private readonly getNavigation = resolve(this, navigationToken);

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

  constructor() {
    super();
    subscribe(
      this,
      () => this.getChangeModel().changeNum$,
      changeNum => (this.changeNum = changeNum)
    );
    subscribe(
      this,
      () => this.getUserModel().diffPreferences$,
      diffPreferences => {
        if (!diffPreferences) return;
        this.diffPrefs = diffPreferences;
        this.syntaxLayer.setEnabled(!!this.diffPrefs.syntax_highlighting);
      }
    );
    subscribe(
      this,
      () => this.getCommentModel().comment$,
      comment => (this.comment = comment)
    );
    subscribe(
      this,
      () => this.getCommentModel().commentedText$,
      commentedText => (this.commentedText = commentedText)
    );
    subscribe(
      this,
      () => this.getChangeModel().repo$,
      x => (this.repo = x)
    );
  }

  static override get styles() {
    return [
      css`
        :host {
          display: block;
        }
        .buttons {
          text-align: right;
        }
        .diff-container {
          border: 1px solid var(--border-color);
          border-top: none;
        }
        code {
          max-width: var(--gr-formatted-text-prose-max-width, none);
          background-color: var(--background-color-secondary);
          border: 1px solid var(--border-color);
          border-top: 0;
          display: block;
          font-family: var(--monospace-font-family);
          font-size: var(--font-size-code);
          line-height: var(--line-height-mono);
          margin-bottom: var(--spacing-m);
          padding: var(--spacing-xxs) var(--spacing-s);
          overflow-x: auto;
          /* Pre will preserve whitespace and line breaks but not wrap */
          white-space: pre;
          border-bottom-left-radius: var(--border-radius);
          border-bottom-right-radius: var(--border-radius);
        }
      `,
    ];
  }

  override updated(changed: PropertyValues) {
    if (changed.has('commentedText') || changed.has('comment')) {
      if (this.previewLoadedFor !== this.suggestion) {
        this.fetchFixPreview();
      }
    }

    if (changed.has('changeNum') || changed.has('comment')) {
      if (this.previewLoadedFor !== this.fixSuggestionInfo) {
        this.fetchfixSuggestionInfoPreview();
      }
    }
  }

  override render() {
    if (!this.suggestion && !this.fixSuggestionInfo) return nothing;
    const code = this.suggestion;
    return html`
      ${when(
        this.previewLoadedFor,
        () => this.renderDiff(),
        () => html`<code>${code}</code>`
      )}
      ${when(
        this.showAddSuggestionButton,
        () =>
          html`<div class="buttons">
            <gr-button
              link
              class="action add-suggestion"
              @click=${this.handleAddGeneratedSuggestion}
            >
              Add suggestion to comment
            </gr-button>
          </div>`
      )}
    `;
  }

  private renderDiff() {
    if (!this.preview) return;
    const diff = this.preview.preview;
    if (!anyLineTooLong(diff)) {
      this.syntaxLayer.process(diff);
    }
    return html`<div class="diff-container">
      <gr-diff
        .prefs=${this.overridePartialDiffPrefs()}
        .path=${this.preview.filepath}
        .diff=${diff}
        .layers=${this.layers}
        .renderPrefs=${this.renderPrefs}
        .viewMode=${DiffViewMode.UNIFIED}
      ></gr-diff>
    </div>`;
  }

  private async fetchFixPreview() {
    if (
      !this.changeNum ||
      !this.comment?.patch_set ||
      !this.suggestion ||
      !this.commentedText
    )
      return;
    const fixSuggestions = createUserFixSuggestion(
      this.comment,
      this.commentedText,
      this.suggestion
    );
    this.reporting.time(Timing.PREVIEW_FIX_LOAD);
    const res = await this.restApiService.getFixPreview(
      this.changeNum,
      this.comment?.patch_set,
      fixSuggestions[0].replacements
    );
    if (!res) return;
    const currentPreviews = Object.keys(res).map(key => {
      return {filepath: key, preview: res[key]};
    });
    this.reporting.timeEnd(Timing.PREVIEW_FIX_LOAD, {
      uuid: this.uuid,
      commentId: this.comment?.id ?? '',
    });
    if (currentPreviews.length > 0) {
      this.preview = currentPreviews[0];
      this.previewLoadedFor = this.suggestion;
    }

    return res;
  }

  private async fetchfixSuggestionInfoPreview() {
    if (
      this.suggestion ||
      !this.changeNum ||
      !this.comment?.patch_set ||
      !this.fixSuggestionInfo
    )
      return;

    this.previewed = false;
    this.reporting.time(Timing.PREVIEW_FIX_LOAD);
    const res = await this.restApiService.getFixPreview(
      this.changeNum,
      this.comment?.patch_set,
      this.fixSuggestionInfo.replacements
    );

    if (!res) return;
    const currentPreviews = Object.keys(res).map(key => {
      return {filepath: key, preview: res[key]};
    });
    this.reporting.timeEnd(Timing.PREVIEW_FIX_LOAD, {
      uuid: this.uuid,
      commentId: this.comment?.id ?? '',
    });
    if (currentPreviews.length > 0) {
      this.preview = currentPreviews[0];
      this.previewLoadedFor = this.fixSuggestionInfo;
      this.previewed = true;
    }

    return res;
  }

  /**
   * Applies a fix (fix_suggestion in comment) previewed in
   * `suggestion-diff-preview`, navigating to the new change URL with the EDIT
   * patchset.
   *
   * Similar code flow is in gr-apply-fix-dialog.handleApplyFix
   * Used in gr-fix-suggestions
   */
  public applyFixSuggestion() {
    if (this.suggestion || !this.fixSuggestionInfo) return;
    this.applyFix(this.fixSuggestionInfo);
  }

  /**
   * Applies a fix (codeblock in comment message) previewed in
   * `suggestion-diff-preview`, navigating to the new change URL with the EDIT
   * patchset.
   *
   * Similar code flow is in gr-apply-fix-dialog.handleApplyFix
   * Used in gr-user-suggestion-fix
   */
  public applyUserSuggestedFix() {
    if (!this.comment || !this.suggestion || !this.commentedText) return;

    const fixSuggestions = createUserFixSuggestion(
      this.comment,
      this.commentedText,
      this.suggestion
    );
    this.applyFix(fixSuggestions[0]);
  }

  private async applyFix(fixSuggestion: FixSuggestionInfo) {
    const changeNum = this.changeNum;
    const basePatchNum = this.comment?.patch_set as BasePatchSetNum;
    if (!changeNum || !basePatchNum || !fixSuggestion) return;

    this.reporting.time(Timing.APPLY_FIX_LOAD);
    const res = await this.restApiService.applyFixSuggestion(
      changeNum,
      basePatchNum,
      fixSuggestion.replacements
    );
    this.reporting.timeEnd(Timing.APPLY_FIX_LOAD, {
      method: '1-click',
      description: fixSuggestion.description,
      fileExtension: getFileExtension(
        fixSuggestion?.replacements?.[0].path ?? ''
      ),
      commentId: this.comment?.id ?? '',
    });
    if (res?.ok) {
      this.getNavigation().setUrl(
        createChangeUrl({
          changeNum,
          repo: this.repo!,
          patchNum: EDIT,
          basePatchNum,
        })
      );
      fire(this, 'apply-user-suggestion', {});
    }
  }

  private overridePartialDiffPrefs() {
    if (!this.diffPrefs) return undefined;
    return {
      ...this.diffPrefs,
      context: 0,
      line_length: Math.min(this.diffPrefs.line_length, 100),
      line_wrapping: true,
    };
  }

  handleAddGeneratedSuggestion() {
    if (!this.suggestion) return;
    this.reporting.reportInteraction(Interaction.GENERATE_SUGGESTION_ADDED, {
      uuid: this.uuid,
      commentId: this.comment?.id ?? '',
    });
    fire(this, 'add-generated-suggestion', {code: this.suggestion});
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-suggestion-diff-preview': GrSuggestionDiffPreview;
  }
}
