/**
 * @license
 * Copyright 2016 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '../../../styles/shared-styles';
import '../gr-selection-action-box/gr-selection-action-box';
import {GrAnnotation} from './gr-annotation';
import {normalize} from './gr-range-normalizer';
import {strToClassName} from '../../../utils/dom-util';
import {Side} from '../../../constants/constants';
import {CommentRange} from '../../../types/common';
import {GrSelectionActionBox} from '../gr-selection-action-box/gr-selection-action-box';
import {FILE} from '../gr-diff/gr-diff-line';
import {
  getLineElByChild,
  getLineNumberByChild,
  getSideByLineEl,
  GrDiffThreadElement,
} from '../gr-diff/gr-diff-utils';
import {debounce, DelayedTask} from '../../../utils/async-util';
import {assertIsDefined, queryAndAssert} from '../../../utils/common-util';
import {fire} from '../../../utils/event-util';

interface SidedRange {
  side: Side;
  range: CommentRange;
}

interface NormalizedPosition {
  node: Node | null;
  side: Side;
  line: number;
  column: number;
}

interface NormalizedRange {
  start: NormalizedPosition | null;
  end: NormalizedPosition | null;
}

/**
 * The methods that we actually want to call on the builder. We don't want a
 * fully blown dependency on GrDiffBuilderElement.
 */
export interface DiffBuilderInterface {
  getContentTdByLineEl(lineEl?: Element): Element | undefined;
}

/**
 * Handles showing, positioning and interacting with <gr-selection-action-box>.
 *
 * Toggles a css class for highlighting comment ranges when the mouse leaves or
 * enters a comment thread element.
 */
export class GrDiffHighlight {
  selectedRange?: SidedRange;

  private diffBuilder?: DiffBuilderInterface;

  private diffTable?: HTMLElement;

  private selectionChangeTask?: DelayedTask;

  init(diffTable: HTMLElement, diffBuilder: DiffBuilderInterface) {
    this.cleanup();

    this.diffTable = diffTable;
    this.diffBuilder = diffBuilder;

    diffTable.addEventListener(
      'comment-thread-mouseleave',
      this.handleCommentThreadMouseleave
    );
    diffTable.addEventListener(
      'comment-thread-mouseenter',
      this.handleCommentThreadMouseenter
    );
    diffTable.addEventListener(
      'create-comment-requested',
      this.handleRangeCommentRequest
    );
  }

  cleanup() {
    this.selectionChangeTask?.cancel();
    if (this.diffTable) {
      this.diffTable.removeEventListener(
        'comment-thread-mouseleave',
        this.handleCommentThreadMouseleave
      );
      this.diffTable.removeEventListener(
        'comment-thread-mouseenter',
        this.handleCommentThreadMouseenter
      );
      this.diffTable.removeEventListener(
        'create-comment-requested',
        this.handleRangeCommentRequest
      );
    }
  }

  /**
   * Determines side/line/range for a DOM selection and shows a tooltip.
   *
   * With native shadow DOM, gr-diff-highlight cannot access a selection that
   * references the DOM elements making up the diff because they are in the
   * shadow DOM the gr-diff element. For this reason, we listen to the
   * selectionchange event and retrieve the selection in gr-diff, and then
   * call this method to process the Selection.
   *
   * @param selection A DOM Selection living in the shadow DOM of
   * the diff element.
   * @param isMouseUp If true, this is called due to a mouseup
   * event, in which case we might want to immediately create a comment,
   * because isMouseUp === true combined with an existing selection must
   * mean that this is the end of a double-click.
   */
  handleSelectionChange(
    selection: Selection | Range | null,
    isMouseUp: boolean
  ) {
    if (selection === null) return;
    // Debounce is not just nice for waiting until the selection has settled,
    // it is also vital for being able to click on the action box before it is
    // removed.
    // If you wait longer than 50 ms, then you don't properly catch a very
    // quick 'c' press after the selection change. If you wait less than 10
    // ms, then you will have about 50 handleSelection() calls when doing a
    // simple drag for select.
    this.selectionChangeTask = debounce(
      this.selectionChangeTask,
      () => this.handleSelection(selection, isMouseUp),
      10
    );
  }

  private getThreadEl(e: Event): GrDiffThreadElement | null {
    for (const pathEl of e.composedPath()) {
      if (
        pathEl instanceof HTMLElement &&
        pathEl.classList.contains('comment-thread')
      ) {
        return pathEl as GrDiffThreadElement;
      }
    }
    return null;
  }

  private toggleRangeElHighlight(
    threadEl: GrDiffThreadElement | null,
    highlightRange = false
  ) {
    const rootId = threadEl?.rootId;
    if (!rootId) return;
    if (!this.diffTable) return;
    if (highlightRange) {
      const selector = `.range.${strToClassName(rootId)}`;
      const rangeNodes = this.diffTable.querySelectorAll(selector);
      rangeNodes.forEach(rangeNode => {
        rangeNode.classList.add('rangeHoverHighlight');
      });
      const hintNode = this.diffTable.querySelector(
        `gr-ranged-comment-hint[threadElRootId="${rootId}"]`
      );
      hintNode?.shadowRoot
        ?.querySelectorAll('.rangeHighlight')
        .forEach(highlightNode =>
          highlightNode.classList.add('rangeHoverHighlight')
        );
    } else {
      const selector = `.rangeHoverHighlight.${strToClassName(rootId)}`;
      const rangeNodes = this.diffTable.querySelectorAll(selector);
      rangeNodes.forEach(rangeNode => {
        rangeNode.classList.remove('rangeHoverHighlight');
      });
      const hintNode = this.diffTable.querySelector(
        `gr-ranged-comment-hint[threadElRootId="${rootId}"]`
      );
      hintNode?.shadowRoot
        ?.querySelectorAll('.rangeHoverHighlight')
        .forEach(highlightNode =>
          highlightNode.classList.remove('rangeHoverHighlight')
        );
    }
  }

  private handleCommentThreadMouseenter = (e: Event) => {
    const threadEl = this.getThreadEl(e);
    this.toggleRangeElHighlight(threadEl, /* highlightRange= */ true);
  };

  private handleCommentThreadMouseleave = (e: Event) => {
    const threadEl = this.getThreadEl(e);
    this.toggleRangeElHighlight(threadEl, /* highlightRange= */ false);
  };

  /**
   * Get current normalized selection.
   * Merges multiple ranges, accounts for triple click, accounts for
   * syntax highligh, convert native DOM Range objects to Gerrit concepts
   * (line, side, etc).
   */
  private getNormalizedRange(selection: Selection | Range) {
    /* On Safari the ShadowRoot.getSelection() isn't there and the only thing
       we can get is a single Range */
    if (selection instanceof Range) {
      return this.normalizeRange(selection);
    }
    const rangeCount = selection.rangeCount;
    if (rangeCount === 0) {
      return null;
    } else if (rangeCount === 1) {
      return this.normalizeRange(selection.getRangeAt(0));
    } else {
      const startRange = this.normalizeRange(selection.getRangeAt(0));
      const endRange = this.normalizeRange(
        selection.getRangeAt(rangeCount - 1)
      );
      return {
        start: startRange.start,
        end: endRange.end,
      };
    }
  }

  /**
   * Normalize a specific DOM Range.
   *
   * @return fixed normalized range
   */
  private normalizeRange(domRange: Range): NormalizedRange {
    const range = normalize(domRange);
    return this.fixTripleClickSelection(
      {
        start: this.normalizeSelectionSide(
          range.startContainer,
          range.startOffset
        ),
        end: this.normalizeSelectionSide(range.endContainer, range.endOffset),
      },
      domRange
    );
  }

  /**
   * Adjust triple click selection for the whole line.
   * A triple click always results in:
   * - start.column == end.column == 0
   * - end.line == start.line + 1
   *
   * @param range Normalized range, ie column/line numbers
   * @param domRange DOM Range object
   * @return fixed normalized range
   */
  private fixTripleClickSelection(range: NormalizedRange, domRange: Range) {
    if (!range.start) {
      // Selection outside of current diff.
      return range;
    }
    const start = range.start;
    const end = range.end;
    // Happens when triple click in side-by-side mode with other side empty.
    const endsAtOtherEmptySide =
      !end &&
      domRange.endOffset === 0 &&
      domRange.endContainer instanceof HTMLElement &&
      domRange.endContainer.nodeName === 'TD' &&
      (domRange.endContainer.classList.contains('left') ||
        domRange.endContainer.classList.contains('right'));
    const endsAtBeginningOfNextLine =
      end &&
      start.column === 0 &&
      end.column === 0 &&
      end.line === start.line + 1;
    const content = domRange.cloneContents().querySelector('.contentText');
    const lineLength = (content && this.getLength(content)) || 0;
    if (lineLength && (endsAtBeginningOfNextLine || endsAtOtherEmptySide)) {
      // Move the selection to the end of the previous line.
      range.end = {
        node: start.node,
        column: lineLength,
        side: start.side,
        line: start.line,
      };
    }
    return range;
  }

  /**
   * Convert DOM Range selection to concrete numbers (line, column, side).
   * Moves range end if it's not inside td.content.
   * Returns null if selection end is not valid (outside of diff).
   *
   * @param node td.content child
   * @param offset offset within node
   */
  private normalizeSelectionSide(
    node: Node | null,
    offset: number
  ): NormalizedPosition | null {
    let column;
    if (!this.diffTable) return null;
    if (!this.diffBuilder) return null;
    if (!node || !this.diffTable.contains(node)) return null;
    const lineEl = getLineElByChild(node);
    if (!lineEl) return null;
    const side = getSideByLineEl(lineEl);
    if (!side) return null;
    const line = getLineNumberByChild(lineEl);
    if (!line || line === FILE || line === 'LOST') return null;
    const contentTd = this.diffBuilder.getContentTdByLineEl(lineEl);
    if (!contentTd) return null;
    const contentText = contentTd.querySelector('.contentText');
    if (!contentTd.contains(node)) {
      node = contentText;
      column = 0;
    } else {
      const thread = contentTd.querySelector('.comment-thread');
      if (thread?.contains(node)) {
        column = this.getLength(contentText);
        node = contentText;
      } else {
        column = this.convertOffsetToColumn(node, offset);
      }
    }

    return {
      node,
      side,
      line,
      column,
    };
  }

  /**
   * The only line in which add a comment tooltip is cut off is the first
   * line. Even if there is a collapsed section, The first visible line is
   * in the position where the second line would have been, if not for the
   * collapsed section, so don't need to worry about this case for
   * positioning the tooltip.
   */
  // visible for testing
  positionActionBox(
    actionBox: GrSelectionActionBox,
    startLine: number,
    range: Text | Element | Range
  ) {
    if (startLine > 1) {
      actionBox.positionBelow = false;
      actionBox.placeAbove(range);
      return;
    }
    actionBox.positionBelow = true;
    actionBox.placeBelow(range);
  }

  private isRangeValid(range: NormalizedRange | null) {
    if (!range || !range.start || !range.start.node || !range.end) {
      return false;
    }
    const start = range.start;
    const end = range.end;
    return !(
      start.side !== end.side ||
      end.line < start.line ||
      (start.line === end.line && start.column === end.column)
    );
  }

  // visible for testing
  handleSelection(selection: Selection | Range, isMouseUp: boolean) {
    /* On Safari, the selection events may return a null range that should
       be ignored */
    if (!selection) return;
    if (!this.diffTable) return;

    const normalizedRange = this.getNormalizedRange(selection);
    if (!this.isRangeValid(normalizedRange)) {
      this.removeActionBox();
      return;
    }
    /* On Safari the ShadowRoot.getSelection() isn't there and the only thing
       we can get is a single Range */
    const domRange =
      selection instanceof Range ? selection : selection.getRangeAt(0);
    const start = normalizedRange!.start!;
    const end = normalizedRange!.end!;

    // TODO (viktard): Drop empty first and last lines from selection.

    // If the selection is from the end of one line to the start of the next
    // line, then this must have been a double-click, or you have started
    // dragging. Showing the action box is bad in the former case and not very
    // useful in the latter, so never do that.
    // If this was a mouse-up event, we create a comment immediately if
    // the selection is from the end of a line to the start of the next line.
    // In a perfect world we would only do this for double-click, but it is
    // extremely rare that a user would drag from the end of one line to the
    // start of the next and release the mouse, so we don't bother.
    // TODO(brohlfs): This does not work, if the double-click is before a new
    // diff chunk (start will be equal to end), and neither before an "expand
    // the diff context" block (end line will match the first line of the new
    // section and thus be greater than start line + 1).
    if (start.line === end.line - 1 && end.column === 0) {
      // Rather than trying to find the line contents (for comparing
      // start.column with the content length), we just check if the selection
      // is empty to see that it's at the end of a line.
      const content = domRange.cloneContents().querySelector('.contentText');
      if (isMouseUp && this.getLength(content) === 0) {
        this.fireCreateRangeComment(start.side, {
          start_line: start.line,
          start_character: 0,
          end_line: start.line,
          end_character: start.column,
        });
      }
      return;
    }

    let actionBox = this.diffTable.querySelector('gr-selection-action-box');
    if (!actionBox) {
      actionBox = document.createElement('gr-selection-action-box');
      this.diffTable.appendChild(actionBox);
    }
    this.selectedRange = {
      range: {
        start_line: start.line,
        start_character: start.column,
        end_line: end.line,
        end_character: end.column,
      },
      side: start.side,
    };
    if (start.line === end.line) {
      this.positionActionBox(actionBox, start.line, domRange);
    } else if (start.node instanceof Text) {
      if (start.column) {
        this.positionActionBox(
          actionBox,
          start.line,
          start.node.splitText(start.column)
        );
      }
      start.node.parentElement!.normalize(); // Undo splitText from above.
    } else if (
      start.node instanceof HTMLElement &&
      start.node.classList.contains('content') &&
      (start.node.firstChild instanceof Element ||
        start.node.firstChild instanceof Text)
    ) {
      this.positionActionBox(actionBox, start.line, start.node.firstChild);
    } else if (start.node instanceof Element || start.node instanceof Text) {
      this.positionActionBox(actionBox, start.line, start.node);
    } else {
      console.warn('Failed to position comment action box.');
      this.removeActionBox();
    }
  }

  private fireCreateRangeComment(side: Side, range: CommentRange) {
    if (this.diffTable) {
      fire(this.diffTable, 'create-range-comment', {side, range});
    }
    this.removeActionBox();
  }

  private handleRangeCommentRequest = (e: Event) => {
    e.stopPropagation();
    assertIsDefined(this.selectedRange, 'selectedRange');
    const {side, range} = this.selectedRange;
    this.fireCreateRangeComment(side, range);
  };

  // visible for testing
  removeActionBox() {
    this.selectedRange = undefined;
    const actionBox = this.diffTable?.querySelector('gr-selection-action-box');
    if (actionBox) actionBox.remove();
  }

  private convertOffsetToColumn(el: Node, offset: number) {
    if (el instanceof Element && el.classList.contains('content')) {
      return offset;
    }
    while (
      el.previousSibling ||
      !el.parentElement?.classList.contains('content')
    ) {
      if (el.previousSibling) {
        el = el.previousSibling;
        offset += this.getLength(el);
      } else {
        el = el.parentElement!;
      }
    }
    return offset;
  }

  /**
   * Get length of a node. If the node is a content node, then only give the
   * length of its .contentText child.
   *
   * @param node this is sometimes passed as null.
   */
  // visible for testing
  getLength(node: Node | null): number {
    if (node === null) return 0;
    if (node instanceof Element && node.classList.contains('content')) {
      return this.getLength(queryAndAssert(node, '.contentText'));
    } else {
      return GrAnnotation.getLength(node);
    }
  }
}

export interface CreateRangeCommentEventDetail {
  side: Side;
  range: CommentRange;
}

declare global {
  interface HTMLElementEventMap {
    'create-range-comment': CustomEvent<CreateRangeCommentEventDetail>;
  }
}
