/**
 * @license
 * Copyright 2026 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import {css, html, LitElement, nothing, PropertyValues} from 'lit';
import {customElement, property, query, state} from 'lit/decorators.js';
import {classMap} from 'lit/directives/class-map.js';
import {ifDefined} from 'lit/directives/if-defined.js';
import {when} from 'lit/directives/when.js';
import '../../shared/gr-button/gr-button';
import '../../shared/gr-icon/gr-icon';
import '../../shared/gr-comment-thread/gr-comment-thread';
import type {GrCommentThread} from '../../shared/gr-comment-thread/gr-comment-thread';
import {DiffInfo} from '../../../types/diff';
import {CommentSide, DiffViewMode, Side} from '../../../constants/constants';
import {
  CommentThread,
  DraftInfo,
  EDIT,
  PARENT,
  PatchRange,
  PatchSetNum,
  RevisionPatchSetNum,
} from '../../../types/common';
import {sanitizeHtmlToFragment} from '../../../utils/inner-html-util';
import {resolve} from '../../../models/dependency';
import {browserModelToken} from '../../../models/browser/browser-model';
import {commentsModelToken} from '../../../models/comments/comments-model';
import {userModelToken} from '../../../models/user/user-model';
import {ChangeComments} from '../gr-comment-api/gr-comment-api';
import {subscribe} from '../../lit/subscription-controller';
import {createNew} from '../../../utils/comment-util';
import {
  getParentIndex,
  isAParent,
  isMergeParent,
} from '../../../utils/patch-set-util';
import {assertIsDefined} from '../../../utils/common-util';
import {fire, fireAlert} from '../../../utils/event-util';
import {
  AlignedDiffRow,
  AlignedDiffRowWithThreads,
  alignMarkdownTokens,
  attachThreadsToRows,
  getThreadDiffSide,
  parseMarkdownBlocks,
  reconstructFileContent,
} from './markdown-diff-util';

@customElement('gr-diff-markdown-viewer')
export class GrDiffMarkdownViewer extends LitElement {
  @property({type: Object}) diff?: DiffInfo;

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

  @property({type: Object}) patchRange?: PatchRange;

  @property({type: Array}) threads?: CommentThread[];

  @property({type: String}) viewMode: DiffViewMode = DiffViewMode.SIDE_BY_SIDE;

  @state() alignedRows: AlignedDiffRow[] = [];

  @state() private internalThreads: CommentThread[] = [];

  @state() private changeComments?: ChangeComments;

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

  @query('.selection-action-box')
  private selectionActionBox?: HTMLElement;

  private selectionActionBoxVisible = false;

  private selectionBoxPositionBelow = false;

  private selectionBoxTop = 0;

  private selectionBoxLeft = 0;

  private selectedSide?: Side;

  private selectedLine?: number;

  private hoveredSide?: Side;

  private hoveredLine?: number;

  private readonly getBrowserModel = resolve(this, browserModelToken);

  private readonly getCommentsModel = resolve(this, commentsModelToken);

  private readonly getUserModel = resolve(this, userModelToken);

  constructor() {
    super();
    subscribe(
      this,
      () => this.getBrowserModel().diffViewMode$,
      mode => {
        if (mode) this.viewMode = mode;
      }
    );
    subscribe(
      this,
      () => this.getCommentsModel().changeComments$,
      changeComments => {
        this.changeComments = changeComments;
        this.updateInternalThreads();
      }
    );
    subscribe(
      this,
      () => this.getUserModel().loggedIn$,
      loggedIn => {
        this.loggedIn = loggedIn;
      }
    );
  }

  override connectedCallback() {
    super.connectedCallback();
    document.addEventListener('selectionchange', this.handleSelectionChange);
    window.addEventListener('keydown', this.handleKeyDown);
  }

  override disconnectedCallback() {
    super.disconnectedCallback();
    document.removeEventListener('selectionchange', this.handleSelectionChange);
    window.removeEventListener('keydown', this.handleKeyDown);
  }

  get effectiveThreads(): CommentThread[] {
    return this.threads ?? this.internalThreads;
  }

  get filePath(): string | undefined {
    return this.path ?? this.diff?.meta_b?.name ?? this.diff?.meta_a?.name;
  }

  private updateInternalThreads() {
    if (!this.changeComments || !this.patchRange || !this.filePath) return;
    this.internalThreads = this.changeComments.getThreadsBySideForFile(
      {path: this.filePath},
      this.patchRange
    );
  }

  static override get styles() {
    return [
      css`
        :host {
          display: block;
          position: relative;
          background-color: var(--view-background-color, #ffffff);
          color: var(--primary-text-color, #202124);
          font-family: var(--font-family, Roboto, sans-serif);
          font-size: var(--font-size-normal, 14px);
          line-height: var(--line-height-normal, 1.5);
        }
        .file-level-threads {
          padding: var(--spacing-m, 12px) var(--spacing-l, 16px);
          background-color: var(--background-color-secondary, #f8f9fa);
          border-bottom: 1px solid var(--border-color, #e0e0e0);
          display: flex;
          flex-direction: column;
          gap: var(--spacing-s, 8px);
        }
        .file-level-title {
          font-size: var(--font-size-small, 12px);
          font-weight: var(--font-weight-bold, 600);
          color: var(--deemphasized-text-color, #5f6368);
          text-transform: uppercase;
        }
        .column-headers {
          display: grid;
          grid-template-columns: 1fr 1fr;
          column-gap: var(--spacing-l, 16px);
          padding: var(--spacing-xs, 4px) var(--spacing-m, 12px);
          border-bottom: 1px solid var(--border-color, #e0e0e0);
          background-color: var(--background-color-secondary, #f8f9fa);
          color: var(--deemphasized-text-color, #5f6368);
          font-size: var(--font-size-small, 12px);
          font-weight: var(--font-weight-bold, 600);
          text-transform: uppercase;
          letter-spacing: 0.5px;
        }
        .diff-grid {
          display: grid;
          grid-template-columns: 1fr 1fr;
          column-gap: var(--spacing-l, 16px);
          row-gap: var(--spacing-m, 12px);
          padding: var(--spacing-m, 12px);
        }
        .diff-cell {
          position: relative;
          min-width: 0;
          overflow-wrap: break-word;
          padding: var(--spacing-xxs, 2px) var(--spacing-s, 8px);
          padding-right: 90px;
          border-left: 3px solid transparent;
          box-sizing: border-box;
          display: flex;
          flex-direction: column;
        }
        .diff-cell.empty {
          background-color: var(--diff-blank-background-color, transparent);
          min-height: 24px;
        }
        .diff-cell.added,
        .diff-cell.modified-right {
          border-left-color: var(--positive-green-text-color, #2da44e);
          background-color: var(--light-add-highlight-color, #d8fed8);
          border-radius: 0 4px 4px 0;
        }
        .diff-cell.deleted,
        .diff-cell.modified-left {
          border-left-color: var(--negative-red-text-color, #cf222e);
          background-color: var(--light-remove-highlight-color, #ffebee);
          border-radius: 0 4px 4px 0;
        }
        .unified-container {
          box-sizing: border-box;
          max-width: 100%;
          padding: var(--spacing-m, 12px) var(--spacing-l, 16px);
        }
        .unified-block {
          position: relative;
          border-left: 3px solid transparent;
          box-sizing: border-box;
          margin-bottom: var(--spacing-s, 8px);
          overflow-wrap: break-word;
          padding: var(--spacing-xxs, 2px) var(--spacing-s, 8px);
          padding-right: 90px;
          display: flex;
          flex-direction: column;
        }
        .unified-block.added {
          border-left-color: var(--positive-green-text-color, #2da44e);
          background-color: var(--light-add-highlight-color, #d8fed8);
          border-radius: 0 4px 4px 0;
        }
        .unified-block.deleted {
          border-left-color: var(--negative-red-text-color, #cf222e);
          background-color: var(--light-remove-highlight-color, #ffebee);
          border-radius: 0 4px 4px 0;
        }
        .unified-block.unchanged {
          border-left-color: transparent;
        }
        .cell-action-bar {
          position: absolute;
          top: 4px;
          right: 8px;
          z-index: 10;
          pointer-events: none;
        }
        .add-comment-btn {
          pointer-events: auto;
          opacity: 0;
          visibility: hidden;
          transition: opacity 0.15s ease-in-out, background-color 0.15s;
          background-color: var(--background-color-primary, #ffffff);
          color: var(--primary-text-color, #202124);
          border: 1px solid var(--border-color, #dadce0);
          border-radius: 16px;
          padding: 2px 8px;
          font-size: var(--font-size-small, 12px);
          font-weight: var(--font-weight-medium, 500);
          box-shadow: var(--elevation-level-1, 0 1px 3px rgba(60, 64, 67, 0.3));
          display: inline-flex;
          align-items: center;
          gap: 4px;
          cursor: pointer;
          user-select: none;
          line-height: 18px;
        }
        .add-comment-btn gr-icon {
          --gr-icon-size: 16px;
          color: var(--primary-text-color, #202124);
        }
        .diff-cell:hover .add-comment-btn,
        .unified-block:hover .add-comment-btn {
          opacity: 1;
          visibility: visible;
        }
        .add-comment-btn:hover {
          background: linear-gradient(
              var(--hover-background-color, rgba(161, 194, 250, 0.2)),
              var(--hover-background-color, rgba(161, 194, 250, 0.2))
            ),
            var(--background-color-primary, #ffffff);
          box-shadow: var(--elevation-level-2, 0 2px 6px rgba(60, 64, 67, 0.3));
        }
        .add-comment-btn:active {
          background: linear-gradient(rgba(0, 0, 0, 0.12), rgba(0, 0, 0, 0.12)),
            var(--background-color-primary, #ffffff);
        }
        .selection-action-box {
          position: absolute;
          z-index: 500;
          transform: translate(-50%, -100%);
          margin-top: -6px;
        }
        .selection-action-box.below {
          transform: translate(-50%, 0);
          margin-top: 6px;
        }
        .selection-comment-btn {
          background-color: var(--background-color-primary, #ffffff);
          color: var(--primary-text-color, #202124);
          border: 1px solid var(--border-color, #dadce0);
          border-radius: 16px;
          padding: 4px 12px;
          font-size: var(--font-size-small, 12px);
          font-weight: var(--font-weight-medium, 500);
          box-shadow: var(--elevation-level-2, 0 2px 6px rgba(60, 64, 67, 0.3));
          display: inline-flex;
          align-items: center;
          gap: 6px;
          cursor: pointer;
          white-space: nowrap;
          user-select: none;
        }
        .selection-comment-btn:hover {
          background: linear-gradient(
              var(--hover-background-color, rgba(161, 194, 250, 0.2)),
              var(--hover-background-color, rgba(161, 194, 250, 0.2))
            ),
            var(--background-color-primary, #ffffff);
          box-shadow: var(--elevation-level-3, 0 4px 8px rgba(60, 64, 67, 0.3));
        }
        .selection-comment-btn:active {
          background: linear-gradient(rgba(0, 0, 0, 0.12), rgba(0, 0, 0, 0.12)),
            var(--background-color-primary, #ffffff);
        }
        .selection-comment-btn gr-icon {
          --gr-icon-size: 16px;
          color: var(--primary-text-color, #202124);
        }
        .comment-thread {
          display: block;
          max-width: 100%;
        }
        .cell-content {
          min-width: 0;
        }
        .threads-container {
          margin-top: var(--spacing-s, 8px);
          padding-top: var(--spacing-xs, 4px);
          display: flex;
          flex-direction: column;
          gap: var(--spacing-s, 8px);
        }
        .diff-highlight-add,
        ins {
          background-color: var(--dark-add-highlight-color, #aaf2aa);
          text-decoration: none;
          border-radius: 2px;
          padding: 1px 2px;
        }
        .diff-highlight-del,
        del {
          background-color: var(--dark-remove-highlight-color, #ffcdd2);
          text-decoration: line-through;
          border-radius: 2px;
          padding: 1px 2px;
        }
        .diff-cell.deleted code,
        .diff-cell.modified-left code,
        .unified-block.deleted code,
        del code {
          background-color: rgba(0, 0, 0, 0.05);
        }
        .diff-cell.added code,
        .diff-cell.modified-right code,
        .unified-block.added code,
        ins code {
          background-color: rgba(0, 0, 0, 0.05);
        }
        .diff-cell.deleted pre,
        .diff-cell.modified-left pre,
        .unified-block.deleted pre {
          background-color: rgba(0, 0, 0, 0.03);
          border-color: rgba(207, 34, 46, 0.2);
        }
        .diff-cell.added pre,
        .diff-cell.modified-right pre,
        .unified-block.added pre {
          background-color: rgba(0, 0, 0, 0.03);
          border-color: rgba(46, 160, 67, 0.2);
        }
        pre .diff-highlight-del {
          display: inline-block;
          width: 100%;
          box-sizing: border-box;
        }
        pre .diff-highlight-add {
          display: inline-block;
          width: 100%;
          box-sizing: border-box;
        }
        .diff-cell.deleted th,
        .diff-cell.modified-left th,
        .unified-block.deleted th {
          background-color: rgba(0, 0, 0, 0.04);
        }
        h1,
        h2,
        h3,
        h4,
        h5,
        h6 {
          margin-top: 0;
          margin-bottom: var(--spacing-xs, 4px);
          color: var(--primary-text-color, #202124);
        }
        h1 {
          font-size: 1.6em;
          border-bottom: 1px solid var(--border-color, #e0e0e0);
          padding-bottom: 4px;
        }
        h2 {
          font-size: 1.3em;
          border-bottom: 1px solid var(--border-color, #e0e0e0);
          padding-bottom: 4px;
        }
        h3 {
          font-size: 1.15em;
        }
        p {
          margin-top: 0;
          margin-bottom: var(--spacing-xs, 4px);
        }
        code {
          font-family: var(--monospace-font-family, 'Roboto Mono', monospace);
          font-size: var(--font-size-code, 12px);
          background-color: var(--background-color-secondary, #f1f3f4);
          padding: 2px 4px;
          border-radius: 3px;
        }
        pre {
          background-color: var(--background-color-secondary, #f8f9fa);
          border: 1px solid var(--border-color, #e0e0e0);
          border-radius: 4px;
          padding: var(--spacing-s, 8px);
          overflow-x: auto;
          margin: 0;
        }
        pre code {
          background-color: transparent;
          padding: 0;
          font-size: var(--font-size-code, 12px);
          display: block;
          white-space: pre;
        }
        blockquote {
          border-left: 4px solid var(--border-color, #d0d7de);
          margin: 0 0 var(--spacing-s, 8px) 0;
          padding: 0 var(--spacing-m, 12px);
          color: var(--deemphasized-text-color, #5f6368);
        }
        ul,
        ol {
          margin-top: 0;
          margin-bottom: var(--spacing-xs, 4px);
          padding-left: var(--spacing-xl, 24px);
        }
        table {
          border-collapse: collapse;
          width: 100%;
          margin-bottom: var(--spacing-s, 8px);
        }
        th,
        td {
          border: 1px solid var(--border-color, #e0e0e0);
          padding: 6px 12px;
          text-align: left;
        }
        th {
          background-color: var(--background-color-secondary, #f8f9fa);
          font-weight: var(--font-weight-bold, 600);
        }
      `,
    ];
  }

  override willUpdate(changedProperties: PropertyValues) {
    if (changedProperties.has('diff')) {
      this.recomputeAlignedRows();
    }
    if (
      changedProperties.has('changeComments') ||
      changedProperties.has('patchRange') ||
      changedProperties.has('path')
    ) {
      this.updateInternalThreads();
    }
  }

  private recomputeAlignedRows() {
    if (!this.diff) {
      this.alignedRows = [];
      return;
    }
    const textA = reconstructFileContent(this.diff, Side.LEFT);
    const textB = reconstructFileContent(this.diff, Side.RIGHT);
    const tokensA = parseMarkdownBlocks(textA);
    const tokensB = parseMarkdownBlocks(textB);
    this.alignedRows = alignMarkdownTokens(tokensA, tokensB);
  }

  private canCommentOnPatchSetNum(patchNum: PatchSetNum) {
    if (!this.loggedIn) {
      fire(this, 'show-auth-required', {});
      return false;
    }
    if (!this.patchRange) {
      fireAlert(this, 'Cannot create comment. patchRange undefined.');
      return false;
    }

    const isEdit = patchNum === EDIT;
    const isEditBase = patchNum === PARENT && this.patchRange.patchNum === EDIT;

    if (isEdit) {
      fireAlert(this, 'You cannot comment on an edit.');
      return false;
    }
    if (isEditBase) {
      fireAlert(this, 'You cannot comment on the base patchset of an edit.');
      return false;
    }
    return true;
  }

  private computeParentIndex() {
    if (!this.patchRange) return null;
    return isMergeParent(this.patchRange.basePatchNum)
      ? getParentIndex(this.patchRange.basePatchNum)
      : null;
  }

  createComment(side: Side, lineNum?: number) {
    if (!this.patchRange) {
      fireAlert(this, 'Cannot create comment. patchRange undefined.');
      return;
    }

    const patchNum =
      side === Side.LEFT && !isAParent(this.patchRange.basePatchNum)
        ? this.patchRange.basePatchNum
        : this.patchRange.patchNum;
    const commentSide =
      side === Side.LEFT && isAParent(this.patchRange.basePatchNum)
        ? CommentSide.PARENT
        : CommentSide.REVISION;

    if (!this.canCommentOnPatchSetNum(patchNum)) return;
    const path = this.filePath;
    assertIsDefined(path, 'path');

    const basePath = this.diff?.meta_a?.name;
    const effectivePath =
      basePath && side === Side.LEFT && commentSide === CommentSide.REVISION
        ? basePath
        : path;

    let effectiveLine = lineNum;
    if (effectiveLine === undefined) {
      const fallbackRow = this.alignedRows.find(r =>
        side === Side.LEFT
          ? r.leftStartLine !== undefined
          : r.rightStartLine !== undefined
      );
      effectiveLine =
        side === Side.LEFT
          ? fallbackRow?.leftStartLine
          : fallbackRow?.rightStartLine ?? 1;
    }

    const parentIndex = this.computeParentIndex();
    const draft: DraftInfo = {
      ...createNew('', true),
      patch_set: patchNum as RevisionPatchSetNum,
      side: commentSide,
      parent: parentIndex ?? undefined,
      path: effectivePath,
      line: typeof effectiveLine === 'number' ? effectiveLine : undefined,
    };
    this.getCommentsModel().addNewDraft(draft);
  }

  private handleCellMouseEnter(side: Side, lineNum?: number) {
    this.hoveredSide = side;
    this.hoveredLine = lineNum;
  }

  private handleCellMouseLeave() {
    this.hoveredSide = undefined;
    this.hoveredLine = undefined;
  }

  private clearSelection() {
    (this.renderRoot as ShadowRoot)?.getSelection?.()?.removeAllRanges();
    window.getSelection()?.removeAllRanges();
    this.selectedSide = undefined;
    this.selectedLine = undefined;
  }

  hasActiveSelection(): boolean {
    const selection = this.getActiveSelection();
    if (!selection || selection.isCollapsed || !selection.rangeCount) {
      return false;
    }
    const range = selection.getRangeAt(0);
    const container = range.commonAncestorContainer;
    const elementNode =
      container.nodeType === Node.TEXT_NODE
        ? container.parentElement
        : (container as Element);
    return !!(
      elementNode &&
      this.renderRoot.contains(elementNode) &&
      elementNode.closest('.diff-cell, .unified-block')
    );
  }

  private getActiveSelection(): Selection | null {
    const shadowSelection = (this.renderRoot as ShadowRoot)?.getSelection?.();
    if (
      shadowSelection &&
      !shadowSelection.isCollapsed &&
      shadowSelection.rangeCount > 0
    ) {
      return shadowSelection;
    }
    const docSelection = window.getSelection();
    if (
      docSelection &&
      !docSelection.isCollapsed &&
      docSelection.rangeCount > 0
    ) {
      return docSelection;
    }
    return null;
  }

  private handleSelectionChange = () => {
    const selection = this.getActiveSelection();
    if (!selection || selection.isCollapsed || !selection.rangeCount) {
      if (this.selectionActionBoxVisible) {
        this.selectionActionBoxVisible = false;
        if (this.selectionActionBox) {
          this.selectionActionBox.style.display = 'none';
        }
      }
      return;
    }
    const range = selection.getRangeAt(0);
    const container = range.commonAncestorContainer;
    const elementNode =
      container.nodeType === Node.TEXT_NODE
        ? container.parentElement
        : (container as Element);
    if (!elementNode || !this.renderRoot.contains(elementNode)) {
      if (this.selectionActionBoxVisible) {
        this.selectionActionBoxVisible = false;
        if (this.selectionActionBox) {
          this.selectionActionBox.style.display = 'none';
        }
      }
      return;
    }
    const cell = elementNode.closest('.diff-cell, .unified-block');
    if (!cell) {
      if (this.selectionActionBoxVisible) {
        this.selectionActionBoxVisible = false;
        if (this.selectionActionBox) {
          this.selectionActionBox.style.display = 'none';
        }
      }
      return;
    }

    const rangeRect = range.getBoundingClientRect();
    const hostRect = this.getBoundingClientRect();

    const spaceAbove = rangeRect.top - hostRect.top;
    if (spaceAbove < 40) {
      this.selectionBoxTop = rangeRect.bottom - hostRect.top + this.scrollTop;
      this.selectionBoxPositionBelow = true;
    } else {
      this.selectionBoxTop = rangeRect.top - hostRect.top + this.scrollTop;
      this.selectionBoxPositionBelow = false;
    }
    this.selectionBoxLeft =
      rangeRect.left - hostRect.left + rangeRect.width / 2 + this.scrollLeft;
    const sideStr = cell.getAttribute('data-side');
    this.selectedSide = sideStr === 'left' ? Side.LEFT : Side.RIGHT;
    const lineStr = cell.getAttribute('data-line');
    this.selectedLine = lineStr ? Number(lineStr) : undefined;
    this.selectionActionBoxVisible = true;
    if (this.selectionActionBox) {
      this.selectionActionBox.style.display = 'block';
      this.selectionActionBox.style.top = `${this.selectionBoxTop}px`;
      this.selectionActionBox.style.left = `${this.selectionBoxLeft}px`;
      this.selectionActionBox.classList.toggle(
        'below',
        this.selectionBoxPositionBelow
      );
    }
  };

  private handleSelectionCommentClick(e: Event) {
    e.stopPropagation();
    if (this.selectedSide !== undefined) {
      this.createComment(this.selectedSide, this.selectedLine);
      this.selectionActionBoxVisible = false;
      if (this.selectionActionBox) {
        this.selectionActionBox.style.display = 'none';
      }
      this.clearSelection();
    }
  }

  private handleKeyDown = (e: KeyboardEvent) => {
    if (e.key === 'c' || e.key === 'C') {
      if (e.ctrlKey || e.metaKey || e.altKey) {
        return;
      }
      const target = e.composedPath()[0] as HTMLElement;
      if (
        target?.tagName === 'INPUT' ||
        target?.tagName === 'TEXTAREA' ||
        target?.tagName === 'GR-TEXTAREA' ||
        target?.isContentEditable
      ) {
        return;
      }
      if (this.hasActiveSelection() || this.hoveredSide !== undefined) {
        e.preventDefault();
        e.stopPropagation();
        this.createCommentFromSelectionOrHover();
      }
    }
  };

  createCommentFromSelectionOrHover() {
    const selection = this.getActiveSelection();
    if (selection && !selection.isCollapsed && selection.rangeCount > 0) {
      const range = selection.getRangeAt(0);
      const container = range.commonAncestorContainer;
      const elementNode =
        container.nodeType === Node.TEXT_NODE
          ? container.parentElement
          : (container as Element);
      if (elementNode && this.renderRoot.contains(elementNode)) {
        const cell = elementNode.closest('.diff-cell, .unified-block');
        if (cell) {
          const sideStr = cell.getAttribute('data-side');
          const side = sideStr === 'left' ? Side.LEFT : Side.RIGHT;
          const lineStr = cell.getAttribute('data-line');
          const line = lineStr ? Number(lineStr) : undefined;
          this.createComment(side, line);
          this.selectionActionBoxVisible = false;
          if (this.selectionActionBox) {
            this.selectionActionBox.style.display = 'none';
          }
          this.clearSelection();
          return;
        }
      }
    }
    if (this.selectedSide !== undefined) {
      this.createComment(this.selectedSide, this.selectedLine);
      this.selectionActionBoxVisible = false;
      if (this.selectionActionBox) {
        this.selectionActionBox.style.display = 'none';
      }
      this.clearSelection();
      return;
    }
    if (this.hoveredSide !== undefined) {
      this.createComment(this.hoveredSide, this.hoveredLine);
      return;
    }
    const firstRow = this.alignedRows.find(r => r.rightStartLine !== undefined);
    if (firstRow) {
      this.createComment(Side.RIGHT, firstRow.rightStartLine);
    } else {
      this.createComment(Side.RIGHT, 1);
    }
  }

  async autoSaveDrafts(): Promise<void> {
    const threadElements = Array.from(
      this.shadowRoot?.querySelectorAll<GrCommentThread>('gr-comment-thread') ??
        []
    );
    await Promise.all(threadElements.map(thread => thread.autoSave()));
  }

  override render() {
    if (this.viewMode === DiffViewMode.UNIFIED) {
      return this.renderUnifiedView();
    }
    return this.renderSideBySideView();
  }

  private renderThread(thread: CommentThread, side?: Side) {
    const diffSide = side ?? getThreadDiffSide(thread, this.patchRange);
    return html`
      <gr-comment-thread
        class="comment-thread"
        .rootId=${thread.rootId}
        .thread=${thread}
        .showPatchset=${false}
        .showPortedComment=${!!thread.ported}
        diff-side=${diffSide}
        line-num=${thread.line ?? 'FILE'}
      >
      </gr-comment-thread>
    `;
  }

  private renderCommentButton(side: Side, lineNum?: number) {
    if (lineNum === undefined) return nothing;
    return html`
      <div class="cell-action-bar">
        <button
          type="button"
          class="add-comment-btn"
          title="Add comment (line ${lineNum})"
          aria-label="Add comment (line ${lineNum})"
          @click=${(e: Event) => {
            e.stopPropagation();
            this.createComment(side, lineNum);
          }}
        >
          <gr-icon icon="add_comment" filled></gr-icon>
          <span>Comment</span>
        </button>
      </div>
    `;
  }

  private renderSelectionActionBox() {
    return html`
      <div
        class="selection-action-box ${this.selectionBoxPositionBelow
          ? 'below'
          : ''}"
        style="display: ${this.selectionActionBoxVisible
          ? 'block'
          : 'none'}; top: ${this.selectionBoxTop}px; left: ${this
          .selectionBoxLeft}px;"
      >
        <button
          type="button"
          class="selection-comment-btn"
          @mousedown=${(e: MouseEvent) => {
            e.preventDefault();
          }}
          @click=${this.handleSelectionCommentClick}
        >
          <gr-icon icon="add_comment" filled></gr-icon>
          <span>Comment (c)</span>
        </button>
      </div>
    `;
  }

  private renderSideBySideView() {
    const {rowsWithThreads, fileLevelThreads} = attachThreadsToRows(
      this.alignedRows,
      this.effectiveThreads,
      this.patchRange
    );

    return html`
      ${when(
        fileLevelThreads.length > 0,
        () => html`
          <div class="file-level-threads">
            <div class="file-level-title">File Comments</div>
            ${fileLevelThreads.map(t => this.renderThread(t))}
          </div>
        `
      )}
      <div class="column-headers">
        <div class="column-header left">Base</div>
        <div class="column-header right">Revision</div>
      </div>
      <div class="diff-grid" role="region" aria-label="Rich Markdown Diff">
        ${rowsWithThreads.map(row => this.renderRow(row))}
      </div>
      ${this.renderSelectionActionBox()}
    `;
  }

  private renderUnifiedView() {
    const {rowsWithThreads, fileLevelThreads} = attachThreadsToRows(
      this.alignedRows,
      this.effectiveThreads,
      this.patchRange
    );

    return html`
      ${when(
        fileLevelThreads.length > 0,
        () => html`
          <div class="file-level-threads">
            <div class="file-level-title">File Comments</div>
            ${fileLevelThreads.map(t => this.renderThread(t))}
          </div>
        `
      )}
      <div
        class="unified-container"
        role="region"
        aria-label="Rich Markdown Diff"
      >
        ${rowsWithThreads.map(row => this.renderUnifiedRow(row))}
      </div>
      ${this.renderSelectionActionBox()}
    `;
  }

  private renderUnifiedRow(row: AlignedDiffRowWithThreads) {
    if (row.status === 'unchanged') {
      const allThreads = [...row.leftThreads, ...row.rightThreads];
      return html`
        <div
          class="unified-block unchanged"
          data-side="right"
          data-line=${ifDefined(row.rightStartLine)}
          @mouseenter=${() =>
            this.handleCellMouseEnter(Side.RIGHT, row.rightStartLine)}
          @mouseleave=${() => this.handleCellMouseLeave()}
        >
          ${this.renderCommentButton(Side.RIGHT, row.rightStartLine)}
          <div class="cell-content">
            ${sanitizeHtmlToFragment(row.leftHtml ?? row.rightHtml ?? '')}
          </div>
          ${when(
            allThreads.length > 0,
            () => html`
              <div class="threads-container">
                ${allThreads.map(t => this.renderThread(t))}
              </div>
            `
          )}
        </div>
      `;
    }
    if (row.status === 'deleted') {
      return html`
        <div
          class="unified-block deleted"
          data-side="left"
          data-line=${ifDefined(row.leftStartLine)}
          @mouseenter=${() =>
            this.handleCellMouseEnter(Side.LEFT, row.leftStartLine)}
          @mouseleave=${() => this.handleCellMouseLeave()}
        >
          ${this.renderCommentButton(Side.LEFT, row.leftStartLine)}
          <div class="cell-content">
            ${sanitizeHtmlToFragment(row.leftHtml!)}
          </div>
          ${when(
            row.leftThreads.length > 0,
            () => html`
              <div class="threads-container">
                ${row.leftThreads.map(t => this.renderThread(t, Side.LEFT))}
              </div>
            `
          )}
        </div>
      `;
    }
    if (row.status === 'added') {
      return html`
        <div
          class="unified-block added"
          data-side="right"
          data-line=${ifDefined(row.rightStartLine)}
          @mouseenter=${() =>
            this.handleCellMouseEnter(Side.RIGHT, row.rightStartLine)}
          @mouseleave=${() => this.handleCellMouseLeave()}
        >
          ${this.renderCommentButton(Side.RIGHT, row.rightStartLine)}
          <div class="cell-content">
            ${sanitizeHtmlToFragment(row.rightHtml!)}
          </div>
          ${when(
            row.rightThreads.length > 0,
            () => html`
              <div class="threads-container">
                ${row.rightThreads.map(t => this.renderThread(t, Side.RIGHT))}
              </div>
            `
          )}
        </div>
      `;
    }
    // modified: render deleted (base) then added (revision)
    return html`
      <div
        class="unified-block deleted"
        data-side="left"
        data-line=${ifDefined(row.leftStartLine)}
        @mouseenter=${() =>
          this.handleCellMouseEnter(Side.LEFT, row.leftStartLine)}
        @mouseleave=${() => this.handleCellMouseLeave()}
      >
        ${this.renderCommentButton(Side.LEFT, row.leftStartLine)}
        <div class="cell-content">${sanitizeHtmlToFragment(row.leftHtml!)}</div>
        ${when(
          row.leftThreads.length > 0,
          () => html`
            <div class="threads-container">
              ${row.leftThreads.map(t => this.renderThread(t, Side.LEFT))}
            </div>
          `
        )}
      </div>
      <div
        class="unified-block added"
        data-side="right"
        data-line=${ifDefined(row.rightStartLine)}
        @mouseenter=${() =>
          this.handleCellMouseEnter(Side.RIGHT, row.rightStartLine)}
        @mouseleave=${() => this.handleCellMouseLeave()}
      >
        ${this.renderCommentButton(Side.RIGHT, row.rightStartLine)}
        <div class="cell-content">
          ${sanitizeHtmlToFragment(row.rightHtml!)}
        </div>
        ${when(
          row.rightThreads.length > 0,
          () => html`
            <div class="threads-container">
              ${row.rightThreads.map(t => this.renderThread(t, Side.RIGHT))}
            </div>
          `
        )}
      </div>
    `;
  }

  private renderRow(row: AlignedDiffRowWithThreads) {
    return html` ${this.renderLeftCell(row)} ${this.renderRightCell(row)} `;
  }

  private renderLeftCell(row: AlignedDiffRowWithThreads) {
    const isDeleted = row.status === 'deleted';
    const isModified = row.status === 'modified';
    const isEmpty = row.status === 'added' || !row.leftHtml;

    const classes = {
      'diff-cell': true,
      left: true,
      deleted: isDeleted,
      'modified-left': isModified,
      empty: isEmpty,
    };

    return html`
      <div
        class=${classMap(classes)}
        data-side="left"
        data-line=${ifDefined(row.leftStartLine)}
        @mouseenter=${() =>
          !isEmpty && this.handleCellMouseEnter(Side.LEFT, row.leftStartLine)}
        @mouseleave=${() => this.handleCellMouseLeave()}
      >
        ${when(!isEmpty, () =>
          this.renderCommentButton(Side.LEFT, row.leftStartLine)
        )}
        <div class="cell-content">
          ${when(!isEmpty, () => sanitizeHtmlToFragment(row.leftHtml!))}
        </div>
        ${when(
          row.leftThreads.length > 0,
          () => html`
            <div class="threads-container">
              ${row.leftThreads.map(t => this.renderThread(t, Side.LEFT))}
            </div>
          `
        )}
      </div>
    `;
  }

  private renderRightCell(row: AlignedDiffRowWithThreads) {
    const isAdded = row.status === 'added';
    const isModified = row.status === 'modified';
    const isEmpty = row.status === 'deleted' || !row.rightHtml;

    const classes = {
      'diff-cell': true,
      right: true,
      added: isAdded,
      'modified-right': isModified,
      empty: isEmpty,
    };

    return html`
      <div
        class=${classMap(classes)}
        data-side="right"
        data-line=${ifDefined(row.rightStartLine)}
        @mouseenter=${() =>
          !isEmpty && this.handleCellMouseEnter(Side.RIGHT, row.rightStartLine)}
        @mouseleave=${() => this.handleCellMouseLeave()}
      >
        ${when(!isEmpty, () =>
          this.renderCommentButton(Side.RIGHT, row.rightStartLine)
        )}
        <div class="cell-content">
          ${when(!isEmpty, () => sanitizeHtmlToFragment(row.rightHtml!))}
        </div>
        ${when(
          row.rightThreads.length > 0,
          () => html`
            <div class="threads-container">
              ${row.rightThreads.map(t => this.renderThread(t, Side.RIGHT))}
            </div>
          `
        )}
      </div>
    `;
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-diff-markdown-viewer': GrDiffMarkdownViewer;
  }
}
