var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { MapToComponentField, MapToComponentMethod } from 'vega-slimmer/core';
import { getElementComputedStyle, isTextWrapped } from '../../../../utils/ui';
import { PageResizeObserverSlimmer } from '../../../../helpers/slimmers/page-resize-observer-slimmer';
/** The vega-text tooltip renderer slimmer */
export class VegaTextTooltipRenderer extends PageResizeObserverSlimmer {
  /**
   * The below method is e2e-test covered in
   * @see{module:vega-text-with-long-text-change-screen-size}
   * @see{module:vega-text-restore-on-enlarge-screen-size}
   */
  constructor() {
    /* eslint-disable jsdoc/require-jsdoc*/
    super({
      // Observe both the host (catches show/hide e.g. in vega-tab-group-panel, VD-8769)
      // and document.body (catches viewport resize after truncation collapses host width).
      // eslint-disable-next-line no-restricted-globals
      target: /* istanbul ignore next */ () => [this.host, document.body],
      callback: /* istanbul ignore next */ () => {
        if (this.overflow === 'ellipsis') {
          if (this.tooltipRef) {
            this.tooltipRef.innerText = this.content;
          }
          void this.handleTooltip();
        }
      },
      isDeferred: true,
    });
    /**
     * The below method is e2e-test covered in
     * @see{module:vega-text-with-long-text}
     * @see{module:vega-text-with-long-text-change-screen-size}
     */
    /* istanbul ignore next */
    this.handleTooltip = async () => {
      // Skip when host has no layout (e.g. hidden inside an inactive vega-tab-group-panel);
      // the observer will re-fire once the host becomes visible.
      if (this.host.clientWidth === 0) {
        return;
      }
      if (isTextWrapped(this.host)) {
        const tooltip = this.createTooltip();
        void tooltip.componentOnReady().then(() => {
          void this.updateTooltipDisplayText();
        });
      }
      else {
        if (this.tooltipRef && this.tooltipRef.classList.contains('hydrated')) {
          this.host.innerText = this.content;
          this.tooltipRef.remove();
          this.tooltipRef = null;
        }
        this.host.style.minWidth = 'auto';
      }
    };
    /**
     * The below method is e2e-test covered in
     * @see{module:vega-text-with-long-text}
     * @see{module:vega-text-with-long-text-change-screen-size}
     */
    /* istanbul ignore next */
    this.createTooltip = () => {
      var _a, _b, _c;
      this.tooltipRef = this.host.querySelector('vega-tooltip');
      if (!this.tooltipRef) {
        // eslint-disable-next-line no-restricted-globals
        this.tooltipRef = document.createElement('vega-tooltip');
        this.tooltipRef.text = this.content;
        this.tooltipRef.innerText = this.content;
        this.tooltipRef.placement = (_a = this.tooltip) === null || _a === void 0 ? void 0 : _a.placement;
        this.tooltipRef.maxWidth = (_b = this.tooltip) === null || _b === void 0 ? void 0 : _b.maxWidth;
        this.tooltipRef.minWidth = (_c = this.tooltip) === null || _c === void 0 ? void 0 : _c.minWidth;
        this.host.replaceChildren(this.tooltipRef);
      }
      return this.tooltipRef;
    };
    /** Calculate the number of displayed characters according to the screen width and font size.
     * In order to avoid errors, recalculate whether the vega-tooltip displays a line break.
     * If it has, gradually reduce the number of calculated characters until there is no line break.
     * If there is no newline yet, incrementally increase the counted number of characters until the newline.
     * The below method is e2e-test covered in
     * @see{module:vega-text-with-long-text}
     * @see{module:vega-text-with-long-text-change-screen-size}
     * @see{module:vega-text-with-long-text-minimize-screen-size}
     * @see{module:vega-text-with-long-text-minimize-screen-safari}
     */
    /* istanbul ignore next */
    this.updateTooltipDisplayText = async () => {
      let fontSize = parseFloat(getElementComputedStyle(this.host, 'font-size'));
      fontSize = isNaN(fontSize) ? VegaTextTooltipRenderer.DEFAULT_FONT_SIZE : fontSize;
      const textLength = Math.floor(this.host.getBoundingClientRect().width / Math.floor(fontSize / 2));
      if (isTextWrapped(this.tooltipRef)) {
        for (let i = textLength; i >= 1; i--) {
          this.tooltipRef.textContent = this.truncateStringWithEllipsis(i);
          if (!isTextWrapped(this.tooltipRef)) {
            break;
          }
          if (i <= 1) {
            // Set min-width to fix the safari wrap issue when the default width is already wrapped.
            this.insertMinWidthStyle();
            break;
          }
        }
      }
    };
    /**
     * The below method is e2e-test covered in
     * @see{module:vega-text-with-long-text}
     * @see{module:vega-text-with-long-text-change-screen-size}
     * @see{module:vega-text-with-long-text-minimize-screen-size}
     */
    /* istanbul ignore next */
    this.truncateStringWithEllipsis = (textLength) => {
      return this.content.substring(0, textLength) + '...';
    };
    this.initTextContent = () => {
      this.content = this.host.textContent;
    };
  }
  /**
   * Component lifecycle - [componentDidLoad]{@link VegaText.componentDidLoad}
   */
  componentDidLoad() {
    this.initTextContent();
  }
  /**
   * The below method is e2e-test covered in
   * @see{module:vega-text-with-tooltip-placement}
   */
  /* istanbul ignore next */
  /** Watching the tooltip prop. */
  watchTooltip() {
    var _a, _b, _c;
    if (this.tooltipRef) {
      this.tooltipRef.placement = (_a = this.tooltip) === null || _a === void 0 ? void 0 : _a.placement;
      this.tooltipRef.maxWidth = (_b = this.tooltip) === null || _b === void 0 ? void 0 : _b.maxWidth;
      this.tooltipRef.minWidth = (_c = this.tooltip) === null || _c === void 0 ? void 0 : _c.minWidth;
    }
  }
  /**
   * Dynamically calculates and sets the minimum width of an element based on the content inside a hidden placeholder element.
   * The below method is e2e-test covered in
   * @see{module:vega-text-with-long-text-minimize-screen-safari}
   */
  /* istanbul ignore next */
  insertMinWidthStyle() {
    let placeholder = this.host.shadowRoot.querySelector('#min-width-placeholder');
    if (!placeholder) {
      // eslint-disable-next-line no-restricted-globals
      placeholder = document.createElement('span');
      placeholder.id = 'min-width-placeholder';
      placeholder.style.cssText = 'position:absolute; visibility:hidden; word-break:keep-all;';
      this.host.shadowRoot.appendChild(placeholder);
    }
    placeholder.textContent = this.truncateStringWithEllipsis(1);
    this.host.style.minWidth = placeholder.getBoundingClientRect().width + 'px';
  }
}
VegaTextTooltipRenderer.DEFAULT_FONT_SIZE = 16;
__decorate([
  MapToComponentField()
], VegaTextTooltipRenderer.prototype, "host", void 0);
__decorate([
  MapToComponentField()
], VegaTextTooltipRenderer.prototype, "tooltip", void 0);
__decorate([
  MapToComponentField()
], VegaTextTooltipRenderer.prototype, "overflow", void 0);
__decorate([
  MapToComponentMethod('componentDidLoad')
], VegaTextTooltipRenderer.prototype, "componentDidLoad", null);
__decorate([
  MapToComponentMethod('watchTooltip')
], VegaTextTooltipRenderer.prototype, "watchTooltip", null);
