/**
 * @license
 * Copyright 2016 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '../../../elements/shared/gr-tooltip/gr-tooltip';
import {GrTooltip} from '../../../elements/shared/gr-tooltip/gr-tooltip';
import {fire} from '../../../utils/event-util';
import {html, LitElement} from 'lit';
import {customElement, property, query, state} from 'lit/decorators.js';
import {Side} from '../../../api/diff';
import {CommentRange} from '../../../api/rest-api';

export interface SelectionContext {
  path?: string;
  side?: Side;
  range?: CommentRange;
  text?: string;
}

export interface SelectionActionBoxVisibleEventDetail {
  getSelectionContext?: () => Promise<SelectionContext>;
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-selection-action-box': GrSelectionActionBox;
  }
  interface HTMLElementEventMap {
    /** Fired when the comment creation action was taken (click). */
    'create-comment-requested': CustomEvent<{}>;

    /** Fired when the selection action box is visible. */
    'selection-action-box-visible': CustomEvent<SelectionActionBoxVisibleEventDetail>;
  }
}

@customElement('gr-selection-action-box')
export class GrSelectionActionBox extends LitElement {
  @query('#tooltip')
  tooltip?: GrTooltip;

  @state() private isSlotAssigned = false;

  @query('slot') slotElement!: HTMLSlotElement;

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

  @property({type: String})
  hoverCardText = 'Press c to comment';

  @property({type: Object})
  getSelectionContext?: () => Promise<SelectionContext>;

  /**
   * We need to absolutely position the element before we can show it. So
   * initially the tooltip must be invisible.
   */
  @state() private invisible = true;

  constructor() {
    super();
    // See https://crbug.com/gerrit/4767
    this.addEventListener('mousedown', e => this.handleMouseDown(e));
  }

  override render() {
    // We create the gr-tooltip anyway even if the slot is assigned so that
    // we reuse the logic for positioning the tooltip (in placeAbove/Below).
    return html`
      <slot
        name="selectionActionBox"
        ?invisible=${this.invisible}
        @slotchange=${this.handleSlotChange}
      >
        <gr-tooltip
          id="tooltip"
          text=${this.hoverCardText}
          ?position-below=${this.positionBelow}
        ></gr-tooltip>
      </slot>
    `;
  }

  private handleSlotChange() {
    const assignedNodes = this.slotElement.assignedNodes({flatten: true});
    this.isSlotAssigned = assignedNodes.length > 0;
  }

  /**
   * The browser API for handling selection does not (yet) work for selection
   * across multiple shadow DOM elements. So we are rendering gr-diff components
   * into the light DOM instead of the shadow DOM by overriding this method,
   * which was the recommended workaround by the lit team.
   * See also https://github.com/WICG/webcomponents/issues/79.
   */
  override createRenderRoot() {
    return this;
  }

  // TODO(b/315277651): This is very similar in purpose to gr-tooltip-content.
  //   We should figure out a way to reuse as much of the logic as possible.
  async placeAbove(el: Text | Element | Range) {
    await this.updateComplete;
    if (!this.tooltip) return;
    await this.tooltip.updateComplete;
    const rect = this.getTargetBoundingRect(el);
    const boxRect = this.tooltip.getBoundingClientRect();
    const parentRect = this.getParentBoundingClientRect();
    if (parentRect === null) {
      return;
    }
    this.style.top = `${rect.top - parentRect.top - boxRect.height - 6}px`;
    this.style.left = `${
      rect.left - parentRect.left + (rect.width - boxRect.width) / 2
    }px`;
    this.invisible = false;
    fire(this, 'selection-action-box-visible', {
      getSelectionContext: this.getSelectionContext,
    });
  }

  async placeBelow(el: Text | Element | Range) {
    await this.updateComplete;
    if (!this.tooltip) return;
    await this.tooltip.updateComplete;
    const rect = this.getTargetBoundingRect(el);
    const boxRect = this.tooltip.getBoundingClientRect();
    const parentRect = this.getParentBoundingClientRect();
    if (parentRect === null) {
      return;
    }
    this.style.top = `${rect.top - parentRect.top + boxRect.height - 6}px`;
    this.style.left = `${
      rect.left - parentRect.left + (rect.width - boxRect.width) / 2
    }px`;
    this.invisible = false;
    fire(this, 'selection-action-box-visible', {
      getSelectionContext: this.getSelectionContext,
    });
  }

  private getParentBoundingClientRect() {
    // With native shadow DOM, the parent is the shadow root, not the gr-diff
    // element
    if (this.parentElement) {
      return this.parentElement.getBoundingClientRect();
    }
    if (this.parentNode !== null) {
      return (this.parentNode as ShadowRoot).host.getBoundingClientRect();
    }
    return null;
  }

  // visible for testing
  getTargetBoundingRect(el: Text | Element | Range) {
    let rect;
    if (el instanceof Text) {
      const range = document.createRange();
      range.selectNode(el);
      rect = range.getBoundingClientRect();
      range.detach();
    } else {
      rect = el.getBoundingClientRect();
    }
    return rect;
  }

  // visible for testing
  handleMouseDown(e: MouseEvent) {
    if (this.isSlotAssigned) {
      return;
    }
    if (e.button !== 0) {
      return;
    } // 0 = main button
    e.preventDefault();
    e.stopPropagation();
    fire(this, 'create-comment-requested', {});
  }
}
