import { ElementIDUtils, KeyboardManager } from '@sankhyalabs/core';
import { Host, h } from '@stencil/core';
export class EzClassicComboBox {
  constructor() {
    this._keyboardManager = undefined;
    this._boundHandleDocumentClick = this.handleDocumentClick.bind(this);
    this.popoverVisible = false;
    this.hasSlotContent = false;
    this.highlightedIndex = 0;
    this.filteredOptions = [];
    this.inputValue = '';
    this.value = null;
    this.label = undefined;
    this.placeholder = undefined;
    this.enabled = true;
    this.readonly = false;
    this.name = undefined;
    this.state = "default";
    this.helpText = undefined;
    this.iconName = undefined;
    this.titleIcon = undefined;
    this.iconClickable = false;
    this.suppressSearch = false;
    this.options = undefined;
    this.textEmptyOption = undefined;
    this.suppressEmptyOption = false;
  }
  /**
   * Aplica o foco no campo.
   */
  async setFocus(option) {
    var _a;
    await ((_a = this._inputElem) === null || _a === void 0 ? void 0 : _a.setFocus(option));
  }
  /**
   * Remove o foco do campo.
   */
  async setBlur() {
    var _a;
    await ((_a = this._inputElem) === null || _a === void 0 ? void 0 : _a.setBlur());
    await this.hidePopover();
  }
  /**
   * Exibe o popover abaixo do input.
   */
  async showPopover() {
    var _a, _b, _c;
    if (!this._popoverElem || !this._inputElem || this.popoverVisible) {
      return;
    }
    this.popoverVisible = true;
    const inputContainer = (_b = (_a = this._inputElem) === null || _a === void 0 ? void 0 : _a.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector('.input-container');
    await ((_c = this._popoverElem) === null || _c === void 0 ? void 0 : _c.showUnder(inputContainer !== null && inputContainer !== void 0 ? inputContainer : this._inputElem));
  }
  /**
   * Oculta o popover.
   */
  async hidePopover() {
    var _a;
    this.popoverVisible = false;
    await ((_a = this._popoverElem) === null || _a === void 0 ? void 0 : _a.hide());
  }
  compareOptionValues(option1, option2) {
    var _a, _b;
    return JSON.stringify((_a = option1 === null || option1 === void 0 ? void 0 : option1.value) !== null && _a !== void 0 ? _a : null) === JSON.stringify((_b = option2 === null || option2 === void 0 ? void 0 : option2.value) !== null && _b !== void 0 ? _b : null);
  }
  setEmptyValue() {
    this.value = null;
    this.inputValue = '';
  }
  async setValue(option) {
    if (!option || !this.options) {
      this.setEmptyValue();
      await this.hidePopover();
      return;
    }
    if (this.compareOptionValues(this.value, option)) {
      await this.hidePopover();
      return;
    }
    if (!option.value) {
      this.setEmptyValue();
    }
    else {
      this.value = option;
      this.inputValue = option.label;
    }
    this.ezChange.emit(this.value);
    await this.hidePopover();
  }
  async optionsChanged() {
    this.filterOptions('');
  }
  async valueChanged(newValue) {
    if (newValue) {
      this.inputValue = newValue.label;
      this.setHighlightedIndexToValue();
    }
    else {
      this.inputValue = '';
      this.highlightedIndex = 0;
    }
  }
  async handleIconClick(event) {
    event.stopPropagation();
    event.preventDefault();
    if (event.detail.icon === 'right') {
      if (!this.popoverVisible) {
        await this.showPopover();
      }
      else {
        await this.hidePopover();
      }
    }
    else {
      this.iconClick.emit();
    }
  }
  async handleEzChange(event) {
    event.stopPropagation();
    this.inputValue = event.detail;
    if (!this.popoverVisible && this.inputValue.length > 0) {
      await this.showPopover();
    }
    this.ezType.emit(this.inputValue);
    this.highlightedIndex = 0;
    this.filterOptions(this.inputValue);
  }
  async handleEzBlur(event) {
    var _a, _b;
    event.stopPropagation();
    if (((_a = this.value) === null || _a === void 0 ? void 0 : _a.label) !== this.inputValue) {
      this.inputValue = ((_b = this.value) === null || _b === void 0 ? void 0 : _b.label) || '';
    }
    this.ezBlur.emit(this.value);
  }
  filterOptions(searchTerm) {
    if (!this.options) {
      this.filteredOptions = [];
      return;
    }
    let currentOptions = [];
    if (!searchTerm || searchTerm.trim() === '') {
      currentOptions = currentOptions.concat([...this.options]);
    }
    else {
      const term = searchTerm.toLowerCase().trim();
      currentOptions = currentOptions.concat(this.options.filter(option => option.label.toLowerCase().includes(term) ||
        option.value.toLowerCase().includes(term)));
    }
    if (!this.suppressEmptyOption && currentOptions.length > 0) {
      currentOptions = [
        {
          value: null,
          label: this.textEmptyOption || "Selecione um item"
        },
        ...currentOptions
      ];
    }
    this.filteredOptions = currentOptions;
    this.setHighlightedIndexToValue();
    this.scrollToHighlightedOption();
  }
  scrollToHighlightedOption() {
    if (this.highlightedIndex < 0 || !this._listElem) {
      return;
    }
    const highlightedOption = this._listElem.children[this.highlightedIndex];
    if (highlightedOption) {
      highlightedOption.scrollIntoView({
        behavior: 'smooth',
        block: 'nearest',
        inline: 'start'
      });
    }
  }
  async selectOption(option) {
    if (!option || this.readonly || !this.enabled) {
      return;
    }
    await this.setValue(option);
  }
  async handleArrowUp() {
    var _a;
    if (!this.popoverVisible) {
      await this.showPopover();
      return;
    }
    const optionsLength = ((_a = this.filteredOptions) === null || _a === void 0 ? void 0 : _a.length) || 0;
    if (optionsLength <= 0 || this.highlightedIndex <= 0) {
      return;
    }
    this.highlightedIndex = Math.max(0, this.highlightedIndex - 1);
    this.scrollToHighlightedOption();
  }
  handleArrowDown() {
    var _a;
    if (!this.popoverVisible) {
      this.showPopover();
      return;
    }
    const optionsLength = ((_a = this.filteredOptions) === null || _a === void 0 ? void 0 : _a.length) || 0;
    if (optionsLength <= 0) {
      return;
    }
    this.highlightedIndex = Math.min(optionsLength - 1, this.highlightedIndex + 1);
    this.scrollToHighlightedOption();
  }
  async selectCurrentItem() {
    if (!this.popoverVisible || this.highlightedIndex < 0) {
      return;
    }
    if (this.hasSlotContent || this.filteredOptions.length === 0 || this.readonly || !this.enabled) {
      await this.hidePopover();
      return;
    }
    if (this.filteredOptions && this.filteredOptions[this.highlightedIndex]) {
      this.selectOption(this.filteredOptions[this.highlightedIndex]);
    }
  }
  handleVisibilityChange(event) {
    this.popoverVisible = event.detail;
    this.ezVisibilityChange.emit(this.popoverVisible);
  }
  checkSlotContent() {
    const slot = this._element.querySelector('slot') || this._element;
    if (slot instanceof HTMLSlotElement) {
      this.hasSlotContent = slot.assignedNodes().length > 0;
    }
    else {
      this.hasSlotContent = slot.children.length > 0;
    }
  }
  setHighlightedIndexToValue() {
    if (this.value && this.filteredOptions) {
      const index = this.filteredOptions.findIndex(opt => opt.value === this.value.value);
      if (index >= 0) {
        this.highlightedIndex = index;
        return;
      }
      this.highlightedIndex = 0;
    }
  }
  async handleDocumentClick(event) {
    const target = event.target;
    if (!this._element.contains(target) && !this._popoverElem.contains(target)) {
      await this.hidePopover();
    }
  }
  addInfoId() {
    const dataInfo = { id: 'embedded' };
    if (this._element) {
      ElementIDUtils.addIDInfo(this._element);
    }
    if (this._inputElem) {
      ElementIDUtils.addIDInfo(this._inputElem, 'classic-combo-box-input', dataInfo);
    }
    if (this._popoverElem) {
      ElementIDUtils.addIDInfo(this._popoverElem, 'classic-combo-box-popover', dataInfo);
    }
  }
  async initKeyboardManager() {
    this._keyboardManager = new KeyboardManager({ element: this._element, propagate: true });
    this._keyboardManager
      .bind("ArrowUp", () => this.handleArrowUp(), { propagate: false })
      .bind("ArrowDown", () => this.handleArrowDown(), { propagate: false })
      .bind("Enter", () => this.selectCurrentItem(), { propagate: false })
      .bind("Tab", () => this.selectCurrentItem())
      .bind("shift+Tab", () => this.selectCurrentItem())
      .bind("Escape", () => this.hidePopover());
  }
  async connectedCallback() {
    await this.initKeyboardManager();
    document.addEventListener('mouseup', this._boundHandleDocumentClick);
  }
  disconnectedCallback() {
    this._keyboardManager.unbindAllShortcutKeys();
    document.removeEventListener('mouseup', this._boundHandleDocumentClick);
  }
  componentWillLoad() {
    this.filterOptions('');
  }
  componentDidLoad() {
    this.addInfoId();
    this.checkSlotContent();
    if (this.value) {
      this.inputValue = this.value.label;
      this.setHighlightedIndexToValue();
    }
  }
  render() {
    var _a;
    return (h(Host, null, h("ez-classic-input", { ref: ref => this._inputElem = ref, name: this.name, label: this.label, placeholder: this.placeholder, value: this.inputValue, state: this.state, enabled: this.enabled, readonly: this.readonly || this.suppressSearch, leftIconName: this.iconName, leftIconTooltip: this.titleIcon, leftIconClickable: this.iconClickable, rightIconClickable: true, helpText: this.helpText, rightIconName: this.popoverVisible ? 'chevron-up' : 'chevron-down', onIconClick: this.handleIconClick.bind(this), onEzChange: this.handleEzChange.bind(this), onEzFocus: this.showPopover.bind(this), onEzBlur: this.handleEzBlur.bind(this) }), h("ez-popover-core", { ref: ref => this._popoverElem = ref, useAnchorSize: true, onEzVisibilityChange: this.handleVisibilityChange.bind(this), overlayType: "none", options: { verticalGap: 2, horizontalGap: 0 }, autoClose: false }, h("slot", { onSlotchange: this.checkSlotContent.bind(this) }), !this.hasSlotContent && (((_a = this.filteredOptions) === null || _a === void 0 ? void 0 : _a.length) > 0 ? (h("ul", { ref: ref => this._listElem = ref, tabIndex: -1 }, this.filteredOptions.map((option, index) => {
      var _a, _b;
      return (h("li", { key: (_a = option.value) !== null && _a !== void 0 ? _a : '__empty__', value: option.value, class: {
          'highlighted': this.highlightedIndex === index,
          'selected': ((_b = this.value) === null || _b === void 0 ? void 0 : _b.value) === option.value
        }, onMouseDown: () => this.selectOption(option) }, option.label));
    }))) : (h("span", { class: "no-results" }, "Nenhum resultado encontrado"))))));
  }
  static get is() { return "ez-classic-combo-box"; }
  static get encapsulation() { return "shadow"; }
  static get originalStyleUrls() {
    return {
      "$": ["ez-classic-combo-box.css"]
    };
  }
  static get styleUrls() {
    return {
      "$": ["ez-classic-combo-box.css"]
    };
  }
  static get properties() {
    return {
      "value": {
        "type": "unknown",
        "mutable": true,
        "complexType": {
          "original": "IOption",
          "resolved": "IOption",
          "references": {
            "IOption": {
              "location": "import",
              "path": "./interfaces/IOption"
            }
          }
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Valor do combo box."
        },
        "defaultValue": "null"
      },
      "label": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Texto do label exibido acima do combo box."
        },
        "attribute": "label",
        "reflect": false
      },
      "placeholder": {
        "type": "string",
        "mutable": true,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Placeholder do combo box"
        },
        "attribute": "placeholder",
        "reflect": false
      },
      "enabled": {
        "type": "boolean",
        "mutable": false,
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Define se o combo box 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 combo box \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 combo box."
        },
        "attribute": "name",
        "reflect": false
      },
      "state": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "\"default\" | \"error\" | \"success\" | \"warning\"",
          "resolved": "\"default\" | \"error\" | \"success\" | \"warning\"",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Estado visual do combo box: default, error, success ou warning."
        },
        "attribute": "state",
        "reflect": false,
        "defaultValue": "\"default\""
      },
      "helpText": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Texto de ajuda exibido abaixo do combo box."
        },
        "attribute": "help-text",
        "reflect": false
      },
      "iconName": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Nome do \u00EDcone."
        },
        "attribute": "icon-name",
        "reflect": false
      },
      "titleIcon": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "T\u00EDtulo do \u00EDcone (tooltip)."
        },
        "attribute": "title-icon",
        "reflect": false
      },
      "iconClickable": {
        "type": "boolean",
        "mutable": false,
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Define se o \u00EDcone \u00E9 clic\u00E1vel"
        },
        "attribute": "icon-clickable",
        "reflect": false,
        "defaultValue": "false"
      },
      "suppressSearch": {
        "type": "boolean",
        "mutable": false,
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Se true desabilita a digita\u00E7\u00E3o dentro do componente."
        },
        "attribute": "suppress-search",
        "reflect": false,
        "defaultValue": "false"
      },
      "options": {
        "type": "unknown",
        "mutable": false,
        "complexType": {
          "original": "Array<IOption>",
          "resolved": "IOption[]",
          "references": {
            "Array": {
              "location": "global"
            },
            "IOption": {
              "location": "import",
              "path": "./interfaces/IOption"
            }
          }
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Array com as op\u00E7\u00F5es do ez-classic-combo-box. Os elementos devem obedecer\no formato: `{value: string, label: string}`."
        }
      },
      "textEmptyOption": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Texto a ser apresentado na op\u00E7\u00E3o de valor nulo."
        },
        "attribute": "text-empty-option",
        "reflect": false
      },
      "suppressEmptyOption": {
        "type": "boolean",
        "mutable": false,
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Se true remove a op\u00E7\u00E3o vazia da lista."
        },
        "attribute": "suppress-empty-option",
        "reflect": false,
        "defaultValue": "false"
      }
    };
  }
  static get states() {
    return {
      "popoverVisible": {},
      "hasSlotContent": {},
      "highlightedIndex": {},
      "filteredOptions": {},
      "inputValue": {}
    };
  }
  static get events() {
    return [{
        "method": "ezChange",
        "name": "ezChange",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": "Evento disparado quando o valor do combo box muda."
        },
        "complexType": {
          "original": "IOption",
          "resolved": "IOption",
          "references": {
            "IOption": {
              "location": "import",
              "path": "./interfaces/IOption"
            }
          }
        }
      }, {
        "method": "ezBlur",
        "name": "ezBlur",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": "Evento disparado quando o combo box perde o foco."
        },
        "complexType": {
          "original": "IOption",
          "resolved": "IOption",
          "references": {
            "IOption": {
              "location": "import",
              "path": "./interfaces/IOption"
            }
          }
        }
      }, {
        "method": "iconClick",
        "name": "iconClick",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": "Evento disparado quando o \u00EDcone \u00E9 clicado."
        },
        "complexType": {
          "original": "void",
          "resolved": "void",
          "references": {}
        }
      }, {
        "method": "ezVisibilityChange",
        "name": "ezVisibilityChange",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": "Emitido quando acontece a altera\u00E7\u00E3o de estado do popover."
        },
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "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": "../ez-classic-input/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": []
        }
      },
      "showPopover": {
        "complexType": {
          "signature": "() => Promise<void>",
          "parameters": [],
          "references": {
            "Promise": {
              "location": "global"
            },
            "HTMLElement": {
              "location": "global"
            }
          },
          "return": "Promise<void>"
        },
        "docs": {
          "text": "Exibe o popover abaixo do input.",
          "tags": []
        }
      },
      "hidePopover": {
        "complexType": {
          "signature": "() => Promise<void>",
          "parameters": [],
          "references": {
            "Promise": {
              "location": "global"
            }
          },
          "return": "Promise<void>"
        },
        "docs": {
          "text": "Oculta o popover.",
          "tags": []
        }
      },
      "setValue": {
        "complexType": {
          "signature": "(option: IOption) => Promise<void>",
          "parameters": [{
              "tags": [],
              "text": ""
            }],
          "references": {
            "Promise": {
              "location": "global"
            },
            "IOption": {
              "location": "import",
              "path": "./interfaces/IOption"
            }
          },
          "return": "Promise<void>"
        },
        "docs": {
          "text": "",
          "tags": []
        }
      }
    };
  }
  static get elementRef() { return "_element"; }
  static get watchers() {
    return [{
        "propName": "options",
        "methodName": "optionsChanged"
      }, {
        "propName": "value",
        "methodName": "valueChanged"
      }];
  }
}
