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 { Component, Host, Prop, h, Element, Watch } from '@stencil/core';
import { getIconFromToken, Icons } from '../../constants/tokens/icons';
import { Spacing } from '../../constants/tokens/spacing';
import { sanitizeVegaComponent } from '../../utils/component';
import { formatAndValidTextColor } from '../../utils/design-token';
import { arrayToClassString } from '../../utils/ui';
import { VegaIconManager } from '../../helpers/icon/icon-manager';
import { InjectVegaGlobalSlimmer, InjectVegaSlimmer } from 'vega-slimmer/core';
import { LogUtility } from '../../utils/log';
import { VegaComponentUsageRuntimeMetricsSlimmer } from '../../helpers/slimmers/component-usage-runtime-metrics';
import { tryGetDocument } from '../../utils/try-get-document';
import { htmlSanitizer, styleSanitizeStrategy } from '../../utils/sanitize';
/**
 * @vegaVersion 1.0.4
 */
export class VegaIcon {
  constructor() {
    this.globalSlimmers = {};
    this.vegaComponentUsageRuntimeMetricsSlimmer = new VegaComponentUsageRuntimeMetricsSlimmer();
    /**
     * Specifies the width and height of the icon.
     *    For Third Party Icons (e.g., Font Awesome),
     *    it sets the icon's font-size.
     *
     * @vegaVersion 1.0.4
     */
    this.size = 'size-16';
    /**
     * The below method is e2e-test covered in
     * @see {module:console-warn-when-load-fa-lib-timeout}
     */
    /* istanbul ignore next */
    this.cloneFAIconStyles = () => {
      if (this.isThirdPartyIcon(this.icon)) {
        const iconStyleHTML = this.getIconStyleHTML();
        if (iconStyleHTML) {
          this.appendStyles(iconStyleHTML);
        }
        let count = 0;
        const timerId = window.setInterval(() => {
          if (count < 10) {
            count++;
            const iconStyleHTML = this.getIconStyleHTML();
            if (iconStyleHTML) {
              this.appendStyles(iconStyleHTML);
              clearInterval(timerId);
              return;
            }
          }
          else {
            LogUtility.warn('[Vega] Loading Font Awesome timeout.', this.icon);
            clearInterval(timerId);
            return;
          }
        }, 300);
      }
    };
  }
  /**
   * The below method is e2e-test covered in
   * @see {module:icon-changed-from-vega-icon-to-fa-icon-class}
   */
  /* istanbul ignore next */
  watchIcon() {
    this.cloneFAIconStyles();
  }
  componentWillLoad() {
    this.cloneFAIconStyles();
  }
  render() {
    const iconFromTokenIndex = Icons.findIndex((icon) => {
      return icon === this.icon;
    });
    if (VegaIconManager.hasIcon(this.icon)) {
      const { icon, autoSize } = VegaIconManager.getIcon(this.icon);
      const iconSize = autoSize ? null : this.size;
      return this.renderForVegaIconToken(icon, iconSize, autoSize);
    }
    else if (iconFromTokenIndex > -1) {
      return this.renderForVegaIconToken(getIconFromToken(this.icon), this.size);
    }
    else {
      /**
       * The below method is e2e-test covered in
       * @see {module:render-correct-size-with-fa-icon}
       * @see {module:append-fa-icon-styles-to-shadow-dom}
       */
      /* istanbul ignore next */
      return this.renderForThirdPartyIcon();
    }
  }
  /**
   * Verify whether the icon is FA icon or not
   *
   * @param {string} icon - the icon name
   * @returns {boolean} - return true if the icon is FA icon
   */
  isThirdPartyIcon(icon) {
    return !VegaIconManager.hasIcon(icon) && !Icons.find((item) => item === icon);
  }
  renderForVegaIconToken(icon, size, isAutoSize = false) {
    const sizeClassName = size ? this.formatAndValidSize(this.size) : null;
    return sanitizeVegaComponent(h(Host, { class: arrayToClassString([
        sizeClassName,
        this.color && formatAndValidTextColor(this.color),
        isAutoSize && 'vega-auto-size',
      ]), innerHTML: icon },
      h("slot", null)), this.host);
  }
  /**
   * The below method is e2e-test covered in
   * @see {module:render-correct-size-with-fa-icon}
   * @see {module:append-fa-icon-styles-to-shadow-dom}
   */
  /* istanbul ignore next */
  renderForThirdPartyIcon() {
    return sanitizeVegaComponent(h(Host, { class: arrayToClassString([this.color && formatAndValidTextColor(this.color)]), style: this.formatThirdPartyIconSize(this.size) },
      h("i", { part: "icon", class: this.icon })), this.host);
  }
  formatAndValidSize(size) {
    return `v-w-${size} v-h-${size}`;
  }
  /**
   * The below method is e2e-test covered in
   * @see {module:render-correct-size-with-fa-icon}
   */
  /* istanbul ignore next */
  formatThirdPartyIconSize(size) {
    return { 'font-size': `${Spacing[size]}px` };
  }
  /**
   * The below method is e2e-test covered in
   * @see {module:append-fa-icon-styles-to-shadow-dom}
   */
  /* istanbul ignore next */
  appendStyles(iconStyles) {
    var _a;
    if (iconStyles && tryGetDocument()) {
      const styleElement = (_a = this.host.shadowRoot.querySelector('#fa-icon-styles')) !== null && _a !== void 0 ? _a : tryGetDocument().createElement('style');
      styleElement.id = 'fa-icon-styles';
      styleElement.innerHTML = htmlSanitizer.sanitize(iconStyles, styleSanitizeStrategy);
      this.host.shadowRoot.appendChild(styleElement);
    }
  }
  /**
   * The below method is e2e-test covered in
   * @see {module:append-fa-icon-styles-to-shadow-dom}
   */
  /* istanbul ignore next */
  getIconStyleHTML() {
    var _a;
    if (VegaIcon.iconStyleCache.has(this.icon)) {
      return VegaIcon.iconStyleCache.get(this.icon);
    }
    else {
      if (tryGetDocument()) {
        const iconElement = tryGetDocument().createElement('i');
        iconElement.className = this.icon;
        iconElement.style.display = 'none';
        tryGetDocument().body.appendChild(iconElement);
        const computedStyle = getComputedStyle(iconElement);
        // `fontFamily` is null in spec test. Skip it by using '?'
        if ((_a = computedStyle.fontFamily) === null || _a === void 0 ? void 0 : _a.includes('Font Awesome')) {
          const pseudoBeforeElementStyle = getComputedStyle(iconElement, '::before');
          const pseudoAfterElementStyle = getComputedStyle(iconElement, '::after');
          const styleHTML = `
				i {
					font-weight: ${computedStyle.fontWeight};
					font-family: ${computedStyle.fontFamily};
					font-style: ${computedStyle.fontStyle};
					position: ${computedStyle.position};
					letter-spacing: ${computedStyle.letterSpacing};
				}
				i::before {
					content: ${pseudoBeforeElementStyle.content};
					position: ${pseudoBeforeElementStyle.position};
					opacity: ${pseudoBeforeElementStyle.opacity};
				}
				i::after {
					content: ${pseudoAfterElementStyle.content};
					position: ${pseudoAfterElementStyle.position};
					opacity: ${pseudoAfterElementStyle.opacity};
				}
			`.replace(/[\n\t]/gi, '');
          VegaIcon.iconStyleCache.set(this.icon, styleHTML);
          tryGetDocument().body.removeChild(iconElement);
          return styleHTML;
        }
        else {
          tryGetDocument().body.removeChild(iconElement);
          return null;
        }
      }
    }
  }
  static get is() { return "vega-icon"; }
  static get encapsulation() { return "shadow"; }
  static get originalStyleUrls() { return {
    "$": ["vega-icon.scss"]
  }; }
  static get styleUrls() { return {
    "$": ["vega-icon.css"]
  }; }
  static get properties() { return {
    "icon": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [{
            "name": "vegaVersion",
            "text": "1.0.4"
          }],
        "text": "Specifies the required icon design token for the icon."
      },
      "attribute": "icon",
      "reflect": true
    },
    "size": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "SpacingTokenType",
        "resolved": "\"0\" | \"size-112\" | \"size-12\" | \"size-16\" | \"size-2\" | \"size-20\" | \"size-24\" | \"size-32\" | \"size-4\" | \"size-40\" | \"size-48\" | \"size-64\" | \"size-72\" | \"size-8\" | \"size-80\"",
        "references": {
          "SpacingTokenType": {
            "location": "import",
            "path": "../../types/design-token.type"
          }
        }
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [{
            "name": "vegaVersion",
            "text": "1.0.4"
          }],
        "text": "Specifies the width and height of the icon.\n   For Third Party Icons (e.g., Font Awesome),\n   it sets the icon's font-size."
      },
      "attribute": "size",
      "reflect": false,
      "defaultValue": "'size-16'"
    },
    "color": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "TextColorsTokenType",
        "resolved": "\"text-primary\" | \"text-secondary\" | \"text-inverted-primary\" | \"text-inverted-secondary\" | \"text-black\" | \"text-white\" | \"text-brand\" | \"text-danger-link\" | \"text-danger-link-hover\" | \"text-danger-link-active\" | \"text-danger-link-focus\" | \"text-danger-link-visited\" | \"text-disabled\" | \"text-error\" | \"text-input-disabled\" | \"text-input-placeholder\" | \"text-link\" | \"text-link-hover\" | \"text-link-active\" | \"text-link-focus\" | \"text-link-visited\" | \"text-on-action\" | \"text-on-danger\" | \"text-on-disabled\" | \"text-sidebar-link\" | \"text-sidebar-link-hover\" | \"text-sidebar-link-selected\" | \"text-site-footer-link\" | \"text-site-footer-link-hover\" | \"text-site-footer-link-active\" | \"text-success\" | \"text-inverted-success\" | \"text-accent1-primary\" | \"text-accent2-primary\" | \"text-accent3-primary\" | \"text-accent4-primary\" | \"text-accent5-primary\" | \"text-accent6-primary\" | \"text-accent7-primary\" | \"text-accent8-primary\" | \"text-accent9-primary\" | \"text-accent10-primary\"",
        "references": {
          "TextColorsTokenType": {
            "location": "import",
            "path": "../../types/design-token.type"
          }
        }
      },
      "required": false,
      "optional": true,
      "docs": {
        "tags": [{
            "name": "vegaVersion",
            "text": "1.26.0"
          }],
        "text": "Specifies the color of the icon.\n\nIf the color prop is `undefined`, it defaults to `currentColor`."
      },
      "attribute": "color",
      "reflect": false
    }
  }; }
  static get elementRef() { return "host"; }
  static get watchers() { return [{
      "propName": "icon",
      "methodName": "watchIcon"
    }]; }
}
VegaIcon.iconStyleCache = new Map();
__decorate([
  InjectVegaGlobalSlimmer()
], VegaIcon.prototype, "globalSlimmers", void 0);
__decorate([
  InjectVegaSlimmer()
], VegaIcon.prototype, "vegaComponentUsageRuntimeMetricsSlimmer", void 0);
