import { Component, Element, Event, h, Prop } from "@stencil/core";
import { modifiersToClass, regexValidators } from '../../utils/utils';
export class IbkTable {
  constructor() {
    /** Se eliminará el estilo por defecto de la primera fila */
    this.notHeading = false;
    /** Agregará una columna al inicio con un botón para selección  */
    this.selectable = false;
    /** Define si se mostrará una numeración por cada fila */
    this.enumerate = false;
    /** Define cuantas filas se mostrarán por página */
    this.rowsPerPage = 5;
    /** Define la página actual del paginador */
    this.currentPage = 1;
    /** Define si se mostrará un resumen de filas en la parte inferior */
    this.showInfo = false;
    /** Define si se mostrará el selector de filas */
    this.rowsSelector = false;
    /** Define los rangos que se podrán seleccionar en el selector de filas
     * Se ingresará como valor números separados por comas
     * Si se desea que el la última opción sea mostrar todas las filas se colocará "all", por ejm: "5,10,all"
     */
    this.rowsToShow = "5,10,15,20,all";
    /** Especifica si la columna a ordenar tiene un tipo de dato concreto
     * Los valores pueden ser 'text', 'date' o 'number'
     * Por defecto se ordenará con el tipo texto
     * Si el tipo es date, la fecha deberá estar en formato dd/mm/yyyy
     */
    this.sortDataType = 'text';
    /** Almacena los índices seleccionados de la tabla */
    this._tempIndexes = new Array();
    /** Almacenará toda la información de la tabla */
    this._tableInfo = new Array();
    /** Almacenará la información a mostrar en la tabla (página actual) */
    this._currentTableInfo = new Array();
    /** Configura la clase del componente basado en estados y modificadores */
    this.containerClass = () => {
      return modifiersToClass('ibk-table', [
        { selectable: this.selectable },
        { enumerate: this.enumerate }
      ]);
    };
    /** A partir de la tabla creada por el usuario, se creará un objeto con la información de la tabla */
    this.createObjectFromHtml = () => {
      const table = this.host.querySelector('table');
      const rows = table.querySelectorAll('tr');
      rows.forEach((row, index) => {
        const rowInfo = {};
        const cells = row.querySelectorAll('th, td');
        if (this.columnOfId) {
          rowInfo.id = (!this.notHeading && index > 0 || this.notHeading) ? cells[this.columnOfId - 1].innerHTML : 0;
        }
        else {
          rowInfo.id = !this.notHeading ? index : (index + 1);
        }
        rowInfo.cells = [];
        if (this.enumerate) {
          if (!this.notHeading) {
            rowInfo.cells.push(index > 0 ? index.toString() : '');
          }
          else {
            rowInfo.cells.push((index + 1).toString());
          }
        }
        if (this.selectable) {
          const checkboxNode = document.createElement('ibk-checkbox');
          checkboxNode.setAttribute('value', rowInfo.id);
          checkboxNode.setAttribute('icon-only', '');
          checkboxNode.classList.add('ibk-table__selector');
          rowInfo.cells.push(checkboxNode.outerHTML);
        }
        cells.forEach((cell) => {
          rowInfo.cells.push(cell.innerHTML.trim());
        });
        if (this.actions) {
          if (!this.notHeading && index == 0) {
            rowInfo.cells.push('<th class="ibk-table__cell">Acciones</th>');
          }
          if (!this.notHeading && index > 0 || this.notHeading) {
            rowInfo.cells.push(this.addActions(rowInfo.id));
          }
        }
        this._tableInfo.push(rowInfo);
      });
      this.sortData();
    };
    this.drawTable = () => {
      const table = this.host.querySelector('table');
      table.innerHTML = '';
      table.classList.add('ibk-table__container');
      if (this.paginator) {
        const start = !this.notHeading ? (this.currentPage * this.rowsPerPage) - this.rowsPerPage + 1 : (this.currentPage * this.rowsPerPage) - this.rowsPerPage;
        const end = !this.notHeading ? (this.currentPage * this.rowsPerPage) + 1 : (this.currentPage * this.rowsPerPage);
        this._currentTableInfo = this._tableInfo.slice(start, end);
        !this.notHeading && this._currentTableInfo.unshift(this._tableInfo[0]);
      }
      else {
        this._currentTableInfo = this._tableInfo;
      }
      this._currentTableInfo.forEach((rows, index) => {
        const rowNode = document.createElement('tr');
        rowNode.classList.add('ibk-table__row');
        !this.notHeading && index == 0 && rowNode.classList.add('ibk-table__row--heading');
        rows.cells.forEach((cell, i) => {
          const cellNode = document.createElement((!this.notHeading && index == 0) ? 'th' : 'td');
          cellNode.innerHTML = cell;
          cellNode.classList.add('ibk-table__cell');
          if (!this.notHeading && i == rows.cells.length - 1) {
            cellNode.classList.add('ibk-table__cell-actions');
          }
          rowNode.appendChild(cellNode);
        });
        table.appendChild(rowNode);
      });
      this.selectRow();
      this.emitAction();
    };
    /** Función que se ejecuta al seleccionar alguna fila de la tabla */
    this.selectRow = () => {
      const checkboxes = this.host.querySelectorAll('ibk-checkbox');
      checkboxes.forEach((check) => {
        check.addEventListener('onchecked', (e) => {
          if (!this.notHeading && e.detail.value == '0') {
            this._tempIndexes = new Array();
            const rows = this.host.querySelectorAll('.ibk-table__row');
            rows.forEach((row, index) => {
              if (e.detail.checked) {
                if (index != 0) {
                  const id = row.querySelector('.ibk-table__selector').getAttribute('value');
                  this._tempIndexes.push(id);
                  row.querySelector('.ibk-table__selector').setAttribute('checked', '');
                }
              }
              else {
                row.querySelector('.ibk-table__selector').removeAttribute('checked');
              }
            });
          }
          else if ((e.detail.value == '0' && this.notHeading) || e.detail.value != '0') {
            if (!this.notHeading) {
              checkboxes[0].removeAttribute('checked');
            }
            if (e.detail.checked) {
              this._tempIndexes.push(e.detail.value);
            }
            else {
              const idx = this._tempIndexes.indexOf(e.detail.value);
              this._tempIndexes.splice(idx, 1);
            }
          }
          this.onselect.emit(this._tempIndexes);
        });
      });
    };
    /** Configuración del paginador */
    this.configPaginator = () => {
      if (!this._pages) {
        const bodyTable = !this.notHeading ? this._tableInfo.length - 1 : this._tableInfo.length;
        this._pages = Math.ceil(bodyTable / this.rowsPerPage);
      }
      if (this.currentPage >= this._pages) {
        this.currentPage = this._pages;
      }
      else if (this.currentPage < 1) {
        this.currentPage = 1;
      }
    };
    /** Función que maneja el avance o retroceso de las páginas */
    this.handlerPaginator = (action) => {
      if (action == 'next') {
        this.currentPage++;
      }
      else {
        this.currentPage--;
      }
      const start = !this.notHeading ? (this.currentPage * this.rowsPerPage) - this.rowsPerPage + 1 : (this.currentPage * this.rowsPerPage) - this.rowsPerPage;
      const end = !this.notHeading ? (this.currentPage * this.rowsPerPage) + 1 : (this.currentPage * this.rowsPerPage);
      this._currentTableInfo = new Array();
      this._currentTableInfo = this._tableInfo.slice(start, end);
      !this.notHeading && this._currentTableInfo.unshift(this._tableInfo[0]);
      this.drawTable();
    };
    /** Validar que se ingrese un número en el campo de texto del paginador */
    this.validateEntryPage = e => {
      if (!regexValidators.number.test(e.key) && (e.keyCode != 8 && e.keyCode != 9) && !(e.keyCode >= 37 && e.keyCode <= 40)) {
        e.preventDefault();
      }
    };
    /** Función que se ejecuta al escribir manualmente la página */
    this.editPage = e => {
      const t = e.target;
      const newPage = t.value;
      if (newPage < 1) {
        this.currentPage = 1;
      }
      else if (newPage > this._pages) {
        this.currentPage = this._pages;
      }
      else {
        this.currentPage = newPage;
      }
      const field = this.host.querySelector('.ibk-table__page-total');
      field.value = this.currentPage.toString();
      this.drawTable();
    };
    this.setRowsDropdown = () => {
      setTimeout(() => {
        const dropdown = this.host.querySelector('.ibk-table__rows-dropdown');
        this.rowsToShow.split(',').forEach((number, index) => {
          const child = document.createElement('ibk-dropdown-item');
          child.setAttribute('value', number == 'all' ? this._tableInfo.length.toString() : number);
          child.setAttribute('label', number == 'all' ? 'Todos' : number);
          index == 0 && child.setAttribute('selected', '');
          dropdown.appendChild(child);
        });
        dropdown.addEventListener('onchange', (e) => {
          this.rowsPerPage = parseInt(e.detail.value);
          const bodyTable = !this.notHeading ? this._tableInfo.length - 1 : this._tableInfo.length;
          this._pages = Math.ceil(bodyTable / this.rowsPerPage);
          this.drawTable();
        });
      }, 10);
    };
    /** Función que ordena las filas de la tabla dependiendo del dato enviado en el parámetro sort */
    this.sortData = () => {
      if (this.sort) {
        const tempTable = this._tableInfo.slice();
        const firstRow = !this.notHeading ? tempTable.shift() : null;
        const sortData = {
          id: parseInt(this.sort.split(',')[0]),
          type: this.sort.split(',')[1]
        };
        if (this.selectable && this.enumerate) {
          sortData.id++;
        }
        else if ((!this.selectable && this.enumerate) || (this.selectable && !this.enumerate)) {
          sortData.id;
        }
        else if (!this.selectable && !this.enumerate) {
          sortData.id--;
        }
        tempTable.sort((a, b) => {
          let compare1, compare2;
          if (this.sortDataType == 'text') {
            compare1 = a.cells[sortData.id].toLowerCase();
            compare2 = b.cells[sortData.id].toLowerCase();
          }
          else if (this.sortDataType == 'number') {
            compare1 = parseInt(a.cells[sortData.id]);
            compare2 = parseInt(b.cells[sortData.id]);
          }
          else if (this.sortDataType == 'date') {
            let dateA = a.cells[sortData.id].split('/');
            let dateB = b.cells[sortData.id].split('/');
            compare1 = new Date(dateA[2], dateA[1], dateA[0]);
            compare2 = new Date(dateB[2], dateB[1], dateB[0]);
          }
          if (sortData.type == 'asc') {
            return compare1 <= compare2 ? -1 : 1;
          }
          else {
            return compare1 > compare2 ? -1 : 1;
          }
        });
        this._tableInfo = tempTable;
        !this.notHeading && this._tableInfo.unshift(firstRow);
      }
    };
    /** Función que agrega la columna de acciones dependiendo del dato enviado en el parámetro actions */
    this.addActions = (id) => {
      if (this.actions) {
        const actions = this.actions.split(',');
        let htmlActions = '';
        actions.forEach((action) => {
          const actionNode = document.createElement('i');
          actionNode.classList.add('ibk-table__action');
          actionNode.setAttribute('data-id', id);
          actionNode.setAttribute('data-action', action);
          if (action == 'detail') {
            actionNode.classList.add('icon-m-eye-on', 'ibk-table__action--detail');
          }
          else if (action == 'edit') {
            actionNode.classList.add('icon-m-edit', 'ibk-table__action--edit');
          }
          else if (action == 'delete') {
            actionNode.classList.add('icon-m-trash', 'ibk-table__action--delete');
          }
          htmlActions += actionNode.outerHTML;
        });
        return htmlActions;
      }
    };
    this.emitAction = () => {
      const actions = this.host.querySelectorAll('.ibk-table__action');
      actions.forEach((action) => {
        action.addEventListener('click', e => {
          const t = e.target;
          const action = t.getAttribute('data-action');
          const id = t.getAttribute('data-id');
          if (action == 'detail') {
            this.ondetail.emit(id);
          }
          else if (action == 'edit') {
            this.onedit.emit(id);
          }
          else if (action == 'delete') {
            this.ondelete.emit(id);
          }
        });
      });
    };
    /** Función que filtrará la información de la tabla basado en el valor de la propiedad filteredText */
    this.setFilteredText = () => {
    };
  }
  componentWillLoad() {
    this.createObjectFromHtml();
    this.drawTable();
    this.configPaginator();
    this.setRowsDropdown();
  }
  render() {
    return (h("div", { class: this.containerClass() },
      h("div", { class: "ibk-table__body" },
        h("slot", null)),
      this.paginator &&
        h("div", { class: "ibk-table__footer" },
          this.rowsSelector &&
            h("div", { class: "ibk-table__rows-selector" },
              h("ibk-dropdown", { class: "ibk-table__rows-dropdown", "no-handling-error": true }),
              h("span", null, "\u00F3rdenes por p\u00E1gina")),
          this.showInfo &&
            h("div", { class: "ibk-table__showing" },
              h("span", null,
                "Mostrando",
                h("strong", null,
                  " ",
                  (this.currentPage * this.rowsPerPage) - this.rowsPerPage + 1,
                  " - ",
                  (this.currentPage * this.rowsPerPage > this._tableInfo.length ? this._tableInfo.length : this.currentPage * this.rowsPerPage)),
                " de",
                h("strong", null,
                  " ",
                  !this.notHeading ? this._tableInfo.length - 1 : this._tableInfo.length,
                  " "),
                "\u00F3rdenes")),
          h("div", { class: "ibk-table__paginator" },
            h("i", { class: "ibk-table__page-prev icon-xs-arrow-left" + (this.currentPage == 1 ? ' ibk-table__page-prev--disabled' : ''), onClick: () => this.handlerPaginator('prev') }),
            h("input", { class: "ibk-table__page-current", type: "text", value: this.currentPage, onKeyDown: this.validateEntryPage, onInput: this.editPage }),
            h("span", { class: "ibk-table__page-total" },
              "de ",
              h("strong", null, this._pages)),
            h("i", { class: "ibk-table__page-next icon-xs-arrow-right" + (this.currentPage == this._pages ? ' ibk-table__page-next--disabled' : ''), onClick: () => this.handlerPaginator('next') })))));
  }
  static get is() { return "ibk-table"; }
  static get originalStyleUrls() { return {
    "$": ["table.css"]
  }; }
  static get styleUrls() { return {
    "$": ["table.css"]
  }; }
  static get properties() { return {
    "notHeading": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Se eliminar\u00E1 el estilo por defecto de la primera fila"
      },
      "attribute": "not-heading",
      "reflect": false,
      "defaultValue": "false"
    },
    "selectable": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Agregar\u00E1 una columna al inicio con un bot\u00F3n para selecci\u00F3n"
      },
      "attribute": "selectable",
      "reflect": false,
      "defaultValue": "false"
    },
    "enumerate": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Define si se mostrar\u00E1 una numeraci\u00F3n por cada fila"
      },
      "attribute": "enumerate",
      "reflect": false,
      "defaultValue": "false"
    },
    "columnOfId": {
      "type": "number",
      "mutable": false,
      "complexType": {
        "original": "number",
        "resolved": "number",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Define la columna que contiene el identificador de cada fila"
      },
      "attribute": "column-of-id",
      "reflect": false
    },
    "paginator": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Define si la tabla tendr\u00E1 paginaci\u00F3n"
      },
      "attribute": "paginator",
      "reflect": false
    },
    "rowsPerPage": {
      "type": "number",
      "mutable": false,
      "complexType": {
        "original": "number",
        "resolved": "number",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Define cuantas filas se mostrar\u00E1n por p\u00E1gina"
      },
      "attribute": "rows-per-page",
      "reflect": false,
      "defaultValue": "5"
    },
    "currentPage": {
      "type": "number",
      "mutable": false,
      "complexType": {
        "original": "number",
        "resolved": "number",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Define la p\u00E1gina actual del paginador"
      },
      "attribute": "current-page",
      "reflect": false,
      "defaultValue": "1"
    },
    "showInfo": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Define si se mostrar\u00E1 un resumen de filas en la parte inferior"
      },
      "attribute": "show-info",
      "reflect": false,
      "defaultValue": "false"
    },
    "rowsSelector": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Define si se mostrar\u00E1 el selector de filas"
      },
      "attribute": "rows-selector",
      "reflect": false,
      "defaultValue": "false"
    },
    "rowsToShow": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Define los rangos que se podr\u00E1n seleccionar en el selector de filas\r\nSe ingresar\u00E1 como valor n\u00FAmeros separados por comas\r\nSi se desea que el la \u00FAltima opci\u00F3n sea mostrar todas las filas se colocar\u00E1 \"all\", por ejm: \"5,10,all\""
      },
      "attribute": "rows-to-show",
      "reflect": false,
      "defaultValue": "\"5,10,15,20,all\""
    },
    "sort": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Define si la informaci\u00F3n de la tabla se ordener\u00E1\r\nSe ingresar\u00E1 como valor el \u00EDndice a ordenar y separado por una coma el tipo de ordenamiento, ejm: 1,asc o 1,desc"
      },
      "attribute": "sort",
      "reflect": false
    },
    "sortDataType": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "'text' | 'date' | 'number'",
        "resolved": "\"date\" | \"number\" | \"text\"",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Especifica si la columna a ordenar tiene un tipo de dato concreto\r\nLos valores pueden ser 'text', 'date' o 'number'\r\nPor defecto se ordenar\u00E1 con el tipo texto\r\nSi el tipo es date, la fecha deber\u00E1 estar en formato dd/mm/yyyy"
      },
      "attribute": "sort-data-type",
      "reflect": false,
      "defaultValue": "'text'"
    },
    "actions": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Se agregar\u00E1 una columna al final de la tabla con las acciones especificadas\r\nLas acciones disponibles son 'detail', 'edit' o 'delete'\r\nLas acciones se ingresaran separados por coma. Ejm: 'edit,delete'"
      },
      "attribute": "actions",
      "reflect": false
    },
    "filteredText": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Buscar\u00E1 en cada celda el texto ingresado y lo resaltar\u00E1"
      },
      "attribute": "filtered-text",
      "reflect": false
    }
  }; }
  static get events() { return [{
      "method": "onselect",
      "name": "onselect",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": "Emite un evento al seleccionar una o varias filas de la tabla, env\u00EDa un arreglo con los \u00EDndices seleccionados"
      },
      "complexType": {
        "original": "Array<number | string>",
        "resolved": "(string | number)[]",
        "references": {
          "Array": {
            "location": "global"
          }
        }
      }
    }, {
      "method": "ondetail",
      "name": "ondetail",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": "Emite un evento al seleccionar la acci\u00F3n de ver detalle"
      },
      "complexType": {
        "original": "string | number",
        "resolved": "number | string",
        "references": {}
      }
    }, {
      "method": "onedit",
      "name": "onedit",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": "Emite un evento al seleccionar la acci\u00F3n de editar"
      },
      "complexType": {
        "original": "string | number",
        "resolved": "number | string",
        "references": {}
      }
    }, {
      "method": "ondelete",
      "name": "ondelete",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": "Emite un evento al seleccionar la acci\u00F3n de eliminar"
      },
      "complexType": {
        "original": "string | number",
        "resolved": "number | string",
        "references": {}
      }
    }]; }
  static get elementRef() { return "host"; }
}
