/**
 * @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 {getLength} 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 {fire} from '../../../utils/event-util';
import {GrSelectionActionBox} from '../gr-selection-action-box/gr-selection-action-box';
import {
  getLineElByChild,
  getLineNumberByChild,
  getSideByLineEl,
  GrDiffCommentThread,
} from '../gr-diff/gr-diff-utils';
import {debounce, DelayedTask} from '../../../utils/async-util';
import {assertIsDefined, queryAndAssert} from '../../../utils/common-util';
import {DiffModel} from '../gr-diff-model/gr-diff-model';

declare global {
  interface HTMLElementEventMap {
    /** Fired when the action box is removed. */
    'selection-action-box-removed': CustomEvent<{}>;
  }
}

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;
  diffModel: DiffModel;
}

/**
 * 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 toggleRangeElHighlight(
    thread: GrDiffCommentThread,
    highlightRange = false
  ) {
    const rootId = thread?.rootId;
    if (!rootId) return;
    if (!this.diffTable) return;
    const highlightClass = highlightRange ? 'range' : 'rangeHoverHighlight';
    const selector = `.${highlightClass}.${strToClassName(rootId)}`;
    const rangeNodes = this.diffTable.querySelectorAll(selector);
    for (const rangeNode of rangeNodes) {
      rangeNode.classList.toggle('rangeHoverHighlight', highlightRange);
    }
  }

  private handleCommentThreadMouseenter = (
    e: CustomEvent<GrDiffCommentThread>
  ) => {
    this.toggleRangeElHighlight(e.detail, /* highlightRange= */ true);
  };

  private handleCommentThreadMouseleave = (
    e: CustomEvent<GrDiffCommentThread>
  ) => {
    this.toggleRangeElHighlight(e.detail, /* 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.createRangeComment(start.side, {
          start_line: start.line,
          start_character: 0,
          end_line: start.line,
          end_character: start.column,
        });
      }
      return;
    }

    const range = {
      start_line: start.line,
      start_character: start.column,
      end_line: end.line,
      end_character: end.column,
    };
    const side = start.side;
    this.selectedRange = {range, side};
    this.diffBuilder?.diffModel.fireRangeSelectedEvent(side, range, isMouseUp);
    let actionBox = this.diffTable.querySelector('gr-selection-action-box');
    if (!actionBox) {
      actionBox = document.createElement('gr-selection-action-box');
      this.diffTable.appendChild(actionBox);
    }
    const hoverCardText =
      this.diffBuilder?.diffModel.getState().actionHoverCardText;
    if (hoverCardText) {
      actionBox.setAttribute('hoverCardText', hoverCardText);
    }
    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 createRangeComment(side: Side, range: CommentRange) {
    assertIsDefined(this.diffBuilder, 'diffBuilder');
    this.diffBuilder?.diffModel.createCommentOnRange(range, side);
    this.removeActionBox();
  }

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

  // visible for testing
  removeActionBox() {
    this.selectedRange = undefined;
    const actionBox = this.diffTable?.querySelector(
      'gr-selection-action-box'
    ) as GrSelectionActionBox | null;
    if (actionBox) {
      fire(actionBox, 'selection-action-box-removed', {});
      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 getLength(node);
    }
  }
}
