import { Component, h, Host, Prop, Event, Watch, Method, State } from '@stencil/core';
import Tagify from '@yaireo/tagify';
import Filter from 'bad-words';
const filter = new Filter();
export class GdTagInput {
  constructor() {
    /**
     * Used for making form control required
     */
    this.required = false;
    /**
     * the internal tag state, for deciding if we should reinitialize tagify
     */
    this.currentTags = [];
  }
  componentDidLoad() {
    this.initializeTagify();
  }
  defaultValueChanged() {
    // TODO: this seems to bug out the tag input (causes an infinite change loop). Need to review so that tag input can actually reinitialize properly
    /*
    if (JSON.stringify(this.defaultValue) !== JSON.stringify(this.currentTags)) {
        // the application modified the tags, so lets reinitialize tagify
        this.initializeTagify()
    }
    */
  }
  initializeTagify() {
    // already have a tagify instance, reset it's tags
    if (this.tagify) {
      this.tagify.removeAllTags();
      this.tagify.addTags(this.defaultValue);
      this.currentTags = this.defaultValue;
      return;
    }
    this.tagify = new Tagify(this.inputEl, {
      transformTag: this.filterBadWords,
    });
    this.currentTags = this.defaultValue;
    // on change, trigger the tagsChange event
    this.tagify.on('change', e => {
      let tags = e.detail.value || '[]'; // default to no tags (tagify uses JSON, hence the empty string array)
      if (this.isJson(tags)) {
        tags = JSON.parse(tags);
      }
      else if (typeof tags === 'string') {
        tags = tags.split(',');
      }
      this.currentTags = tags.map(tag => tag.value || tag);
      this.tagsChange.emit(this.currentTags);
    });
  }
  async addTags(tags) {
    this.tagify && this.tagify.addTags(tags);
  }
  /**
   * renders the tag component
   */
  render() {
    return (h(Host, { class: {
        pills: this.variant == 'pills',
      } },
      h("input", { type: "text", name: this.name, id: this.controlId, size: this.htmlSize, "read-only": this.readOnly, disabled: this.disabled, value: this.defaultValue, placeholder: this.placeholder, required: this.required, ref: el => (this.inputEl = el) })));
  }
  filterBadWords(tag) {
    if (!filter.isProfane(tag.value)) {
      // tag isn't profane, just return
      return;
    }
    // no bad words! 🤬
    tag.value = filter.clean(tag.value);
  }
  isJson(item) {
    item = typeof item !== 'string' ? JSON.stringify(item) : item;
    try {
      item = JSON.parse(item);
    }
    catch (e) {
      return false;
    }
    if (typeof item === 'object' && item !== null) {
      return true;
    }
    return false;
  }
  static get is() { return "gd-tag-input"; }
  static get encapsulation() { return "shadow"; }
  static get originalStyleUrls() { return {
    "$": ["gd-tag-input.scss"]
  }; }
  static get styleUrls() { return {
    "$": ["gd-tag-input.css"]
  }; }
  static get properties() { return {
    "htmlSize": {
      "type": "number",
      "mutable": false,
      "complexType": {
        "original": "number",
        "resolved": "number",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Specifies how much of the input is shown."
      },
      "attribute": "html-size",
      "reflect": false
    },
    "variant": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "Variant",
        "resolved": "\"pills\"",
        "references": {
          "Variant": {
            "location": "local"
          }
        }
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "change the style of the tags"
      },
      "attribute": "variant",
      "reflect": false
    },
    "size": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "Size",
        "resolved": "\"lg\" | \"sm\"",
        "references": {
          "Size": {
            "location": "local"
          }
        }
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Used to change the size of inputs and labels respectively."
      },
      "attribute": "size",
      "reflect": false
    },
    "readOnly": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "The value of the input is not editable."
      },
      "attribute": "read-only",
      "reflect": false
    },
    "disabled": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Disables the input / select / textarea from edit or copy."
      },
      "attribute": "disabled",
      "reflect": false
    },
    "defaultValue": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "Tags",
        "resolved": "string | string[]",
        "references": {
          "Tags": {
            "location": "local"
          }
        }
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "The initial value of the input"
      },
      "attribute": "default-value",
      "reflect": false
    },
    "controlId": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "The element id"
      },
      "attribute": "control-id",
      "reflect": false
    },
    "name": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "The name applied to the input"
      },
      "attribute": "name",
      "reflect": false
    },
    "placeholder": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "The placeholder text for the input"
      },
      "attribute": "placeholder",
      "reflect": false
    },
    "required": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Used for making form control required"
      },
      "attribute": "required",
      "reflect": false,
      "defaultValue": "false"
    }
  }; }
  static get states() { return {
    "currentTags": {}
  }; }
  static get events() { return [{
      "method": "tagsChange",
      "name": "tagsChange",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": "The event is emitted when the tags change"
      },
      "complexType": {
        "original": "Tags",
        "resolved": "string | string[]",
        "references": {
          "Tags": {
            "location": "local"
          }
        }
      }
    }]; }
  static get methods() { return {
    "addTags": {
      "complexType": {
        "signature": "(tags: Tags) => Promise<void>",
        "parameters": [{
            "tags": [],
            "text": ""
          }],
        "references": {
          "Promise": {
            "location": "global"
          },
          "Tags": {
            "location": "local"
          }
        },
        "return": "Promise<void>"
      },
      "docs": {
        "text": "",
        "tags": []
      }
    }
  }; }
  static get watchers() { return [{
      "propName": "defaultValue",
      "methodName": "defaultValueChanged"
    }, {
      "propName": "placeholder",
      "methodName": "initializeTagify"
    }]; }
}
