import { h } from '@stencil/core';
import Sortable, { MultiDrag } from 'sortablejs';
import { ArrayUtils } from '@sankhyalabs/core';
import initI18n from '../../utils/i18n';
Sortable.mount(new MultiDrag());
export class EzSortableList {
  constructor() {
    this.filterTerm = '';
    this.title = undefined;
    this.hideHeader = false;
    this.hideTotalizer = false;
    this.group = 'default';
    this.dataSource = [];
    this.idSortableList = 'DEFAULT_LIST';
    this.entityLabel = undefined;
    this.entityLabelPlural = undefined;
    this.emptyMessage = undefined;
    this.hoverFeedback = true;
    this.enableMultipleSelection = false;
    this.removeItensMoved = false;
    this.itemRightSlotBuilder = undefined;
    this.itemLeftSlotBuilder = undefined;
    this.selectedItems = new Set();
  }
  /** Remove a seleção de todos os itens da lista */
  async clearSelection() {
    this.selectedItems.clear();
    this.dataSource.forEach((item) => {
      var _a;
      const element = (_a = this.el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector(`[data-key="${item.id}"]`);
      if (!element)
        return;
      Sortable.utils.deselect(element);
      item.selected = false;
    });
    this.ezSelectItens.emit([]);
  }
  async componentWillLoad() {
    this.i18n = await initI18n();
    this.emptyMessage = this.i18n("ez-sortable-list.emptyMessage");
    this.entityLabel = this.i18n("ez-sortable-list.entityLabel");
    this.entityLabelPlural = this.i18n("ez-sortable-list.entityLabelPlural");
  }
  componentDidLoad() {
    this.initSortable();
  }
  componentDidRender() {
    this.selectPredefinedItens();
  }
  initSortable() {
    if (this._sortableInstance) {
      this._sortableInstance.destroy();
    }
    this._sortableInstance = new Sortable(this.el.shadowRoot.querySelector(`#${this.idSortableList}`), {
      group: {
        name: this.group,
        pull: true,
        put: true,
      },
      ghostClass: 'ghost',
      dragClass: 'dragging',
      animation: 15,
      multiDrag: this.enableMultipleSelection,
      avoidImplicitDeselect: this.enableMultipleSelection,
      selectedClass: 'selected',
      filter: '.filtered',
      swapThreshold: 0.5,
      multiDragKey: 'Control',
      removeCloneOnHide: true,
      onEnd: (evt) => this.handleReorderEvent(evt),
      onSelect: (evt) => this.handleSelect(evt),
      onDeselect: (evt) => this.handleDeselect(evt),
      onSort: (evt) => this.handleSortItem(evt),
      onChoose: (evt) => this.ezChoose.emit(evt),
    });
  }
  selectPredefinedItens() {
    this.dataSource.forEach((item) => {
      var _a;
      const element = (_a = this.el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector(`[data-key="${item.id}"]`);
      if (!element)
        return;
      if (this.selectedItems.has(item.id) || item.selected === true) {
        Sortable.utils.select(element);
      }
      else {
        Sortable.utils.deselect(element);
      }
    });
  }
  handleSortItem(evt) {
    var _a;
    if (!this.removeItensMoved)
      return;
    const fromId = evt.from.getAttribute('id');
    const toId = evt.to.getAttribute('id');
    if (toId === fromId) {
      evt.items = this.removeDuplicateElements(evt.items);
      return;
    }
    const itemsToRemove = ((_a = evt.items) === null || _a === void 0 ? void 0 : _a.length) > 0 ? evt.items : [evt.item];
    itemsToRemove.forEach(item => item.remove());
  }
  removeDuplicateElements(items) {
    const seenKeys = new Set();
    return items.filter((el) => {
      const key = el.getAttribute('data-key');
      if (key) {
        if (seenKeys.has(key)) {
          el.remove();
          return false;
        }
        seenKeys.add(key);
      }
      return true;
    });
  }
  handleSelect(evt) {
    this.updateSelection(evt.item, true);
  }
  handleDeselect(evt) {
    this.updateSelection(evt.item, false);
  }
  updateSelection(item, isSelected) {
    const itemId = item.getAttribute('data-key');
    if (!itemId)
      return;
    const targetItem = this.dataSource.find(item => item.id === itemId);
    if (!targetItem)
      return;
    targetItem.selected = isSelected;
    if (isSelected) {
      this.selectedItems.add(itemId);
    }
    else {
      this.selectedItems.delete(itemId);
    }
    this.emitSelectedItems();
  }
  emitSelectedItems() {
    this.ezSelectItens.emit(Array.from(this.selectedItems)
      .map(id => this.dataSource.find(item => item.id === id))
      .filter(Boolean));
  }
  handleReorderEvent(evt) {
    var _a;
    const selectedElements = ((_a = evt.items) === null || _a === void 0 ? void 0 : _a.length) > 0 ? evt.items : [evt.item];
    const selectItens = selectedElements
      .map(el => el.getAttribute('data-key'))
      .filter(Boolean);
    this.itemsReordered.emit({
      dataSource: this.dataSource,
      selectItens,
      from: evt.from,
      to: evt.to,
      newIndex: evt.newIndex,
      newIndicies: evt.newIndicies,
    });
  }
  handleDoubleClick(itemId) {
    var _a;
    const itemList = this.dataSource.find(item => item.id === itemId);
    if (itemList) {
      (_a = this.ezDoubleClick) === null || _a === void 0 ? void 0 : _a.emit(itemList);
    }
  }
  getContainerItemBuilder(slotPosition, item, className) {
    var _a, _b;
    const customContent = slotPosition === 'left' ? (_a = this.itemLeftSlotBuilder) === null || _a === void 0 ? void 0 : _a.call(this, item) : (_b = this.itemRightSlotBuilder) === null || _b === void 0 ? void 0 : _b.call(this, item);
    if (customContent == undefined)
      return;
    if (typeof customContent !== 'string') {
      return h("div", { class: className }, customContent);
    }
    return h("div", { class: className, innerHTML: customContent });
  }
  disconnectedCallback() {
    if (this._sortableInstance) {
      this._sortableInstance.destroy();
      this._sortableInstance = null;
    }
  }
  buildTotalizer() {
    return `${this.i18n("ez-sortable-list.total")} ${this.dataSource.length} ${this.dataSource.length === 1 ? this.entityLabel : this.entityLabelPlural}`;
  }
  renderItems() {
    const itemsToRender = ArrayUtils.applyStringFilter(this.filterTerm, this.dataSource);
    return itemsToRender.map((item) => (h("div", { id: `ID_${item.id}`, key: `KEY_${item.id}`, class: {
        'sortable-item': true,
        'hover-feedback': this.hoverFeedback,
      }, "data-key": item.id, onDblClick: () => this.handleDoubleClick(item.id) }, !!this.itemLeftSlotBuilder && this.getContainerItemBuilder('left', item), h("div", { class: "item-content" }, h("span", { class: "draggable-icon" }), item.label), !!this.itemRightSlotBuilder && this.getContainerItemBuilder('right', item))));
  }
  handleFilterChanged(evt) {
    evt.stopPropagation();
    evt.preventDefault();
    this.filterTerm = evt.detail;
  }
  renderTotalizer() {
    if (this.hideTotalizer)
      return;
    return (h("div", { class: 'sortable-totalizer' }, this.buildTotalizer()));
  }
  renderHeader() {
    if (this.hideHeader)
      return;
    return (h("div", { class: 'sortable-header' }, h("span", { class: 'sortable-label' }, this.title), h("ez-filter-input", { label: `${this.i18n("ez-sortable-list.search")} ${this.entityLabel}`, mode: "slim", onEzChange: evt => this.handleFilterChanged(evt) })));
  }
  render() {
    return (h("div", { class: 'sortable-content' }, this.renderHeader(), h("div", { class: `sortable-list ${this.dataSource.length < 1 ? 'empty-content' : ''} list-scroller--fix`, "data-content": this.emptyMessage, style: { '--empty-content': `"${this.emptyMessage}"` }, id: this.idSortableList, key: this.idSortableList }, this.renderItems()), this.renderTotalizer()));
  }
  static get is() { return "ez-sortable-list"; }
  static get encapsulation() { return "shadow"; }
  static get originalStyleUrls() {
    return {
      "$": ["ez-sortable-list.css"]
    };
  }
  static get styleUrls() {
    return {
      "$": ["ez-sortable-list.css"]
    };
  }
  static get properties() {
    return {
      "title": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Define o t\u00EDtulo da lista."
        },
        "attribute": "title",
        "reflect": false
      },
      "hideHeader": {
        "type": "boolean",
        "mutable": false,
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Define se o cabe\u00E7alho deve ficar oculto."
        },
        "attribute": "hide-header",
        "reflect": false,
        "defaultValue": "false"
      },
      "hideTotalizer": {
        "type": "boolean",
        "mutable": false,
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Define se o totalizador deve ser escondido."
        },
        "attribute": "hide-totalizer",
        "reflect": false,
        "defaultValue": "false"
      },
      "group": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Grupo ao qual o ez-sortable-list pertence"
        },
        "attribute": "group",
        "reflect": false,
        "defaultValue": "'default'"
      },
      "dataSource": {
        "type": "unknown",
        "mutable": false,
        "complexType": {
          "original": "Array<ListItem>",
          "resolved": "ListItem[]",
          "references": {
            "Array": {
              "location": "global"
            },
            "ListItem": {
              "location": "local"
            }
          }
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Lista de itens para serem renderizados"
        },
        "defaultValue": "[]"
      },
      "idSortableList": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "ID do sortable list"
        },
        "attribute": "id-sortable-list",
        "reflect": false,
        "defaultValue": "'DEFAULT_LIST'"
      },
      "entityLabel": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Nome da entidade listada.\nExemplo: \"Campo\", \"Item\", \"Empresa\"."
        },
        "attribute": "entity-label",
        "reflect": false
      },
      "entityLabelPlural": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Varia\u00E7\u00E3o plural do nome da entidade listada.\nExemplo: \"Campos\", \"Itens\", \"Empresas\"."
        },
        "attribute": "entity-label-plural",
        "reflect": false
      },
      "emptyMessage": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Mensagem exibida quando a lista est\u00E1 vazia"
        },
        "attribute": "empty-message",
        "reflect": false
      },
      "hoverFeedback": {
        "type": "boolean",
        "mutable": false,
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Quando verdadeiro, ativa o feedback visual ao efetuar hover nos itens da lista"
        },
        "attribute": "hover-feedback",
        "reflect": false,
        "defaultValue": "true"
      },
      "enableMultipleSelection": {
        "type": "boolean",
        "mutable": false,
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Habilita sele\u00E7\u00E3o de m\u00FAltiplos itens utilizando as teclas 'Ctrl/Command' ou 'Shift'"
        },
        "attribute": "enable-multiple-selection",
        "reflect": false,
        "defaultValue": "false"
      },
      "removeItensMoved": {
        "type": "boolean",
        "mutable": false,
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Remove itens arrastados de uma lista para outra"
        },
        "attribute": "remove-itens-moved",
        "reflect": false,
        "defaultValue": "false"
      },
      "itemRightSlotBuilder": {
        "type": "unknown",
        "mutable": true,
        "complexType": {
          "original": "SlotBuilder",
          "resolved": "(item: ListItem, group?: ListGroup) => string | HTMLElement",
          "references": {
            "SlotBuilder": {
              "location": "import",
              "path": "../ez-list/ez-list"
            }
          }
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Fun\u00E7\u00E3o builder que possibilita alterar como o item da lista vai ser apresentado.\nObserva\u00E7\u00E3o: No react ele se transforma em VNode e n\u00E3o como HTMLElement."
        }
      },
      "itemLeftSlotBuilder": {
        "type": "unknown",
        "mutable": true,
        "complexType": {
          "original": "SlotBuilder",
          "resolved": "(item: ListItem, group?: ListGroup) => string | HTMLElement",
          "references": {
            "SlotBuilder": {
              "location": "import",
              "path": "../ez-list/ez-list"
            }
          }
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Fun\u00E7\u00E3o builder que possibilita gerar conte\u00FAdo din\u00E2mico \u00E0 esquerda do item da lista.\n* Observa\u00E7\u00E3o: No react ele se transforma em VNode e n\u00E3o como HTMLElement."
        }
      }
    };
  }
  static get states() {
    return {
      "filterTerm": {},
      "selectedItems": {}
    };
  }
  static get events() {
    return [{
        "method": "itemsReordered",
        "name": "itemsReordered",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": "Evento emitido quando a ordem dos itens muda"
        },
        "complexType": {
          "original": "any",
          "resolved": "any",
          "references": {}
        }
      }, {
        "method": "ezSelectItens",
        "name": "ezSelectItens",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": "Emitido sempre que um ou v\u00E1rios itens da lista forem selecionados"
        },
        "complexType": {
          "original": "ListItem[] | ListItem",
          "resolved": "ListItem | ListItem[]",
          "references": {
            "ListItem": {
              "location": "local"
            }
          }
        }
      }, {
        "method": "ezDoubleClick",
        "name": "ezDoubleClick",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": "Emitido quando ocorre um duplo clique em um item da lista"
        },
        "complexType": {
          "original": "ListItem",
          "resolved": "ListItem",
          "references": {
            "ListItem": {
              "location": "local"
            }
          }
        }
      }, {
        "method": "ezChoose",
        "name": "ezChoose",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": "Emitido quando ocorre a escolha de um item da lista"
        },
        "complexType": {
          "original": "ListItem[] | ListItem",
          "resolved": "ListItem | ListItem[]",
          "references": {
            "ListItem": {
              "location": "local"
            }
          }
        }
      }];
  }
  static get methods() {
    return {
      "clearSelection": {
        "complexType": {
          "signature": "() => Promise<void>",
          "parameters": [],
          "references": {
            "Promise": {
              "location": "global"
            }
          },
          "return": "Promise<void>"
        },
        "docs": {
          "text": "Remove a sele\u00E7\u00E3o de todos os itens da lista",
          "tags": []
        }
      }
    };
  }
  static get elementRef() { return "el"; }
}
