/**
 * @license
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import '../../../scripts/bundled-polymer.js';

import '../../../styles/shared-styles.js';
import '../../../scripts/rootElement.js';
import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';

const HOVER_CLASS = 'hovered';

/**
 * When the hovercard is positioned diagonally (bottom-left, bottom-right,
 * top-left, or top-right), we add additional (invisible) padding so that the
 * area that a user can hover over to access the hovercard is larger.
 */
const DIAGONAL_OVERFLOW = 15;

/**
 * How long should be wait before showing the hovercard when the user hovers
 * over the element?
 */
const SHOW_DELAY_MS = 500;

/**
 * The mixin for gr-hovercard-behavior.
 *
 * @example
 *
 * // LegacyElementMixin is still needed to support the old lifecycles
 * // TODO: Replace old life cycles with new ones.
 *
 * class YourComponent extends hovercardBehaviorMixin(
 *  LegacyElementMixin(PolymerElement)
 * ) {
 *   static get is() { return ''; }
 *   static get template() { return html``; }
 * }
 *
 * customElements.define(GrHovercard.is, GrHovercard);
 *
 * @see gr-hovercard.js
 *
 * // following annotations are required for polylint
 * @polymer
 * @mixinFunction
 */
export const hovercardBehaviorMixin = superClass => class extends superClass {
  static get properties() {
    return {
      /**
       * @type {?}
       */
      _target: Object,

      /**
       * Determines whether or not the hovercard is visible.
       *
       * @type {boolean}
       */
      _isShowing: {
        type: Boolean,
        value: false,
      },
      /**
       * The `id` of the element that the hovercard is anchored to.
       *
       * @type {string}
       */
      for: {
        type: String,
        observer: '_forChanged',
      },

      /**
       * The spacing between the top of the hovercard and the element it is
       * anchored to.
       *
       * @type {number}
       */
      offset: {
        type: Number,
        value: 14,
      },

      /**
       * Positions the hovercard to the top, right, bottom, left, bottom-left,
       * bottom-right, top-left, or top-right of its content.
       *
       * @type {string}
       */
      position: {
        type: String,
        value: 'right',
      },

      container: Object,
      /**
       * ID for the container element.
       *
       * @type {string}
       */
      containerId: {
        type: String,
        value: 'gr-hovercard-container',
      },
    };
  }

  /** @override */
  attached() {
    super.attached();
    if (!this._target) { this._target = this.target; }
    this.listen(this._target, 'mouseenter', 'showDelayed');
    this.listen(this._target, 'focus', 'showDelayed');
    this.listen(this._target, 'mouseleave', 'hide');
    this.listen(this._target, 'blur', 'hide');
    this.listen(this._target, 'click', 'hide');
  }

  /** @override */
  created() {
    super.created();
    this.addEventListener('mouseleave',
        e => this.hide(e));
  }

  /** @override */
  ready() {
    super.ready();
    // First, check to see if the container has already been created.
    this.container = Gerrit.getRootElement()
        .querySelector('#' + this.containerId);

    if (this.container) { return; }

    // If it does not exist, create and initialize the hovercard container.
    this.container = document.createElement('div');
    this.container.setAttribute('id', this.containerId);
    Gerrit.getRootElement().appendChild(this.container);
  }

  removeListeners() {
    this.unlisten(this._target, 'mouseenter', 'show');
    this.unlisten(this._target, 'focus', 'show');
    this.unlisten(this._target, 'mouseleave', 'hide');
    this.unlisten(this._target, 'blur', 'hide');
    this.unlisten(this._target, 'click', 'hide');
  }

  /**
   * Returns the target element that the hovercard is anchored to (the `id` of
   * the `for` property).
   *
   * @type {HTMLElement}
   */
  get target() {
    const parentNode = dom(this).parentNode;
    // If the parentNode is a document fragment, then we need to use the host.
    const ownerRoot = dom(this).getOwnerRoot();
    let target;
    if (this.for) {
      target = dom(ownerRoot).querySelector('#' + this.for);
    } else {
      target = parentNode.nodeType == Node.DOCUMENT_FRAGMENT_NODE ?
        ownerRoot.host :
        parentNode;
    }
    return target;
  }

  /**
   * Hides/closes the hovercard. This occurs when the user triggers the
   * `mouseleave` event on the hovercard's `target` element (as long as the
   * user is not hovering over the hovercard).
   *
   * @param {Event} e DOM Event (e.g. `mouseleave` event)
   */
  hide(e) {
    this._isScheduledToShow = false;
    if (!this._isShowing) {
      return;
    }

    // If the user is now hovering over the hovercard or the user is returning
    // from the hovercard but now hovering over the target (to stop an annoying
    // flicker effect), just return.
    if (e.toElement === this ||
        (e.fromElement === this && e.toElement === this._target)) {
      return;
    }

    // Mark that the hovercard is not visible and do not allow focusing
    this._isShowing = false;

    // Clear styles in preparation for the next time we need to show the card
    this.classList.remove(HOVER_CLASS);

    // Reset and remove the hovercard from the DOM
    this.style.cssText = '';
    this.$.container.setAttribute('tabindex', -1);

    // Remove the hovercard from the container, given that it is still a child
    // of the container.
    if (this.container.contains(this)) {
      this.container.removeChild(this);
    }
  }

  /**
   * Shows/opens the hovercard with a fixed delay.
   */
  showDelayed() {
    this.showDelayedBy(SHOW_DELAY_MS);
  }

  /**
   * Shows/opens the hovercard with the given delay.
   */
  showDelayedBy(delayMs) {
    if (this._isShowing || this._isScheduledToShow) return;
    this._isScheduledToShow = true;
    setTimeout(() => {
      // This happens when the mouse leaves the target before the delay is over.
      if (!this._isScheduledToShow) return;
      this._isScheduledToShow = false;
      this.show();
    }, delayMs);
  }

  /**
   * Shows/opens the hovercard. This occurs when the user triggers the
   * `mousenter` event on the hovercard's `target` element.
   */
  show() {
    if (this._isShowing) {
      return;
    }

    // Mark that the hovercard is now visible
    this._isShowing = true;
    this.setAttribute('tabindex', 0);

    // Add it to the DOM and calculate its position
    this.container.appendChild(this);
    this.updatePosition();

    // Trigger the transition
    this.classList.add(HOVER_CLASS);
  }

  /**
   * Updates the hovercard's position based on the `position` attribute
   * and the current position of the `target` element.
   *
   * The hovercard is supposed to stay open if the user hovers over it.
   * To keep it open when the user moves away from the target, the bounding
   * rects of the target and hovercard must touch or overlap.
   *
   * NOTE: You do not need to directly call this method unless you need to
   * update the position of the tooltip while it is already visible (the
   * target element has moved and the tooltip is still open).
   */
  updatePosition() {
    if (!this._target) { return; }

    // Calculate the necessary measurements and positions
    const parentRect = document.documentElement.getBoundingClientRect();
    const targetRect = this._target.getBoundingClientRect();
    const thisRect = this.getBoundingClientRect();

    const targetLeft = targetRect.left - parentRect.left;
    const targetTop = targetRect.top - parentRect.top;

    let hovercardLeft;
    let hovercardTop;
    const diagonalPadding = this.offset + DIAGONAL_OVERFLOW;
    let cssText = '';

    // Find the top and left position values based on the position attribute
    // of the hovercard.
    switch (this.position) {
      case 'top':
        hovercardLeft = targetLeft + (targetRect.width - thisRect.width) / 2;
        hovercardTop = targetTop - thisRect.height - this.offset;
        cssText += `padding-bottom:${this.offset
        }px; margin-bottom:-${this.offset}px;`;
        break;
      case 'bottom':
        hovercardLeft = targetLeft + (targetRect.width - thisRect.width) / 2;
        hovercardTop = targetTop + targetRect.height + this.offset;
        cssText +=
            `padding-top:${this.offset}px; margin-top:-${this.offset}px;`;
        break;
      case 'left':
        hovercardLeft = targetLeft - thisRect.width - this.offset;
        hovercardTop = targetTop + (targetRect.height - thisRect.height) / 2;
        cssText +=
            `padding-right:${this.offset}px; margin-right:-${this.offset}px;`;
        break;
      case 'right':
        hovercardLeft = targetRect.right + this.offset;
        hovercardTop = targetTop + (targetRect.height - thisRect.height) / 2;
        cssText +=
            `padding-left:${this.offset}px; margin-left:-${this.offset}px;`;
        break;
      case 'bottom-right':
        hovercardLeft = targetRect.left + targetRect.width + this.offset;
        hovercardTop = targetRect.top + targetRect.height + this.offset;
        cssText += `padding-top:${diagonalPadding}px;`;
        cssText += `padding-left:${diagonalPadding}px;`;
        cssText += `margin-left:-${diagonalPadding}px;`;
        cssText += `margin-top:-${diagonalPadding}px;`;
        break;
      case 'bottom-left':
        hovercardLeft = targetRect.left - thisRect.width - this.offset;
        hovercardTop = targetRect.top + targetRect.height + this.offset;
        cssText += `padding-top:${diagonalPadding}px;`;
        cssText += `padding-right:${diagonalPadding}px;`;
        cssText += `margin-right:-${diagonalPadding}px;`;
        cssText += `margin-top:-${diagonalPadding}px;`;
        break;
      case 'top-left':
        hovercardLeft = targetRect.left - thisRect.width - this.offset;
        hovercardTop = targetRect.top - thisRect.height - this.offset;
        cssText += `padding-bottom:${diagonalPadding}px;`;
        cssText += `padding-right:${diagonalPadding}px;`;
        cssText += `margin-bottom:-${diagonalPadding}px;`;
        cssText += `margin-right:-${diagonalPadding}px;`;
        break;
      case 'top-right':
        hovercardLeft = targetRect.left + targetRect.width + this.offset;
        hovercardTop = targetRect.top - thisRect.height - this.offset;
        cssText += `padding-bottom:${diagonalPadding}px;`;
        cssText += `padding-left:${diagonalPadding}px;`;
        cssText += `margin-bottom:-${diagonalPadding}px;`;
        cssText += `margin-left:-${diagonalPadding}px;`;
        break;
    }

    // Prevent hovercard from appearing outside the viewport.
    // TODO(kaspern): fix hovercard appearing outside viewport on bottom and
    // right.
    if (hovercardLeft < 0) { hovercardLeft = 0; }
    if (hovercardTop < 0) { hovercardTop = 0; }
    // Set the hovercard's position
    cssText += `left:${hovercardLeft}px; top:${hovercardTop}px;`;
    this.style.cssText = cssText;
  }

  /**
   * Responds to a change in the `for` value and gets the updated `target`
   * element for the hovercard.
   *
   * @private
   */
  _forChanged() {
    this._target = this.target;
  }
};
