import { h } from "@stencil/core";
import { ElementIDUtils } from "@sankhyalabs/core";
import initI18n from '../../../utils/i18n';
export class EzComboBoxList {
  constructor() {
    this.showLoading = undefined;
    this.visibleOptions = undefined;
    this.textEmptyList = undefined;
    this.showOptionValue = undefined;
    this.preSelection = undefined;
    this.maxWidth = undefined;
    this.width = undefined;
    this.onOptionSelect = undefined;
    this.onOptionHover = undefined;
  }
  /**
   * Move a seleção para a próxima opção na lista.
   */
  async nextOption() {
    var _a, _b;
    if (!((_a = this.visibleOptions) === null || _a === void 0 ? void 0 : _a.length))
      return;
    const isAtLastOption = this.preSelection !== undefined && this.preSelection >= this.visibleOptions.length - 1;
    if (!isAtLastOption) {
      this.preSelection = this.preSelection === undefined ? 0 : this.preSelection + 1;
      this.scrollToOption(this.visibleOptions[this.preSelection]);
      (_b = this.onOptionHover) === null || _b === void 0 ? void 0 : _b.call(this, this.preSelection);
    }
  }
  /**
   * Move a seleção para a opção anterior na lista, sem ultrapassar o início.
   */
  async previousOption() {
    var _a, _b;
    if (!((_a = this.visibleOptions) === null || _a === void 0 ? void 0 : _a.length))
      return;
    const isAtFirstOption = this.preSelection !== undefined && this.preSelection <= 0;
    if (!isAtFirstOption) {
      this.preSelection = this.preSelection === undefined ? this.visibleOptions.length - 1 : this.preSelection - 1;
      this.scrollToOption(this.visibleOptions[this.preSelection]);
      (_b = this.onOptionHover) === null || _b === void 0 ? void 0 : _b.call(this, this.preSelection);
    }
  }
  /**
   * Seleciona a opção atualmente pré-selecionada.
   */
  async selectCurrentOption() {
    if (this.preSelection !== undefined) {
      this.onOptionSelect(this.visibleOptions[this.preSelection]);
      this.preSelection = undefined;
    }
  }
  /**
   * Observa mudanças na propriedade `width` e ajusta a largura da lista.
   *
   * @param newValue O novo valor da largura.
   * @param oldValue O valor anterior da largura.
   */
  observeWidth(newValue, oldValue) {
    if (newValue === oldValue)
      return;
    if (!this._listWrapper)
      return;
    this._listWrapper.style.width = `${this.width}px`;
  }
  /**
   * Observa mudanças na propriedade `maxWidth` e ajusta a largura máxima da lista.
   *
   * @param newValue O novo valor da largura máxima.
   * @param oldValue O valor anterior da largura máxima.
   */
  observeMaxWidth(newValue, oldValue) {
    if (newValue === oldValue)
      return;
    if (!this._listWrapper)
      return;
    this._listWrapper.style.maxWidth = this.maxWidth ? `${this.maxWidth}px` : '';
  }
  /**
   * Gerencia a navegação por teclado na lista do combo box.
   *
   * - `ArrowDown`: Move para a próxima opção.
   * - `ArrowUp`: Move para a opção anterior.
   * - `Enter`: Seleciona a opção atual.
   * - `Escape`: Limpa a pré-seleção.
   *
   * @param event O evento de teclado.
   */
  handleKeyDown(event) {
    switch (event.key) {
      case "ArrowDown":
        event.preventDefault();
        event.stopPropagation();
        this.nextOption();
        break;
      case "ArrowUp":
        event.preventDefault();
        event.stopPropagation();
        this.previousOption();
        break;
      case "Enter":
        this.selectCurrentOption();
        break;
      case "Escape":
        this.preSelection = undefined;
        break;
    }
  }
  buildItem(opt, index) {
    const widthValue = this.showOptionValue && this.maxWidth > 0 ? `${this.maxWidth}px` : '';
    opt.label = opt.label || opt.value;
    return h("li", { tabIndex: 1, class: index === this.preSelection ? "item preselected" : "item", id: `item_${opt.value}_${index}`, key: `item_${opt.value}_${index}`, onMouseDown: () => this.onOptionSelect(opt), onMouseOver: () => this.preSelection = index }, this.showOptionValue
      ? h("span", { class: "item__value", title: opt.value, style: { width: widthValue, minWidth: widthValue, maxWidth: widthValue } }, opt.value)
      : undefined, h("span", { class: "item__label " + (this.showOptionValue ? "item__label--bold" : ""), title: opt.label }, opt.label));
  }
  scrollToOption(opt) {
    if (!(opt === null || opt === void 0 ? void 0 : opt.value) || !this._optionsList)
      return;
    const index = this.visibleOptions.indexOf(opt);
    if (index === -1)
      return;
    const liElem = this._optionsList.querySelector(`li#item_${CSS.escape(opt.value)}_${CSS.escape(String(index))}`);
    if (liElem) {
      liElem.scrollIntoView({
        behavior: "smooth",
        block: "nearest"
      });
    }
  }
  async componentWillLoad() {
    this.i18n = await initI18n();
  }
  componentDidLoad() {
    this._listWrapper.style.width = `${this.width}px`;
    this._listWrapper.style.maxWidth = this.maxWidth ? `${this.maxWidth}px` : '';
  }
  componentDidRender() {
    var _a;
    (_a = this._optionsList) === null || _a === void 0 ? void 0 : _a.querySelectorAll(".item").forEach((elem) => {
      ElementIDUtils.addIDInfoIfNotExists(elem, "itemComboBox");
    });
  }
  render() {
    return (h("section", { class: "list-container" }, h("div", { class: "list-wrapper", ref: elem => this._listWrapper = elem }, h("ul", { class: "list-options", ref: elem => this._optionsList = elem }, !this.showLoading && this.visibleOptions.length === 0 && (h("div", { class: "message" }, h("span", { class: "message__no-result" }, this.textEmptyList || this.i18n("ez-combo-box.noResults")))), this.showLoading && (h("div", { class: "message" }, h("div", { class: "message__loading" }))), this.showOptionValue && (h("span", { class: "item__value item__value--hidden" })), !this.showLoading && this.visibleOptions.length > 0 &&
      this.visibleOptions.map((opt, index) => this.buildItem(opt, index))))));
  }
  static get is() { return "ez-combo-box-list"; }
  static get encapsulation() { return "shadow"; }
  static get originalStyleUrls() {
    return {
      "$": ["ez-combo-box-list.css"]
    };
  }
  static get styleUrls() {
    return {
      "$": ["ez-combo-box-list.css"]
    };
  }
  static get properties() {
    return {
      "showLoading": {
        "type": "boolean",
        "mutable": false,
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [{
              "name": "tipo",
              "text": "{boolean}"
            }],
          "text": "Indica se o indicador de carregamento deve ser exibido."
        },
        "attribute": "show-loading",
        "reflect": false
      },
      "visibleOptions": {
        "type": "unknown",
        "mutable": false,
        "complexType": {
          "original": "Array<IOption>",
          "resolved": "IOption[]",
          "references": {
            "Array": {
              "location": "global"
            },
            "IOption": {
              "location": "import",
              "path": "../ez-combo-box"
            }
          }
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [{
              "name": "tipo",
              "text": "{Array<IOption>}"
            }],
          "text": "Lista de op\u00E7\u00F5es vis\u00EDveis que ser\u00E3o exibidas no componente."
        }
      },
      "textEmptyList": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [{
              "name": "padr\u00E3o",
              "text": "\"Nenhum resultado encontrado\""
            }, {
              "name": "tipo",
              "text": "{string}"
            }],
          "text": "Mensagem exibida quando a lista de op\u00E7\u00F5es est\u00E1 vazia."
        },
        "attribute": "text-empty-list",
        "reflect": false
      },
      "showOptionValue": {
        "type": "boolean",
        "mutable": false,
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [{
              "name": "tipo",
              "text": "{boolean}"
            }],
          "text": "Indica se o valor de cada op\u00E7\u00E3o deve ser exibido junto com o r\u00F3tulo."
        },
        "attribute": "show-option-value",
        "reflect": false
      },
      "preSelection": {
        "type": "number",
        "mutable": false,
        "complexType": {
          "original": "number",
          "resolved": "number",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [{
              "name": "tipo",
              "text": "{number}"
            }],
          "text": "\u00CDndice da op\u00E7\u00E3o pr\u00E9-selecionada na lista."
        },
        "attribute": "pre-selection",
        "reflect": false
      },
      "maxWidth": {
        "type": "number",
        "mutable": false,
        "complexType": {
          "original": "number",
          "resolved": "number",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [{
              "name": "tipo",
              "text": "{number}"
            }],
          "text": "Largura m\u00E1xima da lista, em pixels."
        },
        "attribute": "max-width",
        "reflect": false
      },
      "width": {
        "type": "number",
        "mutable": false,
        "complexType": {
          "original": "number",
          "resolved": "number",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [{
              "name": "tipo",
              "text": "{number}"
            }],
          "text": "Largura fixa da lista, em pixels."
        },
        "attribute": "width",
        "reflect": false
      },
      "onOptionSelect": {
        "type": "unknown",
        "mutable": false,
        "complexType": {
          "original": "(option: IOption) => void",
          "resolved": "(option: IOption) => void",
          "references": {
            "IOption": {
              "location": "import",
              "path": "../ez-combo-box"
            }
          }
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [{
              "name": "param",
              "text": "option A op\u00E7\u00E3o selecionada."
            }, {
              "name": "tipo",
              "text": "{(option: IOption) => void}"
            }],
          "text": "Callback chamado quando uma op\u00E7\u00E3o \u00E9 selecionada."
        }
      },
      "onOptionHover": {
        "type": "unknown",
        "mutable": false,
        "complexType": {
          "original": "(index: number) => void",
          "resolved": "(index: number) => void",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [{
              "name": "param",
              "text": "index O \u00EDndice da op\u00E7\u00E3o em foco."
            }, {
              "name": "tipo",
              "text": "{(index: number) => void}"
            }],
          "text": "Callback chamado quando o mouse passa sobre uma op\u00E7\u00E3o."
        }
      }
    };
  }
  static get methods() {
    return {
      "nextOption": {
        "complexType": {
          "signature": "() => Promise<void>",
          "parameters": [],
          "references": {
            "Promise": {
              "location": "global"
            }
          },
          "return": "Promise<void>"
        },
        "docs": {
          "text": "Move a sele\u00E7\u00E3o para a pr\u00F3xima op\u00E7\u00E3o na lista.",
          "tags": []
        }
      },
      "previousOption": {
        "complexType": {
          "signature": "() => Promise<void>",
          "parameters": [],
          "references": {
            "Promise": {
              "location": "global"
            }
          },
          "return": "Promise<void>"
        },
        "docs": {
          "text": "Move a sele\u00E7\u00E3o para a op\u00E7\u00E3o anterior na lista, sem ultrapassar o in\u00EDcio.",
          "tags": []
        }
      },
      "selectCurrentOption": {
        "complexType": {
          "signature": "() => Promise<void>",
          "parameters": [],
          "references": {
            "Promise": {
              "location": "global"
            }
          },
          "return": "Promise<void>"
        },
        "docs": {
          "text": "Seleciona a op\u00E7\u00E3o atualmente pr\u00E9-selecionada.",
          "tags": []
        }
      }
    };
  }
  static get watchers() {
    return [{
        "propName": "width",
        "methodName": "observeWidth"
      }, {
        "propName": "maxWidth",
        "methodName": "observeMaxWidth"
      }];
  }
  static get listeners() {
    return [{
        "name": "keydown",
        "method": "handleKeyDown",
        "target": undefined,
        "capture": false,
        "passive": false
      }];
  }
}
