/**
 * @license
 * Copyright 2017 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '../gr-icon/gr-icon';
import '../gr-tooltip/gr-tooltip';
import {GrTooltip} from '../gr-tooltip/gr-tooltip';
import {css, html, LitElement, PropertyValues} from 'lit';
import {customElement, property, state} from 'lit/decorators.js';

const ARROW_HEIGHT = 7.2; // Height of the arrow in tooltip.

declare global {
  interface HTMLElementTagNameMap {
    'gr-tooltip-content': GrTooltipContent;
  }
}

@customElement('gr-tooltip-content')
export class GrTooltipContent extends LitElement {
  @property({type: Boolean, attribute: 'has-tooltip', reflect: true})
  hasTooltip = false;

  // A light tooltip will disappear immediately when the original hovered
  // over content is no longer hovered over.
  @property({type: Boolean, attribute: 'light-tooltip', reflect: true})
  lightTooltip = false;

  @property({type: Boolean, attribute: 'position-below', reflect: true})
  positionBelow = false;

  @property({type: String, attribute: 'max-width', reflect: true})
  maxWidth?: string;

  @property({type: Boolean, attribute: 'show-icon'})
  showIcon = false;

  // Should be private but used in tests.
  @state()
  isTouchDevice = 'ontouchstart' in document.documentElement;

  // Should be private but used in tests.
  tooltip: GrTooltip | null = null;

  @state()
  private originalTitle = '';

  private hasSetupTooltipListeners = false;

  private readonly windowScrollHandler: () => void;

  private readonly showHandler: () => void;

  private readonly hideHandler: (e: Event) => void;

  // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
  constructor() {
    super();
    this.windowScrollHandler = () => this._handleWindowScroll();
    this.showHandler = () => this._handleShowTooltip();
    this.hideHandler = (e: Event | undefined) => this._handleHideTooltip(e);
  }

  override disconnectedCallback() {
    this._handleHideTooltip(undefined);
    this.removeEventListener('mouseenter', this.showHandler);
    window.removeEventListener('scroll', this.windowScrollHandler);
    super.disconnectedCallback();
  }

  static override get styles() {
    return [
      css`
        gr-icon {
          font-size: var(--line-height-normal);
        }
      `,
    ];
  }

  override render() {
    return html`
      <slot></slot>
      ${this.renderIcon()}
    `;
  }

  renderIcon() {
    if (!this.showIcon) return;
    return html`<gr-icon icon="info" filled></gr-icon>`;
  }

  override updated(changedProperties: PropertyValues) {
    if (changedProperties.has('hasTooltip')) {
      this.setupTooltipListeners();
    }
  }

  private setupTooltipListeners() {
    if (!this.hasTooltip) {
      if (this.hasSetupTooltipListeners) {
        // if attribute set to false, remove the listener
        this.removeEventListener('mouseenter', this.showHandler);
        this.hasSetupTooltipListeners = false;
      }
      return;
    }

    if (this.hasSetupTooltipListeners) {
      return;
    }
    this.hasSetupTooltipListeners = true;
    this.addEventListener('mouseenter', this.showHandler);
  }

  async _handleShowTooltip() {
    if (this.isTouchDevice) {
      return;
    }

    if (
      !this.hasAttribute('title') ||
      this.getAttribute('title') === '' ||
      this.tooltip
    ) {
      return;
    }

    // Store the title attribute text then set it to an empty string to
    // prevent it from showing natively.
    this.originalTitle = this.getAttribute('title') || '';
    this.setAttribute('title', '');

    const tooltip = document.createElement('gr-tooltip');
    tooltip.text = this.originalTitle;
    tooltip.maxWidth = this.getAttribute('max-width') || '';
    tooltip.positionBelow = this.hasAttribute('position-below');
    this.tooltip = tooltip;

    // Set visibility to hidden before appending to the DOM so that
    // calculations can be made based on the element’s size.
    tooltip.style.visibility = 'hidden';
    const parent = this.getTooltipParent(this);
    parent.appendChild(tooltip);
    await tooltip.updateComplete;
    this._positionTooltip(tooltip);
    tooltip.style.visibility = 'initial';

    window.addEventListener('scroll', this.windowScrollHandler);
    this.addEventListener('mouseleave', this.hideHandler);
    this.addEventListener('click', this.hideHandler);
    if (!this.lightTooltip) {
      tooltip.addEventListener('mouseleave', this.hideHandler);
    }
  }

  getTooltipParent(el: Node): Node {
    if (el === document.body) {
      return el;
    }
    if (el instanceof HTMLDialogElement) {
      return el;
    }
    if (el instanceof ShadowRoot) {
      return this.getTooltipParent(el.host);
    }
    if (el.parentNode) {
      return this.getTooltipParent(el.parentNode);
    }
    return document.body;
  }

  _handleHideTooltip(e?: Event) {
    if (this.isTouchDevice) {
      return;
    }
    if (!this.hasAttribute('title') || !this.originalTitle) {
      return;
    }
    // Do not hide if mouse left this or this.tooltip and came to this or
    // this.tooltip
    if (
      (!this.lightTooltip &&
        (e as MouseEvent)?.relatedTarget === this.tooltip) ||
      (e as MouseEvent)?.relatedTarget === this
    ) {
      return;
    }

    window.removeEventListener('scroll', this.windowScrollHandler);
    this.removeEventListener('mouseleave', this.hideHandler);
    this.removeEventListener('click', this.hideHandler);
    this.setAttribute('title', this.originalTitle);
    if (!this.lightTooltip) {
      this.tooltip?.removeEventListener('mouseleave', this.hideHandler);
    }

    if (this.tooltip?.parentNode) {
      this.tooltip.parentNode.removeChild(this.tooltip);
    }
    this.tooltip = null;
  }

  _handleWindowScroll() {
    if (!this.tooltip) {
      return;
    }
    // This wait is needed for tooltips to be positioned correctly in Firefox
    // and Safari.
    this.updateComplete.then(() => this._positionTooltip(this.tooltip));
  }

  // private but used in tests.
  _positionTooltip(tooltip: GrTooltip | null) {
    if (tooltip === null) return;
    const hoveredRect = this.getBoundingClientRect();
    const tooltipRect = tooltip.getBoundingClientRect();
    if (!tooltip.parentElement) {
      return;
    }
    const parentRect = tooltip.parentElement.getBoundingClientRect();
    // Use clientWidth to not include the scrollbars
    const parentWidth = tooltip.parentElement.clientWidth;

    const hoveredCenter =
      0.5 * (hoveredRect.left + hoveredRect.right) - parentRect.left;
    const left = this.computeLeft(tooltipRect, hoveredCenter, parentWidth);
    const {isBelow, top} = this.computeTop(
      tooltipRect,
      hoveredRect,
      parentRect
    );
    const tooltipCenter = left + 0.5 * tooltipRect.width;

    tooltip.arrowCenterOffset = `${hoveredCenter - tooltipCenter}px`;
    tooltip.positionBelow = isBelow;
    tooltip.style.top = `${top}px`;
    tooltip.style.left = `${left}px`;
  }

  private computeLeft(
    tooltipRect: DOMRect,
    hoveredCenter: number,
    parentWidth: number
  ) {
    let left = hoveredCenter - 0.5 * tooltipRect.width;
    if (left + tooltipRect.width > parentWidth - 1) {
      // Add 1px of extra padding. Without it on some browser zoom levels
      // the hovercard is still considered going out of bounds and gets
      // reshaped.
      left = parentWidth - tooltipRect.width - 1;
    }
    return Math.max(0, left);
  }

  private computeTop(
    tooltipRect: DOMRect,
    hoveredRect: DOMRect,
    parentRect: DOMRect
  ): {
    isBelow: boolean;
    top: number;
  } {
    const top =
      hoveredRect.top - parentRect.top - tooltipRect.height - ARROW_HEIGHT;
    if (this.positionBelow || top < 0) {
      return {
        isBelow: true,
        top: hoveredRect.bottom - parentRect.top + ARROW_HEIGHT,
      };
    }
    return {isBelow: false, top};
  }
}
