import initI18n from '../../utils/i18n';
import { ArrayUtils } from '@sankhyalabs/core';
import { Fragment, h, Host } from '@stencil/core';
var ViewScenarios;
(function (ViewScenarios) {
  ViewScenarios["DATASOURCE_RESULTS"] = "DATASOURCE_RESULTS";
  ViewScenarios["DATASOURCE_RESULTS_EMPTY"] = "DATASOURCE_RESULTS_EMPTY";
  ViewScenarios["DATASOURCE_INIT"] = "DATASOURCE_INIT";
  ViewScenarios["OPTIONS_EMPTY"] = "OPTIONS_EMPTY";
  ViewScenarios["OPTIONS"] = "OPTIONS";
})(ViewScenarios || (ViewScenarios = {}));
export class EzMuiltiSelectionList {
  constructor() {
    this.columnName = undefined;
    this.dataSource = undefined;
    this.useOptions = false;
    this.options = undefined;
    this.isTextSearch = false;
    this.filteredOptions = undefined;
    this.displayOptions = undefined;
    this.viewScenario = undefined;
    this.displayOptionToCheckAllItems = true;
  }
  async componentWillLoad() {
    this.i18n = await initI18n();
  }
  async clearFilteredOptions() {
    this.setInitialScenario();
    this.filteredOptions = [];
    if (this.searchInput) {
      await this.searchInput.clearValue();
    }
    if (this.filterInput) {
      this.filterInput.value = '';
    }
  }
  onChangeUseOptions() {
    this.setInitialScenario();
  }
  onChangeOptions() {
    if (this.options) {
      this.filteredOptions = this.ordenationByCheckStateAndAlphabetically(this.options);
    }
    this.checkInput && this.changeCheckAllValeuFromFilteredOptions();
    this.setInitialScenario();
  }
  onChangeFilteredOptions(optionsListUpdated) {
    this.displayOptions = this.filteredOptions;
    this.displayOptionToCheckAllItems = this.filteredOptions.length > 1;
    this.checkInput && this.changeCheckAllValeuFromFilteredOptions();
    this.changeFilteredOptions.emit(optionsListUpdated);
  }
  componentDidLoad() {
    this.onChangeOptions();
  }
  componentDidRender() {
    this.changeCheckAllValeuFromFilteredOptions();
  }
  ordenationByCheckStateAndAlphabetically(filteredOptions) {
    const listWithSelectChecked = [];
    const listWithNotSelectChecked = [];
    let emptyElement;
    filteredOptions.forEach(item => {
      if (item.value == undefined || item.label === "") {
        emptyElement = Object.assign(Object.assign({}, item), { label: this.i18n("ez-multi-selection-list.empty") });
      }
      else {
        (item.check ? listWithSelectChecked.push(item) : listWithNotSelectChecked.push(item));
      }
    });
    return (emptyElement == undefined ? [] : [emptyElement])
      .concat(this.dataSource == undefined ? ArrayUtils.sortAlphabetically(listWithSelectChecked) : this.dataSource.sortItems(this.columnName, listWithSelectChecked))
      .concat(this.dataSource == undefined ? ArrayUtils.sortAlphabetically(listWithNotSelectChecked) : this.dataSource.sortItems(this.columnName, listWithNotSelectChecked));
  }
  changeCheckAllValeuFromFilteredOptions() {
    var _a, _b, _c, _d;
    const selectAll = (_a = this.filteredOptions) === null || _a === void 0 ? void 0 : _a.every(item => item.check === true);
    const notSelectAll = (_b = this.filteredOptions) === null || _b === void 0 ? void 0 : _b.every(item => item.check === false);
    const selectIndeterminated = ((_c = this.filteredOptions) === null || _c === void 0 ? void 0 : _c.some(item => item.check === false)) && ((_d = this.filteredOptions) === null || _d === void 0 ? void 0 : _d.some(item => item.check === true)) && (!selectAll || !notSelectAll);
    if (this.checkInput && selectAll) {
      this.checkInput.indeterminate = false;
      this.checkInput.value = true;
      return;
    }
    if (this.checkInput && selectIndeterminated) {
      this.checkInput.indeterminate = true;
      this.checkInput.value = false;
      return;
    }
    if (this.checkInput && notSelectAll) {
      this.checkInput.indeterminate = false;
      this.checkInput.value = false;
      return;
    }
  }
  setInitialScenario() {
    if (this.useOptions) {
      this.viewScenario = ViewScenarios.OPTIONS;
      this.changeCheckAllValeuFromFilteredOptions();
      return;
    }
    this.viewScenario = this.options && this.options.length > 0 ? ViewScenarios.DATASOURCE_RESULTS : ViewScenarios.DATASOURCE_INIT;
  }
  async searchWithDataSource(searchArgument, fieldName) {
    const { argument, mode } = searchArgument;
    if (mode !== 'PRELOAD' && fieldName) {
      return this.dataSource.fetchData(argument, fieldName);
    }
  }
  async handleSearchOnDataSource(event) {
    var _a;
    const optionsToSort = (_a = this.filteredOptions) !== null && _a !== void 0 ? _a : [];
    if (event.detail && !optionsToSort.some(item => item.value == event.detail.value)) {
      this.filteredOptions = this.ordenationByCheckStateAndAlphabetically([...optionsToSort, event.detail]);
    }
    this.viewScenario = ViewScenarios.DATASOURCE_RESULTS;
    await this.searchInput.clearValue();
  }
  async handleRemoveItemFromOptions(item) {
    this.filteredOptions = this.ordenationByCheckStateAndAlphabetically(this.filteredOptions.filter(i => i.value !== item.value));
    if (this.filteredOptions.length === 0) {
      this.viewScenario = ViewScenarios.DATASOURCE_INIT;
    }
    if (this.searchInput) {
      await this.searchInput.clearValue();
    }
  }
  handleSearchOnOption(event) {
    if (event.detail) {
      this.displayOptions = ArrayUtils.applyStringFilter(event.detail, this.filteredOptions, true);
      this.viewScenario = this.displayOptions.length === 0 ? ViewScenarios.OPTIONS_EMPTY : ViewScenarios.OPTIONS;
      return;
    }
    this.displayOptions = this.filteredOptions;
    this.viewScenario = ViewScenarios.OPTIONS;
  }
  handleChangeSelectAllItems(event) {
    this.filteredOptions = this.ordenationByCheckStateAndAlphabetically([
      ...this.filteredOptions.map(item => {
        item.check = !!event.detail;
        return item;
      }),
    ]);
  }
  handleChangeSelectedItem(event) {
    const { detail: itemCheckSelected } = event;
    const itemSelected = this.filteredOptions.find(item => item.label === itemCheckSelected.label);
    itemSelected.check = itemCheckSelected.check;
    this.changeFilteredOptions.emit(this.filteredOptions);
  }
  buildViewList(hasDelete) {
    return (h(Fragment, null, this.displayOptionToCheckAllItems && (h("ez-check", { ref: (element) => (this.checkInput = element), label: this.i18n("ez-multi-selection-list.selectAll"), class: "multi-selection__select-all", onEzChange: this.handleChangeSelectAllItems.bind(this) })), h("ez-list", { class: "multi-selection__list", dataSource: this.displayOptions.map(opt => (Object.assign(Object.assign({}, opt), { id: opt.value }))), listMode: "check", hoverFeedback: true, onEzCheckChange: this.handleChangeSelectedItem.bind(this), itemSlotBuilder: hasDelete ? this.buildDeleteIconSlot.bind(this) : null })));
  }
  buildDeleteIconSlot(item) {
    return h("ez-icon", { style: { cursor: 'pointer' }, iconName: "delete", onClick: () => this.handleRemoveItemFromOptions(item) });
  }
  buildInitViewWithDataSource() {
    return h("multi-selection-box-message", { message: this.i18n("ez-multi-selection-list.initMessage") });
  }
  buildViewEmptyResults() {
    return h("multi-selection-box-message", { message: this.i18n("ez-multi-selection-list.emptyResults") });
  }
  scenarioToDisplay(view) {
    const scenarios = {
      [ViewScenarios.DATASOURCE_INIT]: () => this.buildInitViewWithDataSource(),
      [ViewScenarios.DATASOURCE_RESULTS]: () => this.buildViewList(true),
      [ViewScenarios.DATASOURCE_RESULTS_EMPTY]: () => this.buildViewEmptyResults(),
      [ViewScenarios.OPTIONS_EMPTY]: () => this.buildViewEmptyResults(),
      [ViewScenarios.OPTIONS]: () => this.buildViewList(false),
    };
    const scenarioBuilder = scenarios[view];
    return scenarioBuilder ? scenarioBuilder() : undefined;
  }
  render() {
    return (h(Host, null, h("div", { class: "multi-selection" }, this.useOptions ? (h("ez-filter-input", { ref: (element) => (this.filterInput = element), label: this.i18n("ez-multi-selection-list.search"), onEzChange: this.handleSearchOnOption.bind(this) })) : (h("ez-search", { class: "multi-selection__input", label: this.i18n("ez-multi-selection-list.search"), ref: (element) => (this.searchInput = element), suppressEmptyOption: true, showOptionValue: false, showSelectedValue: false, optionLoader: (search) => this.searchWithDataSource(search, this.columnName), onEzChange: this.handleSearchOnDataSource.bind(this), isTextSearch: this.isTextSearch })), h("ez-scroll", { class: "multi-selection__content-options" }, this.scenarioToDisplay(this.viewScenario)))));
  }
  static get is() { return "ez-multi-selection-list"; }
  static get encapsulation() { return "scoped"; }
  static get originalStyleUrls() {
    return {
      "$": ["ez-multi-selection-list.css"]
    };
  }
  static get styleUrls() {
    return {
      "$": ["ez-multi-selection-list.css"]
    };
  }
  static get properties() {
    return {
      "columnName": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Nome da coluna onde ser\u00E3o aplicadas as op\u00E7\u00F5es selecionadas."
        },
        "attribute": "column-name",
        "reflect": false
      },
      "dataSource": {
        "type": "unknown",
        "mutable": false,
        "complexType": {
          "original": "IMultiSelectionListDataSource",
          "resolved": "IMultiSelectionListDataSource",
          "references": {
            "IMultiSelectionListDataSource": {
              "location": "import",
              "path": "./interfaces/IMultiSelectionListDataSource"
            }
          }
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Classe que implementa o m\u00E9todo fetchData, respons\u00E1vel por realizar a pesquisa dos dados,\ncom base no termo informado pelo usu\u00E1rio."
        }
      },
      "useOptions": {
        "type": "boolean",
        "mutable": true,
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Indica se deve ser exibida lista de op\u00E7\u00F5es do atributo options (true),\nou se deve utilizar o datasource (false)"
        },
        "attribute": "use-options",
        "reflect": false,
        "defaultValue": "false"
      },
      "options": {
        "type": "unknown",
        "mutable": true,
        "complexType": {
          "original": "IMultiSelectionOption[]",
          "resolved": "IMultiSelectionOption[]",
          "references": {
            "IMultiSelectionOption": {
              "location": "import",
              "path": "./interfaces/IMultiSelectionOption"
            }
          }
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Op\u00E7\u00F5es de filtros a serem exibidas na listagem."
        }
      },
      "isTextSearch": {
        "type": "boolean",
        "mutable": false,
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Informa se a pesquisa \u00E9 do tipo texto ou num\u00E9rico."
        },
        "attribute": "is-text-search",
        "reflect": false,
        "defaultValue": "false"
      }
    };
  }
  static get states() {
    return {
      "filteredOptions": {},
      "displayOptions": {},
      "viewScenario": {},
      "displayOptionToCheckAllItems": {}
    };
  }
  static get events() {
    return [{
        "method": "changeFilteredOptions",
        "name": "changeFilteredOptions",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": "Evento que informa que a lista de op\u00E7\u00F5es selecionadas sofreu altera\u00E7\u00E3o."
        },
        "complexType": {
          "original": "IMultiSelectionOption[]",
          "resolved": "IMultiSelectionOption[]",
          "references": {
            "IMultiSelectionOption": {
              "location": "import",
              "path": "./interfaces/IMultiSelectionOption"
            }
          }
        }
      }];
  }
  static get methods() {
    return {
      "clearFilteredOptions": {
        "complexType": {
          "signature": "() => Promise<void>",
          "parameters": [],
          "references": {
            "Promise": {
              "location": "global"
            }
          },
          "return": "Promise<void>"
        },
        "docs": {
          "text": "",
          "tags": []
        }
      }
    };
  }
  static get watchers() {
    return [{
        "propName": "useOptions",
        "methodName": "onChangeUseOptions"
      }, {
        "propName": "options",
        "methodName": "onChangeOptions"
      }, {
        "propName": "filteredOptions",
        "methodName": "onChangeFilteredOptions"
      }];
  }
}
