import { ElementIDUtils, KeyboardManager } from '@sankhyalabs/core';
import { h, Host } from '@stencil/core';
export class EzTagInput {
  constructor() {
    this.handleInputChange = (event) => {
      const target = event.target;
      this._inputElement.value = target.value;
      this.ezType.emit(this._inputElement.value);
    };
    this.handleInputKeyDown = (event) => {
      if (event.key === 'Backspace' && this._inputElement.value === '' && this.tags.length > 0 && !this.suppressBackspaceToRemove) {
        this.handleRemoveTag(this.tags[this.tags.length - 1]);
      }
    };
    this.handleInputFocus = () => {
      this.ezFocus.emit(this.tags);
    };
    this.handleInputBlur = () => {
      this.ezBlur.emit(this.tags);
    };
    this.handleTagClick = (tag, index) => {
      if (this.enabled && !this.readonly) {
        this.handleRemoveTag(tag);
        this.updateTagFocus(index);
      }
    };
    this.handleClearInput = () => {
      this._inputElement.value = '';
    };
    this.label = '';
    this.placeholder = '';
    this.helpText = undefined;
    this.enabled = true;
    this.readonly = false;
    this.name = undefined;
    this.tags = [];
    this.maxTagLength = undefined;
    this.maxTags = undefined;
    this.allowDuplicates = false;
    this.state = "default";
    this.validator = undefined;
    this.suppressTagsKeyboardNavigation = false;
    this.suppressBackspaceToRemove = false;
  }
  /** Aplica o foco no campo */
  async setFocus(option) {
    if (option === null || option === void 0 ? void 0 : option.selectText) {
      this._inputElement.select();
    }
    if (!(option === null || option === void 0 ? void 0 : option.preventScroll)) {
      this._inputElement.scrollIntoView({ behavior: "smooth", block: "center" });
    }
    this._inputElement.focus({ preventScroll: true });
  }
  /** Remove o foco do campo */
  async setBlur() {
    this._inputElement.blur();
  }
  /** Adiciona uma tag programaticamente */
  async addTag(tag) {
    return this.handleAddTag(tag);
  }
  /** Remove uma tag programaticamente */
  async removeTag(tag) {
    return this.handleRemoveTag(tag);
  }
  /** Limpa todas as tags */
  async clearTags() {
    this.tags = [];
    this.ezChange.emit([...this.tags]);
  }
  addInfoId() {
    if (this._element) {
      ElementIDUtils.addIDInfo(this._element);
    }
    if (this._inputElement) {
      const dataInfo = { id: 'embedded' };
      ElementIDUtils.addIDInfo(this._inputElement, 'tag-input', dataInfo);
    }
  }
  initializeKeyboardManager() {
    this._keyboardManager = new KeyboardManager({
      propagate: true,
      element: this._element,
    })
      .bind("Enter", () => this.handleAddCurrentTag())
      .bind("Tab", () => this.handleAddCurrentTag())
      .bind("Escape", () => this.handleClearInput())
      .bind("ArrowLeft", () => this.handlePreviousTagFocus())
      .bind("ArrowRight", () => this.handleNextTagFocus());
  }
  handleAddCurrentTag() {
    if (this._inputElement.value.trim()) {
      const success = this.handleAddTag(this._inputElement.value);
      if (success) {
        this._inputElement.value = '';
      }
      return success;
    }
    return false;
  }
  handleAddTag(tag) {
    const parsedTag = tag.trim();
    if (!this.enabled || this.readonly) {
      return false;
    }
    if (!parsedTag || parsedTag.length === 0) {
      return false;
    }
    if (this.maxTagLength && parsedTag.length > this.maxTagLength) {
      return false;
    }
    if (this.maxTags && this.tags.length >= this.maxTags) {
      return false;
    }
    if (!this.allowDuplicates && this.tags.includes(parsedTag)) {
      return false;
    }
    if (this.validator) {
      const validationResult = this.validator(parsedTag, [...this.tags]);
      if (validationResult === false) {
        this.ezValidationError.emit({ tag: parsedTag, error: undefined });
        return false;
      }
      if (typeof validationResult === 'string') {
        this.ezValidationError.emit({ tag: parsedTag, error: validationResult });
        return false;
      }
    }
    this.tags = [...this.tags, parsedTag];
    this.ezChange.emit([...this.tags]);
    this.ezTagAdded.emit(parsedTag);
    return true;
  }
  async updateTagFocus(lastIndex) {
    var _a;
    if (!((_a = this.tags) === null || _a === void 0 ? void 0 : _a.length) || this.suppressTagsKeyboardNavigation) {
      await this.setFocus();
      return;
    }
    if (!lastIndex) {
      return;
    }
    const nextIndex = lastIndex - 1;
    const tagElement = this._element.shadowRoot.querySelector(`#tag-${nextIndex}`);
    if (tagElement) {
      await tagElement.setFocus();
    }
  }
  getCurrentActiveTagIndex() {
    var _a;
    const currentActiveTag = this._element.shadowRoot.activeElement;
    if (!((_a = this.tags) === null || _a === void 0 ? void 0 : _a.length) || currentActiveTag.tagName.toLowerCase() !== 'ez-chip') {
      return null;
    }
    const currentIndex = parseInt(currentActiveTag.id.split('-')[1], 10);
    if (Number.isNaN(currentIndex) || currentIndex < 0 || currentIndex >= this.tags.length) {
      return null;
    }
    return currentIndex;
  }
  async setTagFocus(tagIndex) {
    const tagElement = this._element.shadowRoot.querySelector(`#tag-${tagIndex}`);
    if (tagElement) {
      await tagElement.setFocus();
    }
  }
  async handlePreviousTagFocus() {
    if (this.suppressTagsKeyboardNavigation || !this.enabled || this.readonly) {
      return;
    }
    if (this._element.shadowRoot.activeElement === this._inputElement) {
      await this.setTagFocus(this.tags.length - 1);
      return;
    }
    const currentIndex = this.getCurrentActiveTagIndex();
    if (currentIndex === null) {
      await this.setFocus();
      return;
    }
    if (currentIndex === 0) {
      return;
    }
    await this.setTagFocus(currentIndex - 1);
  }
  async handleNextTagFocus() {
    if (this.suppressTagsKeyboardNavigation || !this.enabled || this.readonly) {
      return;
    }
    const currentIndex = this.getCurrentActiveTagIndex();
    if (currentIndex === null || currentIndex >= this.tags.length - 1) {
      await this.setFocus();
      return;
    }
    await this.setTagFocus(currentIndex + 1);
  }
  handleRemoveTag(tagToRemove) {
    if (!this.enabled || this.readonly) {
      return false;
    }
    const tagIndex = this.tags.indexOf(tagToRemove);
    if (tagIndex === -1) {
      return false;
    }
    this.tags = this.tags.filter(tag => tag !== tagToRemove);
    this.ezChange.emit([...this.tags]);
    this.ezTagRemoved.emit(tagToRemove);
    return true;
  }
  async componentWillLoad() {
    if (!this.tags) {
      this.tags = [];
    }
  }
  componentDidLoad() {
    this.addInfoId();
    this.initializeKeyboardManager();
  }
  disconnectedCallback() {
    var _a;
    (_a = this._keyboardManager) === null || _a === void 0 ? void 0 : _a.unbindAllShortcutKeys();
  }
  render() {
    return (h(Host, null, h("label", { htmlFor: this.name }, this.label), h("div", { class: "tag-input__container", "data-state": this.state, "data-disabled": (!this.enabled).toString(), onClick: () => this.setFocus({ preventScroll: true }) }, this.tags.map((tag, index) => (h("ez-chip", { key: `tag-${index}`, id: `tag-${index}`, label: tag, enabled: this.enabled && !this.readonly, removePosition: this.enabled && !this.readonly ? "right" : undefined, mode: "label", onRemoveChip: () => this.handleTagClick(tag, index), tabIndex: (this.suppressTagsKeyboardNavigation || !this.enabled || this.readonly) ? -1 : 0, disableAutoUpdateValue: true, removeWithKeyboard: true }))), h("input", { ref: (el) => this._inputElement = el, id: this.name, type: "text", placeholder: this.placeholder, disabled: !this.enabled, readonly: this.readonly, maxlength: this.maxTagLength, onInput: this.handleInputChange, onKeyDown: this.handleInputKeyDown, onFocus: this.handleInputFocus, onBlur: this.handleInputBlur })), this.helpText && (h("span", { title: this.helpText }, this.helpText))));
  }
  static get is() { return "ez-tag-input"; }
  static get encapsulation() { return "shadow"; }
  static get originalStyleUrls() {
    return {
      "$": ["ez-tag-input.css"]
    };
  }
  static get styleUrls() {
    return {
      "$": ["ez-tag-input.css"]
    };
  }
  static get properties() {
    return {
      "label": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Texto do label exibido acima do input"
        },
        "attribute": "label",
        "reflect": false,
        "defaultValue": "''"
      },
      "placeholder": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Placeholder do input"
        },
        "attribute": "placeholder",
        "reflect": false,
        "defaultValue": "''"
      },
      "helpText": {
        "type": "string",
        "mutable": true,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Texto de ajuda exibido abaixo do input"
        },
        "attribute": "help-text",
        "reflect": false
      },
      "enabled": {
        "type": "boolean",
        "mutable": false,
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Define se o input est\u00E1 habilitado"
        },
        "attribute": "enabled",
        "reflect": false,
        "defaultValue": "true"
      },
      "readonly": {
        "type": "boolean",
        "mutable": false,
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Define se o input \u00E9 somente leitura"
        },
        "attribute": "readonly",
        "reflect": false,
        "defaultValue": "false"
      },
      "name": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Nome do input"
        },
        "attribute": "name",
        "reflect": false
      },
      "tags": {
        "type": "unknown",
        "mutable": true,
        "complexType": {
          "original": "string[]",
          "resolved": "string[]",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Array de tags iniciais"
        },
        "defaultValue": "[]"
      },
      "maxTagLength": {
        "type": "number",
        "mutable": false,
        "complexType": {
          "original": "number",
          "resolved": "number",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Tamanho m\u00E1ximo de uma tag"
        },
        "attribute": "max-tag-length",
        "reflect": false
      },
      "maxTags": {
        "type": "number",
        "mutable": false,
        "complexType": {
          "original": "number",
          "resolved": "number",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "N\u00FAmero m\u00E1ximo de tags permitidas"
        },
        "attribute": "max-tags",
        "reflect": false
      },
      "allowDuplicates": {
        "type": "boolean",
        "mutable": false,
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Define se tags duplicadas s\u00E3o permitidas"
        },
        "attribute": "allow-duplicates",
        "reflect": false,
        "defaultValue": "false"
      },
      "state": {
        "type": "string",
        "mutable": true,
        "complexType": {
          "original": "\"default\" | \"error\" | \"success\" | \"warning\"",
          "resolved": "\"default\" | \"error\" | \"success\" | \"warning\"",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Estado visual do componente"
        },
        "attribute": "state",
        "reflect": true,
        "defaultValue": "\"default\""
      },
      "validator": {
        "type": "unknown",
        "mutable": false,
        "complexType": {
          "original": "(tag: string, existingTags: string[]) => boolean | string",
          "resolved": "(tag: string, existingTags: string[]) => string | boolean",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [{
              "name": "param",
              "text": "tag - A tag que est\u00E1 sendo validada"
            }, {
              "name": "param",
              "text": "existingTags - Array com as tags j\u00E1 existentes"
            }, {
              "name": "returns",
              "text": "true se v\u00E1lida, false ou string com mensagem de erro se inv\u00E1lida"
            }, {
              "name": "example",
              "text": "// Valida\u00E7\u00E3o para permitir apenas n\u00FAmeros\nvalidator={(tag) => /^\\d+$/.test(tag) || \"Apenas n\u00FAmeros s\u00E3o permitidos\"}\n\n// Valida\u00E7\u00E3o para evitar palavr\u00F5es\nvalidator={(tag) => !badWords.includes(tag.toLowerCase())}"
            }],
          "text": "Fun\u00E7\u00E3o de valida\u00E7\u00E3o customizada para tags"
        }
      },
      "suppressTagsKeyboardNavigation": {
        "type": "boolean",
        "mutable": false,
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Define se a navega\u00E7\u00E3o por teclado pelas tags deve ser suprimida"
        },
        "attribute": "suppress-tags-keyboard-navigation",
        "reflect": false,
        "defaultValue": "false"
      },
      "suppressBackspaceToRemove": {
        "type": "boolean",
        "mutable": false,
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Define se a tecla Backspace deve remover a \u00FAltima tag quando o input est\u00E1 vazio"
        },
        "attribute": "suppress-backspace-to-remove",
        "reflect": false,
        "defaultValue": "false"
      }
    };
  }
  static get events() {
    return [{
        "method": "ezChange",
        "name": "ezChange",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": "Evento disparado quando as tags mudam"
        },
        "complexType": {
          "original": "string[]",
          "resolved": "string[]",
          "references": {}
        }
      }, {
        "method": "ezTagAdded",
        "name": "ezTagAdded",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": "Evento disparado quando uma tag \u00E9 adicionada"
        },
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        }
      }, {
        "method": "ezTagRemoved",
        "name": "ezTagRemoved",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": "Evento disparado quando uma tag \u00E9 removida"
        },
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        }
      }, {
        "method": "ezFocus",
        "name": "ezFocus",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": "Evento disparado quando o input recebe foco"
        },
        "complexType": {
          "original": "string[]",
          "resolved": "string[]",
          "references": {}
        }
      }, {
        "method": "ezBlur",
        "name": "ezBlur",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": "Evento disparado quando o input perde foco"
        },
        "complexType": {
          "original": "string[]",
          "resolved": "string[]",
          "references": {}
        }
      }, {
        "method": "ezValidationError",
        "name": "ezValidationError",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": "Evento disparado quando uma valida\u00E7\u00E3o falha"
        },
        "complexType": {
          "original": "{ tag: string; error?: string }",
          "resolved": "{ tag: string; error?: string; }",
          "references": {}
        }
      }, {
        "method": "ezType",
        "name": "ezType",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": "Emitido quando \u00E9 digitado no campo de entrada"
        },
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        }
      }];
  }
  static get methods() {
    return {
      "setFocus": {
        "complexType": {
          "signature": "(option?: OptionsSetFocus) => Promise<void>",
          "parameters": [{
              "tags": [],
              "text": ""
            }],
          "references": {
            "Promise": {
              "location": "global"
            },
            "OptionsSetFocus": {
              "location": "import",
              "path": "./interfaces/optionsSetFocus"
            }
          },
          "return": "Promise<void>"
        },
        "docs": {
          "text": "Aplica o foco no campo",
          "tags": []
        }
      },
      "setBlur": {
        "complexType": {
          "signature": "() => Promise<void>",
          "parameters": [],
          "references": {
            "Promise": {
              "location": "global"
            }
          },
          "return": "Promise<void>"
        },
        "docs": {
          "text": "Remove o foco do campo",
          "tags": []
        }
      },
      "addTag": {
        "complexType": {
          "signature": "(tag: string) => Promise<boolean>",
          "parameters": [{
              "tags": [],
              "text": ""
            }],
          "references": {
            "Promise": {
              "location": "global"
            }
          },
          "return": "Promise<boolean>"
        },
        "docs": {
          "text": "Adiciona uma tag programaticamente",
          "tags": []
        }
      },
      "removeTag": {
        "complexType": {
          "signature": "(tag: string) => Promise<boolean>",
          "parameters": [{
              "tags": [],
              "text": ""
            }],
          "references": {
            "Promise": {
              "location": "global"
            }
          },
          "return": "Promise<boolean>"
        },
        "docs": {
          "text": "Remove uma tag programaticamente",
          "tags": []
        }
      },
      "clearTags": {
        "complexType": {
          "signature": "() => Promise<void>",
          "parameters": [],
          "references": {
            "Promise": {
              "location": "global"
            }
          },
          "return": "Promise<void>"
        },
        "docs": {
          "text": "Limpa todas as tags",
          "tags": []
        }
      }
    };
  }
  static get elementRef() { return "_element"; }
}
