import { Component, Watch, h, Prop, State, Event } from '@stencil/core';
import { getIconLibrary } from './library';
import { requestIcon } from './request';
const parser = new DOMParser();
export class ScIcon {
  constructor() {
    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 is() { return "sc-icon"; }
  static get encapsulation() { return "shadow"; }
  static get originalStyleUrls() { return {
    "$": ["sc-icon.css"]
  }; }
  static get styleUrls() { return {
    "$": ["sc-icon.css"]
  }; }
  static get assetsDirs() { return ["icon-assets"]; }
  static get properties() { return {
    "name": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "The name of the icon to draw."
      },
      "attribute": "name",
      "reflect": true
    },
    "src": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "An external URL of an SVG file."
      },
      "attribute": "src",
      "reflect": false
    },
    "label": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "An alternative description to use for accessibility. If omitted, the name or src will be used to generate it."
      },
      "attribute": "label",
      "reflect": false
    },
    "library": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "The name of a registered custom icon library."
      },
      "attribute": "library",
      "reflect": false,
      "defaultValue": "'default'"
    }
  }; }
  static get states() { return {
    "svg": {}
  }; }
  static get events() { return [{
      "method": "scLoad",
      "name": "scLoad",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": "Emitted when the icon has loaded."
      },
      "complexType": {
        "original": "void",
        "resolved": "void",
        "references": {}
      }
    }, {
      "method": "scError",
      "name": "scError",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": "Emitted when the icon failed to load."
      },
      "complexType": {
        "original": "{ status: number }",
        "resolved": "{ status: number; }",
        "references": {}
      }
    }]; }
  static get watchers() { return [{
      "propName": "name",
      "methodName": "setIcon"
    }, {
      "propName": "src",
      "methodName": "setIcon"
    }, {
      "propName": "library",
      "methodName": "setIcon"
    }]; }
}
