import { proxyCustomElement, HTMLElement, createEvent, h } from '@stencil/core/internal/client';

let registry = [];
let watchedIcons = [];
function getIconLibrary(name) {
  return registry.filter(lib => lib.name === name)[0];
}
function registerIconLibrary(name, options) {
  unregisterIconLibrary(name);
  registry.push({
    name,
    resolver: options.resolver,
    mutator: options.mutator,
  });
  // Redraw watched icons
  watchedIcons.map(icon => {
    if (icon.library === name) {
      icon.redraw();
    }
  });
}
function unregisterIconLibrary(name) {
  registry = registry.filter(lib => lib.name !== name);
}
window.ceRegisterIconLibrary = registerIconLibrary;

const iconFiles = new Map();
const requestIcon = (url) => {
  if (iconFiles.has(url)) {
    return iconFiles.get(url);
  }
  else {
    const request = fetch(url).then(async (response) => {
      if (response.ok) {
        const div = document.createElement('div');
        div.innerHTML = await response.text();
        const svg = div.firstElementChild;
        return {
          ok: response.ok,
          status: response.status,
          svg: svg && svg.tagName.toLowerCase() === 'svg' ? svg.outerHTML : '',
        };
      }
      else {
        return {
          ok: response.ok,
          status: response.status,
          svg: null,
        };
      }
    });
    iconFiles.set(url, request);
    return request;
  }
};

const scIconCss = ":host{--width:1em;--height:1em;display:inline-block;width:var(--width);height:var(--height);contain:strict;box-sizing:content-box !important}.icon,svg{display:block;height:100%;width:100%}";

const parser = new DOMParser();
const ScIcon = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
  constructor() {
    super();
    this.__registerHost();
    this.__attachShadow();
    this.scLoad = createEvent(this, "scLoad", 7);
    this.scError = createEvent(this, "scError", 7);
    this.svg = '';
    /** The name of a registered custom icon library. */
    this.library = 'default';
  }
  /** @internal Fetches the icon and redraws it. Used to handle library registrations. */
  redraw() {
    this.setIcon();
  }
  componentWillLoad() {
    this.setIcon();
  }
  getLabel() {
    let label = '';
    if (this.label) {
      label = this.label;
    }
    else if (this.name) {
      label = this.name.replace(/-/g, ' ');
    }
    else if (this.src) {
      label = this.src.replace(/.*\//, '').replace(/-/g, ' ').replace(/\.svg/i, '');
    }
    return label;
  }
  async setIcon() {
    const library = getIconLibrary(this.library);
    const url = this.getUrl();
    if (url) {
      try {
        const file = await requestIcon(url);
        if (url !== this.getUrl()) {
          // If the url has changed while fetching the icon, ignore this request
          return;
        }
        else if (file.ok) {
          const doc = parser.parseFromString(file.svg, 'text/html');
          const svgEl = doc.body.querySelector('svg');
          if (svgEl) {
            if (library && library.mutator) {
              library.mutator(svgEl);
            }
            this.svg = svgEl.outerHTML;
            this.scLoad.emit();
          }
          else {
            this.svg = '';
            this.scError.emit({ status: file.status });
          }
        }
        else {
          this.svg = '';
          this.scError.emit({ status: file.status });
        }
      }
      catch {
        this.scError.emit({ status: -1 });
      }
    }
    else if (this.svg) {
      // If we can't resolve a URL and an icon was previously set, remove it
      this.svg = '';
    }
  }
  getUrl() {
    const library = getIconLibrary(this.library);
    if (this.name && library) {
      return library.resolver(this.name);
    }
    else {
      return this.src;
    }
  }
  render() {
    return h("div", { part: "base", class: "icon", role: "img", "aria-label": this.getLabel(), innerHTML: this.svg });
  }
  static get assetsDirs() { return ["icon-assets"]; }
  static get watchers() { return {
    "name": ["setIcon"],
    "src": ["setIcon"],
    "library": ["setIcon"]
  }; }
  static get style() { return scIconCss; }
}, [1, "sc-icon", {
    "name": [513],
    "src": [1],
    "label": [1],
    "library": [1],
    "svg": [32]
  }]);
function defineCustomElement() {
  if (typeof customElements === "undefined") {
    return;
  }
  const components = ["sc-icon"];
  components.forEach(tagName => { switch (tagName) {
    case "sc-icon":
      if (!customElements.get(tagName)) {
        customElements.define(tagName, ScIcon);
      }
      break;
  } });
}
defineCustomElement();

export { ScIcon as S, defineCustomElement as d, registerIconLibrary as r };
