'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

const index = require('./index-a7b0c73d.js');
const core = require('@sankhyalabs/core');
require('./ApplicationUtils-5cc05979.js');
const CSSVarsUtils = require('./CSSVarsUtils-f20973d1.js');
require('./DialogType-2114c337.js');
require('./CheckMode-ecb90b87.js');
const index$1 = require('./index-1be40f19.js');
require('./FormLayout-18853e70.js');

const ezComboBoxCss = ":host{--ez-combo-box--height:42px;--ez-combo-box--width:100%;--ez-combo-box--border-radius:var(--border--radius-medium, 12px);--ez-combo-box--font-size:var(--text--medium, 14px);--ez-combo-box--font-family:var(--font-pattern, Arial);--ez-combo-box--background-color--xlight:var(--background--xlight, #fff);--ez-combo-box__input--background-color:var(--background--medium, #e0e0e0);--ez-combo-box__input--border:var(--border--medium, 2px solid);--ez-combo-box__input--border-color:var(--ez-combo-box__input--background-color);--ez-combo-box__input--focus--border-color:var(--color--primary, #008561);--ez-combo-box__input--disabled--background-color:var(--color--disable-secondary, #F2F5F8);--ez-combo-box__input--disabled--color:var(--text--disable, #AFB6C0);--ez-combo-box__btn--color:var(--title--primary, #2B3A54);--ez-combo-box__btn-disabled--color:var(--text--disable, #AFB6C0);--ez-combo-box__btn-hover--color:var(--color--primary, #4e4e4e);width:var(--ez-combo-box--width)}ez-icon{--ez-icon--color:inherit;font-weight:var(--text-weight--large, 600)}.suppressed-search-input{--ez-text-input__input--border-color:var(--color--strokes, #dce0e8);--ez-text-input__input--disabled--background-color:var(--background--xlight, #fff);--ez-text-input__input--disabled--color:var(--title--primary, #2B3A54)}.btn{outline:none;border:none;background:none;cursor:pointer;padding:0px;color:var(--ez-combo-box__btn--color)}.btn:disabled{cursor:unset;color:var(--ez-combo-box__btn-disabled--color)}.btn:disabled:hover{cursor:not-allowed;color:var(--ez-combo-box__btn-disabled--color)}.btn:hover{color:var(--ez-combo-box__btn-hover--color)}.btn__close{visibility:hidden}ez-text-input:hover .btn__close,ez-text-input:focus .btn__close{visibility:visible}.text-input-slot-container{--ez-text-input__icon--width:32px;--ez-text-input__min-width:var(--ez-combo-box__min-width);--ez-text-input__max-width:var(--ez-combo-box__max-width)}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg)}}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}";

const EzComboBox = class {
  constructor(hostRef) {
    index.registerInstance(this, hostRef);
    this.ezChange = index.createEvent(this, "ezChange", 7);
    this.ezVisibilityChange = index.createEvent(this, "ezVisibilityChange", 7);
    this._changeDeboucingTimeout = null;
    this._deboucingTime = 300;
    this._maxWidthValue = 0;
    this._tabPressed = false;
    this._lookupMode = false;
    this.isOpen = false;
    this._preSelection = undefined;
    this._visibleOptions = undefined;
    this._startLoading = false;
    this._showLoading = true;
    this._criteria = undefined;
    this.limitCharsToSearch = 3;
    this.value = undefined;
    this.label = undefined;
    this.enabled = true;
    this.options = undefined;
    this.errorMessage = undefined;
    this.showSelectedValue = false;
    this.showOptionValue = false;
    this.suppressSearch = false;
    this.optionLoader = undefined;
    this.suppressEmptyOption = false;
    this.stopPropagateEnterKeyEvent = true;
    this.canShowError = true;
    this.mode = "regular";
    this.hideErrorOnFocusOut = true;
    this.listOptionsPosition = undefined;
    this.isTextSearch = false;
    this.autoFocus = false;
    this.preventAutoFocus = false;
    this.alternativePlaceholder = undefined;
    this.textEmptyOption = undefined;
  }
  observeErrorMessage() {
    var _a;
    if (this._textInput) {
      this._textInput.errorMessage = this.errorMessage;
      if (!((_a = this.errorMessage) === null || _a === void 0 ? void 0 : _a.trim())) {
        this.setInputValue();
      }
    }
  }
  observeValue(newValue, oldValue) {
    if (this._textInput && newValue != oldValue) {
      try {
        if (typeof newValue === "string") {
          this.setInputValue();
          return;
        }
        const newValueSelected = this.getSelectedOption(newValue);
        const oldValueSelected = this.getSelectedOption(oldValue);
        const currentValue = this.getSelectedOption(this.value);
        if (this.isDifferentValues(currentValue, newValueSelected)) {
          this.value = newValueSelected;
        }
        if (this.isDifferentValues(newValueSelected, oldValueSelected)) {
          this.setInputValue();
          const valueEmitted = newValueSelected === null ? undefined : newValueSelected;
          if (!this._lookupMode) {
            this.ezChange.emit(valueEmitted);
          }
        }
        this.resetOptions();
      }
      finally {
        this._lookupMode = false;
      }
    }
  }
  observeOptions(newOptions, oldOptions) {
    if (core.ObjectUtils.equals(newOptions, oldOptions))
      return;
    this.loadOptions(SearchMode.PRELOAD);
  }
  /*
  * Retorna uma promise com o valor da opção selecionada,
  * que será resolvida quando o backend devolver este dado.
  */
  async getValueAsync() {
    if (!this._showLoading) {
      return new Promise(resolve => resolve(this.sanitizeValue(this.value)));
    }
    return new Promise(resolve => {
      let id = setInterval(() => {
        if (!this._showLoading) {
          clearInterval(id);
          resolve(this.sanitizeValue(this.value));
        }
      }, 100);
    });
  }
  /**
   * Aplica o foco no campo.
   */
  async setFocus(options) {
    if (this._textInput) {
      this._textInput.setFocus(options);
    }
  }
  /**
   * Remove o foco do campo.
   */
  async setBlur() {
    if (this._textInput) {
      this._textInput.setBlur();
    }
  }
  /**
   * Retorna se o conteúdo é inválido.
   */
  async isInvalid() {
    return typeof this.errorMessage === "string" && this.errorMessage.trim() !== "";
  }
  /**
   * Limpa o valor do campo de pesquisa
   */
  async clearValue() {
    this.clearSearch();
  }
  isDifferentValues(firstValue, secondValue) {
    return core.ObjectUtils.objectToString(firstValue || {}) !== core.ObjectUtils.objectToString(secondValue || {});
  }
  getFormattedText(currentValue) {
    if (currentValue == undefined) {
      return;
    }
    if (!this.showSelectedValue || currentValue.value == undefined) {
      return currentValue.label;
    }
    return currentValue.label ? `${currentValue.value} - ${currentValue.label}` : currentValue.value;
  }
  getText() {
    const currentValue = this.getSelectedOption(this.sanitizeValue(this.value));
    const text = this.getFormattedText(currentValue);
    if (text == undefined) {
      return;
    }
    return String(text)
      .replace(/&amp;/g, '&')
      .replace(/&lt;/g, '<')
      .replace(/&gt;/g, '>')
      .replace(/&quot;/g, '"');
  }
  getSelectedOption(value) {
    if (typeof value === "string" || value instanceof String) {
      return this._visibleOptions.find(o => o.value === value);
    }
    return value;
  }
  updateVisibleOptions() {
    let opts = this._source || [];
    if (this._criteria) {
      const upperCriteria = this._criteria.toUpperCase();
      opts = opts.filter(opt => opt.label.toLocaleUpperCase().indexOf(upperCriteria) > -1);
    }
    if (this.hasToAddEmptyoption(opts)) {
      opts = [{ value: undefined, label: this.textEmptyOption || this.i18n("ez-combo-box.placeholder") }].concat(opts);
    }
    this._visibleOptions = opts;
    this._maxWidthValue = this.getMaxWidthValue();
  }
  hasToAddEmptyoption(opts) {
    return !this.suppressEmptyOption && !opts.filter(opt => !opt.value).length;
  }
  getMaxWidthValue() {
    var _a;
    if (this.showOptionValue) {
      const arrValues = [];
      (_a = this._visibleOptions) === null || _a === void 0 ? void 0 : _a.forEach(opt => {
        const widthValue = this.getWidthValue(opt.value);
        if (!arrValues.includes(widthValue)) {
          arrValues.push(widthValue);
        }
      });
      return arrValues.length > 1 ? Math.max(...arrValues) : 0;
    }
    return 0;
  }
  getWidthValue(value) {
    if (this._itemValueBasis != undefined) {
      const span = this._itemValueBasis;
      if (value != undefined) {
        span.innerHTML = value;
        return span.clientWidth > 0 ? (span.clientWidth + 2) : 0;
      }
      else {
        span.innerHTML = "";
      }
    }
    return 0;
  }
  async showOptions() {
    var _a, _b;
    if (!this.enabled)
      return;
    await this.openPopover();
    const valueString = (_b = (_a = this.value) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : this.value;
    const indexValue = this._visibleOptions.findIndex(option => option.value === valueString);
    this._preSelection = indexValue === -1 ? 0 : indexValue;
    if (!!this._resizeObserver)
      this._resizeObserver.observe(this._textInput);
    if (!this.preventAutoFocus)
      await this.setFocus();
  }
  hideOptions() {
    var _a;
    (_a = this._popover) === null || _a === void 0 ? void 0 : _a.hide();
    if (!!this._resizeObserver)
      this._resizeObserver.unobserve(this._textInput);
  }
  updateSource(source) {
    this._startLoading = false;
    if (source instanceof Promise) {
      this._showLoading = true;
      source.then(result => {
        this._showLoading = false;
        this.updateSource(result);
      }).catch(() => this._showLoading = false);
      this.updateVisibleOptions();
    }
    else {
      this._showLoading = false;
      if (Array.isArray(source)) {
        this._source = source;
        this.updateVisibleOptions();
        if (this._tabPressed) {
          this._tabPressed = false;
        }
      }
      else {
        this.selectOption(source);
      }
    }
  }
  selectOption(newOption, focusOnInput = true) {
    var _a, _b, _c;
    const currentValue = this.getSelectedOption(this.value);
    if ((((_a = currentValue === null || currentValue === void 0 ? void 0 : currentValue.value) === null || _a === void 0 ? void 0 : _a.toString()) !== ((_b = newOption === null || newOption === void 0 ? void 0 : newOption.value) === null || _b === void 0 ? void 0 : _b.toString()))
      || (currentValue == undefined && newOption != undefined && "value" in newOption)) {
      const adjustedOpt = !(newOption === null || newOption === void 0 ? void 0 : newOption.value) ? undefined : newOption;
      this.value = adjustedOpt;
      (_c = this._popover) === null || _c === void 0 ? void 0 : _c.hide();
    }
    else {
      this.resetOptions();
    }
    if (focusOnInput) {
      setTimeout(() => {
        this.setFocus();
      }, 0);
    }
  }
  loadOptions(mode, argument = "") {
    this._criteria = argument;
    this._startLoading = true;
    if (this.optionLoader) {
      const searchArgument = { mode, argument };
      this.updateSource(this.optionLoader(searchArgument));
    }
    else {
      this.updateSource(this.options);
    }
  }
  cancelPreselection() {
    if (!this._textInput.value && this.sanitizeValue(this.value)) {
      this.selectOption(undefined);
    }
    else {
      window.setTimeout(() => {
        this.setInputValue(false);
      }, this._deboucingTime);
    }
  }
  setInputValue(clearError = true) {
    const textValue = this.getText();
    if ((this._textInput.value || '') !== textValue) {
      this._textInput.value = textValue;
      if (clearError) {
        this.errorMessage = null;
      }
    }
  }
  clearSearch() {
    this.value = null;
  }
  resetOptions() {
    this.hideOptions();
    this._criteria = undefined;
    this._preSelection = undefined;
    this.updateVisibleOptions();
  }
  sanitizeValue(value) {
    if (value === "undefined" || value === "null") {
      return undefined;
    }
    return value;
  }
  //---------------------------------------------
  // Lifecycle web component
  //---------------------------------------------
  async componentWillLoad() {
    this.i18n = await index$1.initI18n();
    if (this.options === undefined) {
      this.options = [];
      const optionsTags = this.el.querySelectorAll("option");
      if (optionsTags) {
        optionsTags.forEach(e => {
          let label = e.innerText;
          let value = e.getAttribute("value");
          if (!value) {
            value = label;
          }
          this.options.push({ label, value });
          e.hidden = true;
        });
      }
    }
    this.loadOptions(SearchMode.PRELOAD);
  }
  setResizeObserver() {
    this._resizeObserver = new ResizeObserver((entries) => {
      window.requestAnimationFrame(() => {
        if (!Array.isArray(entries) || !entries.length)
          return;
        if (!this._textInput)
          return;
        if (!this._comboBoxList)
          return;
        const textInputWidth = this._textInput.clientWidth;
        this._comboBoxList.width = textInputWidth;
      });
    });
  }
  connectedCallback() {
    if (!this._resizeObserver) {
      this.setResizeObserver();
    }
  }
  componentDidLoad() {
    CSSVarsUtils.CSSVarsUtils.applyVarsTextInput(this.el, this._textInput);
    this.setInputValue(false);
    this.setResizeObserver();
    if (this.autoFocus) {
      requestAnimationFrame(() => {
        this.setFocus({ selectText: true });
      });
    }
  }
  disconnectedCallback() {
    var _a;
    (_a = this._popover) === null || _a === void 0 ? void 0 : _a.remove();
    if (this._resizeObserver) {
      this._resizeObserver.disconnect();
      this._resizeObserver = null;
    }
  }
  //---------------------------------------------
  // Event handlers
  //---------------------------------------------
  handlerIconClick() {
    this.showOptions();
  }
  onTextInputChangeHandler(event) {
    var _a;
    this.clearDeboucingTimeout();
    if (this._startLoading) {
      this._changeDeboucingTimeout = window.setTimeout(() => {
        this.onTextInputChangeHandler(event);
      }, this._deboucingTime);
      return;
    }
    const argument = (_a = event.target.value) === null || _a === void 0 ? void 0 : _a.trim();
    if (!this._criteria) {
      this._textInput.value = event.data || argument;
    }
    this._criteria = argument;
    if (argument) {
      this.updateVisibleOptions();
      this.showOptions();
    }
    else {
      this._preSelection = undefined;
      this.updateVisibleOptions();
    }
  }
  clearDeboucingTimeout() {
    if (this._changeDeboucingTimeout) {
      window.clearTimeout(this._changeDeboucingTimeout);
      this._changeDeboucingTimeout = null;
    }
  }
  onTextInputClickHandler() {
    this.showOptions();
  }
  keyDownHandler(event) {
    var _a, _b, _c, _d, _e, _f;
    if (event.ctrlKey && (event.key === "f" || event.key === "F")) {
      this.loadOptions(SearchMode.ADVANCED);
      event.preventDefault();
      event.stopPropagation();
      return;
    }
    switch (event.key) {
      case "ArrowDown":
        event.preventDefault();
        if (this.canShowListOptions()) {
          this.showOptions();
          (_a = this._comboBoxList) === null || _a === void 0 ? void 0 : _a.nextOption();
        }
        break;
      case "ArrowUp":
        event.preventDefault();
        if (this.canShowListOptions()) {
          this.showOptions();
          (_b = this._comboBoxList) === null || _b === void 0 ? void 0 : _b.previousOption();
        }
        break;
      case "Enter":
        if (this.isOpen) {
          event.preventDefault();
          (_c = this._comboBoxList) === null || _c === void 0 ? void 0 : _c.selectCurrentOption();
        }
        break;
      case "Escape":
        if (this.isOpen) {
          event.preventDefault();
          (_d = this._popover) === null || _d === void 0 ? void 0 : _d.hide();
        }
        break;
      case "Tab":
        this._tabPressed = true;
        if (this.isOpen) {
          (_e = this._comboBoxList) === null || _e === void 0 ? void 0 : _e.selectCurrentOption();
          (_f = this._popover) === null || _f === void 0 ? void 0 : _f.hide();
        }
        break;
    }
  }
  onTextInputFocusOutHandler() {
    if (this.hideErrorOnFocusOut)
      this.cancelPreselection();
  }
  canShowListOptions() {
    return !this._showLoading && this._visibleOptions.length > 0;
  }
  async openPopover() {
    var _a;
    this.isOpen = true;
    await ((_a = this._popover) === null || _a === void 0 ? void 0 : _a.showUnder(this._textInput));
  }
  render() {
    var _a;
    core.ElementIDUtils.addIDInfoIfNotExists(this.el, 'input');
    return (index.h(index.Host, null, index.h("ez-text-input", { "data-element-id": core.ElementIDUtils.getInternalIDInfo("textInput"), class: `text-input-slot-container ${this.suppressSearch ? "suppressed-search-input" : ""}`, ref: elem => this._textInput = elem, "data-slave-mode": "true", enabled: this.enabled && !this.suppressSearch, onInput: event => this.onTextInputChangeHandler(event), onClick: () => this.onTextInputClickHandler(), onFocusout: () => this.onTextInputFocusOutHandler(), onKeyDown: event => this.keyDownHandler(event), label: this.label, canShowError: this.canShowError, errorMessage: this.errorMessage, mode: this.mode, alternativePlaceholder: this.alternativePlaceholder || this.i18n("ez-combo-box.placeholder") }, index.h("button", { class: "btn", slot: "rightIcon", disabled: !this.enabled, tabindex: -1, onClick: () => this.handlerIconClick() }, index.h("ez-icon", { iconName: "chevron-down" }))), index.h("ez-popover-plus", { ref: elem => this._popover = elem, anchorElement: this._textInput, autoClose: true, boxWidth: 'fit-content', overlayType: 'none', onEzVisibilityChange: event => this.isOpen = event.detail, "data-element-id": this.el.getAttribute("data-element-id") }, index.h("ez-combo-box-list", { ref: ref => this._comboBoxList = ref, showLoading: this._showLoading, visibleOptions: this._visibleOptions, textEmptyList: this.i18n("ez-combo-box.noResults"), showOptionValue: this.showOptionValue, preSelection: this._preSelection, maxWidth: this._maxWidthValue, width: (_a = this._textInput) === null || _a === void 0 ? void 0 : _a.clientWidth, onOptionSelect: (opt) => this.selectOption(opt), onOptionHover: (index) => this._preSelection = index }))));
  }
  get el() { return index.getElement(this); }
  static get watchers() { return {
    "errorMessage": ["observeErrorMessage"],
    "value": ["observeValue"],
    "options": ["observeOptions"]
  }; }
};
var SearchMode;
(function (SearchMode) {
  SearchMode["ADVANCED"] = "ADVANCED";
  SearchMode["PRELOAD"] = "PRELOAD";
  SearchMode["PREDICTIVE"] = "PREDICTIVE";
})(SearchMode || (SearchMode = {}));
EzComboBox.style = ezComboBoxCss;

exports.ez_combo_box = EzComboBox;
