/**
 * @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 {
  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 (typeof line !== 'number') 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>;
  }
}
