import _defineProperty from "@babel/runtime/helpers/defineProperty";
import { createPopper } from '@popperjs/core';
import { bind } from 'bind-event-listener';
const startingOffset = {
  name: 'offset',
  options: {
    offset: [0, 4]
  }
};
const endingOffset = {
  name: 'offset',
  options: {
    offset: [0, 8]
  }
};

/**
 * A tooltip component similar to "@atlaskit/tooltip" but built for vanilla scenarios
 *
 * Uses Popover API for accessibility + stacking context: https://developer.mozilla.org/en-US/docs/Web/API/Popover_API
 * Uses popperJS for positioning
 */
export class VanillaTooltip {
  constructor(button, content,
  /**
   * Id associated to the tooltip - must be unique.
   */
  id,
  /**
   * Class Name – used for styling.
   */
  className, timeout = 300) {
    _defineProperty(this, "listeners", []);
    _defineProperty(this, "shouldHidePopover", false);
    _defineProperty(this, "isDisplayed", false);
    this.button = button;
    this.timeout = timeout;
    const tooltip = document.createElement('span');
    tooltip.role = 'tooltip';
    tooltip.popover = 'hint';
    tooltip.className = className;
    tooltip.id = id;
    tooltip.textContent = content;
    this.tooltip = tooltip;

    // Button preparation
    button.appendChild(tooltip);
    // Prepare the button to have the popover target and accessibility properties
    button.setAttribute('popovertarget', tooltip.id);
    button.setAttribute('aria-describedby', tooltip.id);
    const showEvents = ['mouseenter', 'focus'];
    const hideEvents = ['mouseleave', 'blur'];
    showEvents.forEach(event => {
      this.listeners.push(bind(button, {
        type: event,
        listener: () => this.show()
      }));
    });
    hideEvents.forEach(event => {
      this.listeners.push(bind(button, {
        type: event,
        listener: () => this.hide()
      }));
    });
    this.listeners.push(bind(window, {
      type: 'keydown',
      listener: e => {
        if (e.key === 'Escape') {
          this.hide(true);
        }
      }
    }));

    // Hide the tooltip if the hide transition has completed
    this.tooltip.ontransitionend = () => {
      if (this.shouldHidePopover) {
        this.tooltip.hidePopover();
      }
    };
  }
  createPopperInstance() {
    this.popperInstance = createPopper(this.button, this.tooltip, {
      placement: 'top',
      modifiers: [startingOffset]
    });
  }
  destroy() {
    var _this$popperInstance;
    (_this$popperInstance = this.popperInstance) === null || _this$popperInstance === void 0 ? void 0 : _this$popperInstance.destroy();
    this.listeners.forEach(listener => {
      listener();
    });
  }
  hide(immediate = false) {
    clearTimeout(this.currentTimeoutId);
    this.shouldHidePopover = true;
    // Disable the event listeners
    this.currentTimeoutId = setTimeout(() => {
      var _this$popperInstance2;
      (_this$popperInstance2 = this.popperInstance) === null || _this$popperInstance2 === void 0 ? void 0 : _this$popperInstance2.setOptions(options => ({
        ...options,
        modifiers: [startingOffset, {
          name: 'eventListeners',
          enabled: false
        }]
      }));
      this.tooltip.style.opacity = '0';
      this.isDisplayed = false;
      // If transition animations are disabled immediately hide the popover
      if (this.tooltip.style.transition === 'none') {
        this.tooltip.hidePopover();
      }
    }, immediate ? 0 : this.timeout);
  }
  show() {
    if (this.isDisplayed) {
      return;
    }
    clearTimeout(this.currentTimeoutId);
    this.shouldHidePopover = false;

    // Make the tooltip visible - but hide until
    this.tooltip.style.visibility = 'hidden';
    this.tooltip.showPopover();

    // Update its position
    if (!this.popperInstance) {
      this.createPopperInstance();
    } else {
      this.popperInstance.update();
    }

    // Enable the event listeners
    this.currentTimeoutId = setTimeout(() => {
      var _this$popperInstance3;
      this.tooltip.style.opacity = '1';
      this.tooltip.style.visibility = 'visible';
      (_this$popperInstance3 = this.popperInstance) === null || _this$popperInstance3 === void 0 ? void 0 : _this$popperInstance3.setOptions(options => ({
        ...options,
        modifiers: [endingOffset, {
          name: 'eventListeners',
          enabled: true
        }]
      }));
      this.isDisplayed = true;
    }, this.timeout);
  }
}