import { arrow, autoUpdate, computePosition, flip, offset, shift } from "@floating-ui/dom";
import { ElementIDUtils } from "@sankhyalabs/core";
import { h, Host } from "@stencil/core";
export class EzTooltip {
  constructor() {
    this._opened = false;
    this._eventsRegistered = false;
    this.message = undefined;
    this.anchoringElement = undefined;
    this.placement = 'bottom';
    this.gapOptions = { horizontalGap: 0, verticalGap: 0 };
    this.type = 'default';
    this.debouncingTime = 500;
    this.active = true;
    this.maxWidth = 200;
    this.useAnchorSize = false;
    this.strategy = 'absolute';
  }
  watchAnchoringElement(newValue, oldValue) {
    if (newValue) {
      this.setEvents(newValue);
      this.removeEvents(oldValue);
    }
  }
  watchMessage(newValue) {
    if (!newValue) {
      this.closeTooltip();
      return;
    }
    this.updatePosition();
  }
  openTooltip() {
    if (this.message && this.active) {
      if (this._debouncingTimeout) {
        clearTimeout(this._debouncingTimeout);
      }
      this._debouncingTimeout = setTimeout(() => {
        this._opened = true;
        this._tooltipElement.style.display = 'block';
        this.updatePosition();
      }, this.debouncingTime);
    }
  }
  closeTooltip() {
    clearTimeout(this._debouncingTimeout);
    this._tooltipElement.style.display = 'none';
    this._opened = false;
  }
  async updatePosition(element = this.anchoringElement) {
    if (!element || !this._opened) {
      return;
    }
    if (this.useAnchorSize) {
      const anchorSize = element.getBoundingClientRect().width;
      this._tooltipElement.style.width = `${anchorSize}px`;
    }
    if (this._cleanup) {
      this._cleanup();
    }
    this._cleanup = autoUpdate(element, this._tooltipElement, () => {
      computePosition(element, this._tooltipElement, {
        placement: this.placement,
        strategy: this.strategy,
        middleware: [
          offset(5),
          flip(),
          shift({ padding: 8 }),
          arrow({ element: this._arrowElement })
        ],
      }).then(({ x, y, placement, middlewareData }) => {
        const newTop = placement.includes("bottom") ? y + this.gapOptions.verticalGap : y - this.gapOptions.verticalGap;
        const newLeft = placement.includes("start") ? x + this.gapOptions.horizontalGap : x - this.gapOptions.horizontalGap;
        Object.assign(this._tooltipElement.style, {
          top: `${newTop}px`,
          left: `${newLeft}px`,
        });
        if (middlewareData.arrow) {
          const { x } = middlewareData.arrow;
          const onBottom = placement.includes("bottom");
          Object.assign(this._arrowElement.style, {
            left: `${x}px`,
            top: onBottom ? `${-this._arrowElement.offsetHeight / 2}px` : '',
            bottom: !onBottom ? `${-this._arrowElement.offsetHeight / 2}px` : '',
          });
        }
      });
    });
  }
  handleSlotChange(ev) {
    const slot = ev.target;
    const content = slot.assignedElements()[0];
    this.anchoringElement = content;
  }
  setEvents(element = this.anchoringElement) {
    if (!element) {
      return;
    }
    this.removeEvents(element);
    this._mouseEnterHandler = () => this.openTooltip();
    this._mouseLeaveHandler = () => this.closeTooltip();
    element.addEventListener('mouseenter', this._mouseEnterHandler);
    element.addEventListener('mouseleave', this._mouseLeaveHandler);
    this._eventsRegistered = true;
  }
  removeEvents(element = this.anchoringElement) {
    if (!element) {
      return;
    }
    if (this._mouseEnterHandler) {
      element.removeEventListener('mouseenter', this._mouseEnterHandler);
    }
    if (this._mouseLeaveHandler) {
      element.removeEventListener('mouseleave', this._mouseLeaveHandler);
    }
    this._eventsRegistered = false;
  }
  initializeTooltip() {
    if (this._element && this.anchoringElement && !this._eventsRegistered) {
      this.setEvents();
      this.addInfoId();
    }
  }
  connectedCallback() {
    this.initializeTooltip();
  }
  componentDidLoad() {
    this.initializeTooltip();
  }
  addInfoId() {
    if (this._element) {
      ElementIDUtils.addIDInfo(this._element);
    }
  }
  disconnectedCallback() {
    this.removeEvents();
    if (this._cleanup) {
      this._cleanup();
    }
    clearTimeout(this._debouncingTimeout);
  }
  render() {
    return (h(Host, null, h("div", Object.assign({ ref: ref => this._tooltipElement = ref }, { inert: true }, { class: "tooltip", "data-type": this.type, "data-active": this.active.toString(), "data-strategy": this.strategy, style: {
        maxWidth: (this.maxWidth && !this.useAnchorSize) ? `${this.maxWidth}px` : undefined,
      }, role: "tooltip", "data-element-id": ElementIDUtils.getInternalIDInfo("tooltip") }), this.message, h("div", { ref: ref => this._arrowElement = ref, class: "arrow" })), h("slot", { onSlotchange: (ev) => { this.handleSlotChange(ev); } })));
  }
  static get is() { return "ez-tooltip"; }
  static get encapsulation() { return "shadow"; }
  static get originalStyleUrls() {
    return {
      "$": ["ez-tooltip.css"]
    };
  }
  static get styleUrls() {
    return {
      "$": ["ez-tooltip.css"]
    };
  }
  static get properties() {
    return {
      "message": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Mensagem que ser\u00E1 apresentada no tooltip."
        },
        "attribute": "message",
        "reflect": false
      },
      "anchoringElement": {
        "type": "unknown",
        "mutable": true,
        "complexType": {
          "original": "HTMLElement",
          "resolved": "HTMLElement",
          "references": {
            "HTMLElement": {
              "location": "global"
            }
          }
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Elemento HTML que ser\u00E1 utilizado como ancoragem do tooltip."
        }
      },
      "placement": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "Placement",
          "resolved": "\"bottom\" | \"bottom-end\" | \"bottom-start\" | \"left\" | \"left-end\" | \"left-start\" | \"right\" | \"right-end\" | \"right-start\" | \"top\" | \"top-end\" | \"top-start\"",
          "references": {
            "Placement": {
              "location": "import",
              "path": "@floating-ui/dom"
            }
          }
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Define a posi\u00E7\u00E3o do tooltip em rela\u00E7\u00E3o ao elemento de ancoragem."
        },
        "attribute": "placement",
        "reflect": false,
        "defaultValue": "'bottom'"
      },
      "gapOptions": {
        "type": "unknown",
        "mutable": false,
        "complexType": {
          "original": "{ horizontalGap: number; verticalGap: number; }",
          "resolved": "{ horizontalGap: number; verticalGap: number; }",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Define o espa\u00E7amento entre o tooltip e o elemento de ancoragem."
        },
        "defaultValue": "{ horizontalGap: 0, verticalGap: 0 }"
      },
      "type": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "'default' | 'success' | 'error' | 'warning'",
          "resolved": "\"default\" | \"error\" | \"success\" | \"warning\"",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Define o tipo de tooltip a ser exibido."
        },
        "attribute": "type",
        "reflect": false,
        "defaultValue": "'default'"
      },
      "debouncingTime": {
        "type": "number",
        "mutable": false,
        "complexType": {
          "original": "number",
          "resolved": "number",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Tempo de espera para exibir o tooltip ap\u00F3s o evento de mouseenter."
        },
        "attribute": "debouncing-time",
        "reflect": false,
        "defaultValue": "500"
      },
      "active": {
        "type": "boolean",
        "mutable": false,
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Define se o tooltip est\u00E1 ativo."
        },
        "attribute": "active",
        "reflect": false,
        "defaultValue": "true"
      },
      "maxWidth": {
        "type": "number",
        "mutable": false,
        "complexType": {
          "original": "number",
          "resolved": "number",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Define a largura m\u00E1xima do elemento."
        },
        "attribute": "max-width",
        "reflect": false,
        "defaultValue": "200"
      },
      "useAnchorSize": {
        "type": "boolean",
        "mutable": false,
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Define se o elemento manter\u00E1 o mesmo tamanho do componente de ancora."
        },
        "attribute": "use-anchor-size",
        "reflect": false,
        "defaultValue": "false"
      },
      "strategy": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "'absolute' | 'fixed'",
          "resolved": "\"absolute\" | \"fixed\"",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Define a estrat\u00E9gia de posicionamento do tooltip.\nUse 'fixed' quando o elemento estiver dentro de containers com position: relative."
        },
        "attribute": "strategy",
        "reflect": false,
        "defaultValue": "'absolute'"
      }
    };
  }
  static get elementRef() { return "_element"; }
  static get watchers() {
    return [{
        "propName": "anchoringElement",
        "methodName": "watchAnchoringElement"
      }, {
        "propName": "message",
        "methodName": "watchMessage"
      }];
  }
}
