/**
 * @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, query, state} from 'lit/decorators.js';
import {getAppContext} from '../../../services/app-context';
import {EDIT, PatchSetNumber, RepoName} from '../../../types/common';
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,
  RevisionPatchSetNum,
} from '../../../api/rest-api';
import {changeModelToken} from '../../../models/change/change-model';
import {subscribe} from '../../lit/subscription-controller';
import {DiffPreview} from '../../diff/gr-apply-fix-dialog/gr-apply-fix-dialog';
import {userModelToken} from '../../../models/user/user-model';
import {navigationToken} from '../../core/gr-navigation/gr-navigation';
import {fire, fireError} from '../../../utils/event-util';
import {Timing} from '../../../constants/reporting';
import {
  changeViewModelToken,
  createApplyFixUrl,
} from '../../../models/views/change';

import {getFileExtension} from '../../../utils/file-util';
import {throwingErrorCallback} from '../gr-rest-api-interface/gr-rest-apis/gr-rest-api-helper';
import {ReportSource} from '../../../services/suggestions/suggestions-service';
import {replacementsToString} from '../../../utils/comment-util';
import {GrTextarea} from '../../../embed/gr-textarea';

export interface PreviewLoadedDetail {
  previewLoadedFor?: FixSuggestionInfo;
}
/**
 * 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 {
  @query('#edit-textarea')
  textarea?: GrTextarea;

  // Optional. Used as backup when preview is not loaded.
  @property({type: String})
  codeText?: string;

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

  // Used to determine if the preview has been loaded
  // this is identical to previewLoadedFor !== undefined and can be removed
  @property({type: Boolean, attribute: 'previewed', reflect: true})
  previewed = false;

  // Optional. Used in logging.
  @property({type: String})
  uuid?: string;

  @property({type: Number})
  patchSet?: RevisionPatchSetNum;

  // Optional. Used in logging.
  @property({type: String})
  commentId?: string;

  @property({type: Boolean, reflect: true})
  editable = false;

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

  /**
   * The fix suggestion info that the preview is loaded for.
   *
   * This is used to determine if the preview has been loaded for the same
   * fix suggestion info currently in gr-comment.
   */
  @state()
  public previewLoadedFor?: {
    fixSuggestionInfo: FixSuggestionInfo;
    changeNum: NumericChangeId;
    patchSet: RevisionPatchSetNum;
  };

  @state() repo?: RepoName;

  @state() hasEdit = false;

  @state()
  changeNum?: NumericChangeId;

  @state()
  preview?: DiffPreview;

  @state()
  diffPrefs?: DiffPreferencesInfo;

  @state() latestPatchNum?: PatchSetNumber;

  @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 getNavigation = resolve(this, navigationToken);

  private readonly getViewModel = resolve(this, changeViewModelToken);

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

  constructor() {
    super();
    subscribe(
      this,
      () => this.getChangeModel().changeNum$,
      changeNum => (this.changeNum = changeNum)
    );
    subscribe(
      this,
      () => this.getChangeModel().revisions$,
      revisions =>
        (this.hasEdit = Object.values(revisions).some(
          info => info._number === EDIT
        ))
    );
    subscribe(
      this,
      () => this.getChangeModel().latestPatchNum$,
      x => (this.latestPatchNum = x)
    );
    subscribe(
      this,
      () => this.getUserModel().diffPreferences$,
      diffPreferences => {
        if (!diffPreferences) return;
        this.diffPrefs = diffPreferences;
        this.syntaxLayer.setEnabled(!!this.diffPrefs.syntax_highlighting);
      }
    );
    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;
          max-height: 70vh;
          overflow-y: auto;
        }
        #edit-textarea {
          width: 100%;
          height: 200px;
        }
        /*
         * On some operating systems (e.g. macOS), scrollbars are hidden by
         * default and only appear when scrolling. The following rules force
         * the scrollbar to be visible when the content overflows.
         *
         * This is only enabled for devices with a mouse, because it would be
         * obtrusive on touch devices.
         */
        @media (pointer: fine) {
          .diff-container::-webkit-scrollbar,
          .diff-container::-webkit-scrollbar-corner {
            background: transparent;
            height: 12px;
            width: 12px;
          }
          .diff-container::-webkit-scrollbar-button {
            height: 0;
            width: 0;
          }
          .diff-container::-webkit-scrollbar-thumb {
            background: content-box currentColor;
            border: 2px solid transparent;
            border-radius: 8px;
            color: var(--deemphasized-text-color);
            min-height: 48px;
            min-width: 48px;
          }
        }
        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('fixSuggestionInfo') ||
      changed.has('changeNum') ||
      changed.has('patchSet')
    ) {
      this.fetchIfReplacementsChanged();
    }
  }

  override render() {
    if (!this.fixSuggestionInfo) return nothing;
    return html`
      ${when(
        this.previewLoadedFor,
        () => this.renderDiff(),
        () => html`<code>${this.codeText}</code>`
      )}
      ${when(this.editable, () => this.renderTextarea())}
    `;
  }

  private renderTextarea() {
    const suggestion = replacementsToString(
      this.fixSuggestionInfo?.replacements ?? []
    );
    return html`<gr-textarea
      id="edit-textarea"
      .value=${suggestion}
    ></gr-textarea>`;
  }

  private renderDiff() {
    if (!this.preview) return;
    const diff = this.preview.preview;
    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 fetchIfReplacementsChanged() {
    if (!this.changeNum || !this.patchSet || !this.fixSuggestionInfo) return;
    if (
      this.previewLoadedFor &&
      this.previewLoadedFor.changeNum === this.changeNum &&
      this.previewLoadedFor.patchSet === this.patchSet &&
      replacementsToString(
        this.previewLoadedFor.fixSuggestionInfo.replacements
      ) === replacementsToString(this.fixSuggestionInfo.replacements)
    ) {
      return;
    }

    this.reporting.time(Timing.PREVIEW_FIX_LOAD);
    const res = await this.restApiService.getFixPreview(
      this.changeNum,
      this.patchSet,
      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.commentId ?? '',
    });
    if (currentPreviews.length > 0) {
      this.preview = currentPreviews[0];
      this.previewLoadedFor = {
        fixSuggestionInfo: this.fixSuggestionInfo,
        changeNum: this.changeNum,
        patchSet: this.patchSet,
      };

      this.previewed = true;

      fire(this, 'preview-loaded', {
        previewLoadedFor: this.fixSuggestionInfo,
      });
    }

    return res;
  }

  public reset() {
    if (this.textarea && this.fixSuggestionInfo) {
      this.textarea.value = replacementsToString(
        this.fixSuggestionInfo.replacements
      );
    }
  }

  public getEditedContent(): string | undefined {
    return this.textarea?.value;
  }

  /**
   * 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 async applyFix() {
    const changeNum = this.changeNum;
    const basePatchNum = this.patchSet;
    const fixSuggestion = this.fixSuggestionInfo;
    if (!changeNum || !basePatchNum || !fixSuggestion) return;

    this.reporting.time(Timing.APPLY_FIX_LOAD);
    let res: Response | undefined = undefined;
    let errorText = '';
    let status = '';
    try {
      res = await this.restApiService.applyFixSuggestion(
        changeNum,
        basePatchNum,
        fixSuggestion.replacements,
        this.latestPatchNum,
        throwingErrorCallback
      );
    } 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: '1-click',
        description: fixSuggestion.description,
        fileExtension: getFileExtension(
          fixSuggestion?.replacements?.[0].path ?? ''
        ),
        commentId: this.commentId ?? '',
        success: res?.ok ?? false,
        status: res?.status ?? status,
        errorText,
      });
    }
    // basePatchNum is from comment patchset and comment cannot be created
    // in EDIT. RevisionPatchset without EDIT is PatchSetNumber
    if (res?.ok && basePatchNum !== undefined && basePatchNum !== EDIT) {
      const currentChildView = this.getViewModel().getState()?.childView;
      const filePath =
        fixSuggestion.replacements[0]?.path ?? this.preview?.filepath;
      this.getNavigation().setUrl(
        createApplyFixUrl({
          changeNum,
          repo: this.repo!,
          basePatchNum: basePatchNum as PatchSetNumber,
          forceReload: !this.hasEdit,
          filePath,
          currentChildView,
        })
      );

      if (filePath) {
        fire(this, 'reload-diff', {path: filePath});
      }
      fire(this, 'apply-user-suggestion', {
        fixSuggestion: fixSuggestion.description.includes(
          ReportSource.GET_AI_FIX_FOR_COMMENT
        )
          ? fixSuggestion
          : undefined,
      });
    }
  }

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

declare global {
  interface HTMLElementTagNameMap {
    'gr-suggestion-diff-preview': GrSuggestionDiffPreview;
  }
  interface HTMLElementEventMap {
    'preview-loaded': CustomEvent<PreviewLoadedDetail>;
  }
}
