import { Component, Element, Event, h, Listen, Prop, State } from "@stencil/core";
import { modifiersToClass, convertToPlainString, nextSibling, prevSibling, visibilityValidate, firstCapitalice } from '../../utils/utils';
export class IbkDropdown {
  constructor() {
    /** Texto de ayuda dentro del campo seleccionable del dropdown */
    this.placeholder = 'Seleccione';
    /** Se mostrará un mensaje de error */
    this.error = false;
    /** Cuando se encuentra dentro de un "ibk-form" al hacer submit si el dropdown se encuentra vacío, mostrará un mensaje de error */
    this.required = false;
    /** Personaliza el mensaje de campo requerido */
    this.requiredMessage = 'Por favor seleccione una opción';
    /** Se agregará un campo de texto al abrir el dropdown donde se podrá ingresar texto y filtrar entre los elementos del dropdown */
    this.searcher = false;
    /** Se agregará un placeholder personalizado al input de busqueda */
    this.searcherPlaceholder = 'Buscar';
    /** El dropdown no se podrá seleccionar */
    this.disabled = false;
    /** Define si el dropdown no contará con manejo de errores. Se omitirá el espacio generado para el mensaje de error */
    this.noHandlingError = false;
    /** Estado que determina si el dropdown se encuentra abierto */
    this._open = false;
    /** El dispositivo es un móvil */
    this._mobileDevice = false;
    /** Determina si el componente se está ejecutando en un dispositivo móvil */
    this.checkDeviceMobile = () => {
      if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
        this._mobileDevice = true;
      }
    };
    /** Configura la clase del componente basado en estados y modificadores */
    this.containerClass = () => {
      return modifiersToClass('ibk-dropdown', [
        { error: this.error },
        { disabled: this.disabled },
        { open: this._open },
        { 'trigger-round': this.triggerIcon != undefined && this.triggerText == undefined },
        { 'trigger-box': this.triggerText != undefined },
        { 'no-handling-error': this.noHandlingError }
      ]);
    };
    /** Abre o cierra el dropdown dependiendo del estado actual */
    this.dropdownHandler = (e) => {
      e.preventDefault();
      e.stopPropagation();
      // Cerrar otros dropdowns que se encuentren abiertos
      const isOpen = this.host.querySelector('.ibk-dropdown').classList.contains('ibk-dropdown--open');
      if (!isOpen && this._open) {
        this._open = false;
      }
      setTimeout(() => {
        const dropitems = document.querySelectorAll('.ibk-dropdown__dropitems');
        Array.from(dropitems, (item) => {
          const otherContainers = item.closest('.ibk-dropdown');
          otherContainers.classList.remove('ibk-dropdown--open');
        });
        this._open = !this._open;
        if (!this._open) {
          const preselected = this.host.querySelector('ibk-dropdown-item[preselected]:not([preselected="false"])');
          if (preselected != null) {
            preselected.removeAttribute('preselected');
          }
        }
        else {
          setTimeout(() => {
            this.setPreselected();
            const searcher = this.host.querySelector('.ibk-dropdown__searcher-value');
            searcher && searcher.focus();
          }, 10);
        }
      }, 10);
    };
    /** Cierra el dropdown al hacer click fuera del mismo */
    this.bodyClick = () => {
      const body = document.querySelector('body');
      body.addEventListener('click', e => {
        const t = e.target;
        const input = t.closest('.ibk-dropdown__input');
        const closest = t.closest('.ibk-dropdown__value');
        const trigger = t.closest('.ibk-dropdown__trigger');
        const searcher = t.closest('.ibk-dropdown__searcher');
        if (this._open && input == null && closest == null && searcher == null && trigger == null) {
          this._open = false;
          let preselected = this.host.querySelector('ibk-dropdown-item[preselected]:not([preselected="false"])');
          if (preselected != null) {
            preselected.removeAttribute('preselected');
          }
        }
      });
    };
    /** Validar si existe algún item pre seleccionado */
    this.setPreselected = () => {
      let preselected = this.host.querySelector('ibk-dropdown-item[selected]:not([selected="false"])');
      if (preselected != null) {
        this._selectedItem = {
          value: preselected.getAttribute('value'),
          label: preselected.getAttribute('label'),
          cardType: preselected.getAttribute('card-type')
        };
        this.moveScrollToSelection(preselected, 'down');
      }
    };
    /** Escucha el evento al seleccionar algún item del dropdown */
    this.listenSlottedEvents = () => {
      const dropitems = this.host.querySelectorAll('ibk-dropdown-item');
      Array.from(dropitems, item => {
        item.addEventListener('onselect', (e) => {
          this._selectedItem = e.detail;
          Array.from(dropitems, d => {
            if (item != d) {
              d.removeAttribute('selected');
            }
          });
          this.clearSearcher();
          this.host.removeAttribute('error');
          this.onchange.emit(this._selectedItem);
          if (this._grouper != null) {
            this._grouper.removeAttribute('error');
          }
        });
      });
    };
    /** Al escribir en el buscador, filtrará entre las opciones */
    this.searchOption = (e) => {
      const t = e.target;
      const dropitems = this.host.querySelectorAll('ibk-dropdown-item');
      if (t.value != '') {
        this._cleared = true;
        Array.from(dropitems, (item) => {
          const label = item.querySelector('.ibk-dropdown-item__label');
          const plain = convertToPlainString(label.innerHTML);
          if (plain.search(t.value) < 0) {
            item.setAttribute('hidden', '');
          }
          else {
            item.removeAttribute('hidden');
          }
        });
      }
      else {
        this.showAllOptions();
      }
    };
    /** Elimina el contenido del buscador */
    this.clearSearcher = () => {
      const searcher = this.host.querySelector('.ibk-dropdown__searcher-value');
      if (searcher != null) {
        searcher.value = '';
        searcher.focus();
        this.showAllOptions();
      }
    };
    /** Muestra todas las opciones que se ocultaron al filtrar usando el buscador */
    this.showAllOptions = () => {
      const dropitems = this.host.querySelectorAll('ibk-dropdown-item');
      Array.from(dropitems, (item) => {
        item.removeAttribute('hidden');
      });
      this._cleared = false;
    };
    /** Verifica que el item preseleccionado se encuentre dentro del espacio visible del scrollbar */
    this.moveScrollToSelection = (preselected, moveTo) => {
      if (this._open) {
        const list = this.host.querySelector('.ibk-dropdown__dropitems-list');
        const itemHeight = list.querySelector('.ibk-dropdown-item').clientHeight;
        const visible = visibilityValidate(preselected, list);
        if (!visible && moveTo == 'down') {
          list.scrollTo({ top: preselected.offsetTop - (list.clientHeight) });
        }
        else if (!visible && moveTo == 'up') {
          list.scrollTo({ top: preselected.offsetTop - itemHeight });
        }
      }
    };
    /** Elimina la preseleccion al hacer focus en el buscador */
    this.deletePreselected = () => {
      const preselected = this.host.querySelector('ibk-dropdown-item[preselected]:not([preselected="false"])');
      if (preselected != null) {
        preselected.removeAttribute('preselected');
      }
    };
    /** Si el dispositivo es mobile, tomará los "ibk-dropdown-items" y los convertirá en "option" */
    this.mobileOptions = () => {
      const items = this.host.querySelectorAll('ibk-dropdown-item');
      let options = [];
      Array.from(items, (it) => {
        let opt = {
          value: it.getAttribute('value'),
          label: it.getAttribute('label'),
          cardType: it.getAttribute('card-type'),
          selected: it.getAttribute('selected')
        };
        options.push(opt);
        it.remove();
      });
      return options;
    };
  }
  componentDidLoad() {
    this.bodyClick();
    this.listenSlottedEvents();
    this.checkDeviceMobile();
  }
  componentWillLoad() {
    this.setPreselected();
    this._grouper = this.host.closest('ibk-form-group');
  }
  /** Usando las flechas de navegación se preselecciona una opcion */
  optionsNavigate(e) {
    if (this._open) {
      // const dropitems = this.host.querySelectorAll('ibk-dropdown-item')
      let preselected = this.host.querySelector('ibk-dropdown-item[preselected]:not([preselected="false"])');
      const itemsLength = this.host.querySelectorAll('ibk-dropdown-item').length;
      // Flecha hacia abajo
      if (e.keyCode == 40) {
        let nextItem;
        if (preselected == null) {
          nextItem = this.host.querySelector('ibk-dropdown-item');
          nextItem = nextItem.matches('[hidden]') ? this.host.querySelector('ibk-dropdown-item:not([hidden])') : nextItem;
        }
        else {
          preselected.removeAttribute('preselected');
          nextItem = nextSibling(preselected, ':not([hidden])');
        }
        if (nextItem == null || nextItem == undefined) {
          nextItem = this.host.querySelector('ibk-dropdown-item:not([hidden])');
        }
        nextItem.setAttribute('preselected', '');
        this.moveScrollToSelection(nextItem, 'down');
      }
      // Flecha hacia arriba
      else if (e.keyCode == 38) {
        let prevItem;
        if (preselected == null) {
          prevItem = this.host.querySelectorAll('ibk-dropdown-item')[itemsLength - 1];
          prevItem = prevItem.matches('[hidden]') ? this.host.querySelectorAll('ibk-dropdown-item:not([hidden])')[itemsLength - 1] : prevItem;
        }
        else {
          preselected.removeAttribute('preselected');
          prevItem = prevSibling(preselected, ':not([hidden])');
        }
        if (prevItem == null || prevItem.classList.contains('ibk-dropdown__searcher')) {
          prevItem = this.host.querySelectorAll('ibk-dropdown-item')[itemsLength - 1];
        }
        prevItem.setAttribute('preselected', '');
        this.moveScrollToSelection(prevItem, 'up');
      }
      // Tecla enter
      else if (e.keyCode == 13) {
        this._selectedItem = {
          value: preselected.getAttribute('value'),
          label: preselected.getAttribute('label'),
          cardType: preselected.getAttribute('card-type')
        };
        const oldSelected = this.host.querySelector('[selected]');
        if (oldSelected != null) {
          oldSelected.removeAttribute('selected');
        }
        const newSelected = this.host.querySelector(`[value="${preselected.getAttribute('value')}"]`);
        newSelected.setAttribute('selected', '');
        this.clearSearcher();
        this.host.removeAttribute('error');
        this._open = false;
        this.onchange.emit(this._selectedItem);
        if (this._grouper != null) {
          this._grouper.removeAttribute('error');
        }
      }
      // Tecla Esc
      else if (e.keyCode == 27) {
        this.clearSearcher();
        this._open = false;
      }
    }
  }
  render() {
    var _a, _b, _c;
    if (!this._mobileDevice) {
      return (h("div", { class: this.containerClass(), style: { width: this.width + 'px' } },
        this.label && h("span", { class: "ibk-dropdown__label", innerHTML: this.label }),
        this.subtitle && h("span", { class: "ibk-dropdown__subtitle", innerHTML: this.subtitle }),
        (this.triggerIcon == undefined && this.triggerText == undefined) ?
          h("label", { class: "ibk-dropdown__input", onClick: this.dropdownHandler },
            h("input", { type: "hidden", value: (_a = this._selectedItem) === null || _a === void 0 ? void 0 : _a.value }),
            ((_b = this._selectedItem) === null || _b === void 0 ? void 0 : _b.cardType) && h("img", { class: "ibk-dropdown__card-image", src: `../assets/images/${this._selectedItem.cardType}.png`, alt: this._selectedItem.cardType }),
            h("input", { class: "ibk-dropdown__value", type: "text", value: (_c = this._selectedItem) === null || _c === void 0 ? void 0 : _c.label, placeholder: this.placeholder, readOnly: true }),
            h("i", { class: "ibk-dropdown__icon-down icon-xs-arrow-down" })) :
          h("button", { type: "button", class: "ibk-dropdown__trigger", onClick: this.dropdownHandler },
            this.triggerIcon && h("i", { style: { color: this.triggerIconColor }, class: 'ibk-dropdown__trigger-icon ' + this.triggerIcon }),
            this.triggerText && h("span", { class: 'ibk-dropdown__trigger-text' + (this.triggerIcon && this.triggerText && ' ibk-dropdown__trigger-space'), innerHTML: this.triggerText })),
        (this.triggerIcon == undefined && this.triggerText == undefined && !this.noHandlingError) && h("span", { class: "ibk-dropdown__error-message", innerHTML: this.error ? this.requiredMessage : '' }),
        h("div", { class: "ibk-dropdown__dropitems" },
          this.searcher &&
            h("div", { class: "ibk-dropdown__searcher" },
              h("i", { class: "ibk-dropdown__searcher-icon icon-m-search" }),
              h("input", { class: "ibk-dropdown__searcher-value", type: "text", placeholder: this.searcherPlaceholder, onInput: this.searchOption, onFocus: this.deletePreselected }),
              this._cleared && h("i", { onClick: this.clearSearcher, class: "ibk-dropdown__searcher-erase icon-m-status-error" })),
          h("ul", { class: "ibk-dropdown__dropitems-list" },
            h("slot", null)))));
    }
    else {
      return (h("div", { class: this.containerClass() },
        this.label && h("span", { class: "ibk-dropdown__label", innerHTML: this.label }),
        this.subtitle && h("span", { class: "ibk-dropdown__subtitle", innerHTML: this.subtitle }),
        h("div", { class: "ibk-dropdown__mobile" },
          h("select", { class: "ibk-dropdown__select" },
            h("slot", null),
            this.placeholder && h("option", { disabled: true, selected: true, value: "-1" }, this.placeholder),
            Array.from(this.mobileOptions(), (option) => {
              return (h("option", { class: "ibk-dropdown__select-option", value: option.value, selected: option.selected != null ? true : null },
                option.cardType != null ? `${firstCapitalice(option.cardType)} - ` : '',
                option.label));
            })),
          h("i", { class: "ibk-dropdown__icon-down icon-xs-arrow-down" })),
        h("span", { class: "ibk-dropdown__error-message", innerHTML: this.error ? this.requiredMessage : '' })));
    }
  }
  static get is() { return "ibk-dropdown"; }
  static get originalStyleUrls() { return {
    "$": ["dropdown.css"]
  }; }
  static get styleUrls() { return {
    "$": ["dropdown.css"]
  }; }
  static get properties() { return {
    "label": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Texto de ayuda encima del dropdown"
      },
      "attribute": "label",
      "reflect": false
    },
    "subtitle": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Se incluye el subtitulo entre el label (si existiera) y el dropdown"
      },
      "attribute": "subtitle",
      "reflect": false
    },
    "placeholder": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Texto de ayuda dentro del campo seleccionable del dropdown"
      },
      "attribute": "placeholder",
      "reflect": false,
      "defaultValue": "'Seleccione'"
    },
    "error": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Se mostrar\u00E1 un mensaje de error"
      },
      "attribute": "error",
      "reflect": false,
      "defaultValue": "false"
    },
    "required": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Cuando se encuentra dentro de un \"ibk-form\" al hacer submit si el dropdown se encuentra vac\u00EDo, mostrar\u00E1 un mensaje de error"
      },
      "attribute": "required",
      "reflect": false,
      "defaultValue": "false"
    },
    "requiredMessage": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Personaliza el mensaje de campo requerido"
      },
      "attribute": "required-message",
      "reflect": false,
      "defaultValue": "'Por favor seleccione una opci\u00F3n'"
    },
    "searcher": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Se agregar\u00E1 un campo de texto al abrir el dropdown donde se podr\u00E1 ingresar texto y filtrar entre los elementos del dropdown"
      },
      "attribute": "searcher",
      "reflect": false,
      "defaultValue": "false"
    },
    "searcherPlaceholder": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Se agregar\u00E1 un placeholder personalizado al input de busqueda"
      },
      "attribute": "searcher-placeholder",
      "reflect": false,
      "defaultValue": "'Buscar'"
    },
    "disabled": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "El dropdown no se podr\u00E1 seleccionar"
      },
      "attribute": "disabled",
      "reflect": false,
      "defaultValue": "false"
    },
    "triggerIcon": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "El bot\u00F3n que desplegar\u00E1 el dropdown ser\u00E1 el \u00EDcono especificado, se puede combinar con un texto"
      },
      "attribute": "trigger-icon",
      "reflect": false
    },
    "triggerIconColor": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Define el color del \u00EDcono especificado"
      },
      "attribute": "trigger-icon-color",
      "reflect": false
    },
    "triggerText": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "El bot\u00F3n que desplegar\u00E1 el dropdown ser\u00E1 un texto, se puede combinar con un \u00EDcono"
      },
      "attribute": "trigger-text",
      "reflect": false
    },
    "triggerTextColor": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Define el color del texto especificado"
      },
      "attribute": "trigger-text-color",
      "reflect": false
    },
    "keepMarked": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Define si al seleccionar un item de la lista, este se mantendr\u00E1 marcado"
      },
      "attribute": "keep-marked",
      "reflect": false
    },
    "width": {
      "type": "number",
      "mutable": false,
      "complexType": {
        "original": "number",
        "resolved": "number",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Define un ancho fijo para el dropdown"
      },
      "attribute": "width",
      "reflect": false
    },
    "noHandlingError": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Define si el dropdown no contar\u00E1 con manejo de errores. Se omitir\u00E1 el espacio generado para el mensaje de error"
      },
      "attribute": "no-handling-error",
      "reflect": false,
      "defaultValue": "false"
    }
  }; }
  static get states() { return {
    "_open": {},
    "_selectedItem": {},
    "_cleared": {},
    "_mobileDevice": {},
    "_grouper": {}
  }; }
  static get events() { return [{
      "method": "onchange",
      "name": "onchange",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": "Emite un evento cuando se selecciona un item y lo env\u00EDa como par\u00E1metro"
      },
      "complexType": {
        "original": "DropdownItem",
        "resolved": "DropdownItem",
        "references": {
          "DropdownItem": {
            "location": "import",
            "path": "../dropdown-item/dropdown-item"
          }
        }
      }
    }]; }
  static get elementRef() { return "host"; }
  static get listeners() { return [{
      "name": "keydown",
      "method": "optionsNavigate",
      "target": undefined,
      "capture": false,
      "passive": false
    }]; }
}
