import { ApplicationContext, ElementIDUtils, UserInterface } from '@sankhyalabs/core';
import { h, Host, Fragment } from '@stencil/core';
import FilterItemType from '../../filter-item-type.enum';
import { EPresentationMode } from '../enum/presentationMode';
import { EzScrollDirection } from '@sankhyalabs/ezui/dist/collection/components/ez-scroller/EzScrollDirection';
import { CheckMode } from "@sankhyalabs/ezui/dist/collection/utils";
export class SnkFilterPersonalized {
  constructor() {
    this.originalItems = [];
    this.messagesBuilder = undefined;
    this.presentationMode = EPresentationMode.MODAL;
    this.config = undefined;
    this.value = undefined;
    this.items = [];
  }
  /**
   * Apresenta o componente
   */
  async show() {
    const elem = document.querySelector("#param_0");
    if (elem)
      elem["setFocus"]();
  }
  configWatcher(newConfig) {
    this.items = this.originalItems = newConfig.groupedItems || [];
  }
  /**
   * Conforme mecanismo de mensagens, é possível customizar as mensagens dos blocos de construção
   * através de um pequeno modulo na estrutura da aplicação:
   * - Criar um arquivo no seguinte caminho: /messages/appmessages.msg.js.
   * Para conhecer os detalhes do módulo, vide o arquivo neste projeto "/src/lib/message/resources/snk-personalized-filter.msg.ts"
   */
  getMessage(key, params) {
    var _a;
    if (this.messagesBuilder)
      return this.messagesBuilder.getMessage(key, params);
    if ((_a = this._application) === null || _a === void 0 ? void 0 : _a.messagesBuilder)
      return this._application.messagesBuilder.getMessage(key, params);
  }
  getItemContent(item) {
    var _a, _b;
    const CheckboxElement = () => (h("ez-check", Object.assign({ class: "SnkFilterPersonalized_checkbox", id: `param_${item.id}`, key: item.id, value: item.visible, label: item.label, onEzChange: ({ detail: visible }) => this.handleItemChange.bind(this)(visible, item.id) }, { [ElementIDUtils.DATA_ELEMENT_ID_ATTRIBUTE_NAME]: `${ElementIDUtils.getInternalIDInfo(`checkboxFilter_${item.id}`)}` })));
    const isVariable = !!((_b = (_a = item.props) === null || _a === void 0 ? void 0 : _a.personalizedFilter) === null || _b === void 0 ? void 0 : _b.parameters.length);
    return (h("div", { class: `${!this.isModalMode() ? "SnkFilterPersonalized_list-item--chip" : ""}` }, h("li", { class: `${this.isModalMode() ? "SnkFilterPersonalized_list-item--modal" : ""}` }, h("div", { class: "ez-flex ez-flex--align-items-center ez-flex--justify-between ez-size-width--full" }, h(CheckboxElement, null), this.buildModalListActions(item, isVariable))), (item.visible && isVariable) && (h("div", { class: "ez-row ez-padding--small" }, this.getFormField(item)))));
  }
  buildModalListActions(item, isVariable) {
    if (!this.isModalMode())
      return;
    return (this.isModalMode() ?
      h("div", { class: "SnkFilterPersonalized_list-actions" }, h("ez-icon", { class: 'SnkFilterPersonalized_list-icon', iconName: "edit", title: this.getMessage('snkPersonalizedFilter.listActions.edit'), onClick: () => this.editFilter.emit(item.id) }), h("ez-icon", { class: 'SnkFilterPersonalized_list-icon', iconName: "delete", title: this.getMessage('snkPersonalizedFilter.listActions.delete'), onClick: this.handleDeleteFilter.bind(this, item) }))
      :
        isVariable && (h("ez-badge", Object.assign({ class: "ez-badge--warning-subtle ez-margin-right--small", label: this.getMessage('snkPersonalizedFilter.info.badgeVariable'), size: "medium" }, { [ElementIDUtils.DATA_ELEMENT_ID_ATTRIBUTE_NAME]: `${ElementIDUtils.getInternalIDInfo(`variableBadge_${item.id}`)}` }))));
  }
  isModalMode() {
    return this.presentationMode === EPresentationMode.MODAL;
  }
  doSearch(mode, argument, param) {
    const context = Object.assign({}, param.searchContext);
    context.searchOptions = Object.assign(Object.assign({}, context.searchOptions), { showInactives: "true" });
    return new Promise((resolve, reject) => {
      this._application.executePreparedSearch(mode, argument, context)
        .then(result => {
        resolve(result);
      }).catch(reason => {
        reject(reason);
      });
    });
  }
  getFormField(parentItem) {
    var _a, _b;
    const params = (_b = (_a = parentItem === null || parentItem === void 0 ? void 0 : parentItem.props) === null || _a === void 0 ? void 0 : _a.personalizedFilter) === null || _b === void 0 ? void 0 : _b.parameters;
    return params.map((param, index) => {
      var _a, _b, _c, _d;
      const formProp = Object.assign(Object.assign({}, param), { id: parentItem.id });
      const value = (_a = parentItem.value) === null || _a === void 0 ? void 0 : _a[index];
      const elemId = 'param_' + index;
      switch (param.userInterface) {
        case UserInterface.SEARCH:
          const isSearchPlus = ((_b = this.config.props) === null || _b === void 0 ? void 0 : _b["useSearchPlus"]) == true;
          const TagName = isSearchPlus ? "ez-search-plus" : "ez-search";
          return h(TagName, { id: elemId, suppressEmptyOption: true, value: value, onEzChange: evt => this.handleFilterItemChange(evt.detail, formProp), label: param.label, optionLoader: ({ mode, argument }) => this.doSearch(mode, argument, param) });
        case UserInterface.SWITCH:
        case UserInterface.CHECKBOX:
          const mode = UserInterface.SWITCH === param.userInterface ? CheckMode.SWITCH : CheckMode.REGULAR;
          return h("ez-check", { id: elemId, class: "ez-padding-bottom--medium", mode: mode, value: value, label: param.label, onEzChange: evt => this.handleFilterItemChange(evt.detail, formProp) });
        case UserInterface.DECIMALNUMBER:
          return h("ez-number-input", { id: elemId, label: param.label, value: value, precision: ((_c = param.props) === null || _c === void 0 ? void 0 : _c.precision) || 2, onEzChange: evt => this.handleFilterItemChange(evt.detail, formProp) });
        case UserInterface.INTEGERNUMBER:
          return h("ez-number-input", { id: elemId, label: param.label, value: value, precision: (_d = param.props) === null || _d === void 0 ? void 0 : _d.precision, onEzChange: evt => this.handleFilterItemChange(evt.detail, formProp) });
        case UserInterface.OPTIONSELECTOR:
          return h("ez-combo-box", { id: elemId, label: param.label, value: value, options: param.options, onEzChange: evt => this.handleFilterItemChange(evt.detail, formProp) });
        case UserInterface.DATE:
          return h("ez-date-input", { id: elemId, label: param.label, value: this.parseDate(value), onEzChange: evt => this.handleFilterItemChange(evt.detail, formProp) });
        case UserInterface.DATETIME:
          return h("ez-date-time-input", { id: elemId, label: param.label, value: this.parseDate(value), onEzChange: evt => this.handleFilterItemChange(evt.detail, formProp) });
        default:
          return h("ez-text-input", { id: elemId, label: param.label, value: value, onEzChange: evt => this.handleFilterItemChange(evt.detail, formProp) });
      }
    });
  }
  parseDate(objValue) {
    if (typeof objValue === "string") {
      let date = new Date(objValue);
      date.setMinutes(date.getMinutes() + date.getTimezoneOffset());
      return date;
    }
    return objValue;
  }
  getVisibleCount(items) {
    return items.reduce((total, item) => {
      if (!!item.visible)
        return total + 1;
      return total;
    }, 0);
  }
  handleItemChange(visible, itemId) {
    this.items = this.originalItems = this.originalItems.map(item => {
      const isVisible = item.id === itemId ? visible : item.visible;
      return Object.assign(Object.assign({}, item), { visible: isVisible, active: isVisible });
    });
    this.emitChange();
  }
  handleSearchFilterList({ detail: query = "" }) {
    this.items = query ? this.originalItems.filter(item => item.label.toLowerCase().includes(query.toLowerCase())) : this.originalItems;
  }
  handleFilterItemChange(value, formProp) {
    var _a;
    const changedItem = this.items.find(({ id }) => id === formProp.id);
    const { parameters = [] } = ((_a = changedItem.props) === null || _a === void 0 ? void 0 : _a.personalizedFilter) || {};
    const indexToChangedParameter = parameters.findIndex(param => param.name === formProp.name);
    parameters[indexToChangedParameter] = formProp;
    changedItem.props.personalizedFilter.parameters = parameters;
    if (!changedItem.value) {
      changedItem.value = [];
    }
    changedItem.value[indexToChangedParameter] = value;
    const updatedItems = [
      ...this.items,
      changedItem
    ];
    this.items = Array.from(new Set(updatedItems));
    this.emitChange();
  }
  handleClearFilters() {
    this.emitChange(true);
  }
  emitChange(clear = false) {
    if (clear)
      this.items = this.originalItems;
    const items = this.items.map(item => (Object.assign(Object.assign({}, item), { visible: !clear && item.visible })));
    const value = this.getVisibleCount(items);
    this.valueChanged.emit({ value, items });
  }
  handleDeleteFilter(item) {
    this._application.confirm(this.getMessage('snkPersonalizedFilter.deleteConfirm.title'), this.getMessage('snkPersonalizedFilter.deleteConfirm.message', { filterName: item.label })).then((actionConfirmed) => {
      if (!actionConfirmed)
        return;
      this.deleteFilter.emit(item);
      this.items = this.originalItems = this.originalItems.filter(originalItem => originalItem.id !== item.id);
      this.emitChange();
    });
  }
  componentDidLoad() {
    if (this._element)
      ElementIDUtils.addIDInfoIfNotExists(this._element, 'filterContentEditor');
  }
  componentWillLoad() {
    var _a;
    this._application = ApplicationContext.getContextValue('__SNK__APPLICATION__');
    this.items = this.originalItems = ((_a = this.config) === null || _a === void 0 ? void 0 : _a.groupedItems) || [];
  }
  buildModeModalHeader() {
    if (this.presentationMode !== EPresentationMode.MODAL)
      return;
    return (h("div", { class: "ez-margin-bottom--medium" }, h(Fragment, null, h("ez-filter-input", Object.assign({ label: this.config.label, onEzChange: this.handleSearchFilterList.bind(this) }, { [ElementIDUtils.DATA_ELEMENT_ID_ATTRIBUTE_NAME]: `${ElementIDUtils.getInternalIDInfo("filterSearch")}` })), h("span", { class: "ez-text ez-title--small ez-title--primary" }, " ", this.config.detailTitle, " "))));
  }
  buildModeModalFooter() {
    if (this.presentationMode !== EPresentationMode.MODAL)
      return;
    return (h("div", { class: "ez-flex ez-flex--justify-end grow ez-margin-top--medium ez-margin-bottom--small" }, h("ez-button", { class: "ez-button--tertiary ez-margin-right--small", size: "medium", label: this.getMessage('snkPersonalizedFilter.footerActions.clear'), onClick: this.handleClearFilters.bind(this) }), h("ez-button", { class: "ez-button--secondary ez-margin-right--small", size: "medium", label: this.getMessage('snkPersonalizedFilter.footerActions.create'), onClick: () => this.addFilter.emit() })));
  }
  buildContainerFiltersCreated() {
    if (this.items.length) {
      return (h("ez-scroller", { class: "SnkFilterPersonalized_list-scroller", direction: EzScrollDirection.VERTICAL }, h("ul", { class: `SnkFilterPersonalized_list-container ${!this.isModalMode() ? "SnkFilterPersonalized_list-container-chip" : ""}` }, this.items.map((itemConfig) => this.getItemContent(itemConfig)))));
    }
    else {
      return (h("div", { class: "ez-margin--auto" }, h("span", { class: "ez-text ez-text--secondary ez-text--small" }, this.getMessage('snkPersonalizedFilter.info.noDataFound'))));
    }
  }
  render() {
    if (!this.config || this.config.type !== FilterItemType.PERSONALIZED)
      return undefined;
    return (h(Host, null, this.buildModeModalHeader(), this.buildContainerFiltersCreated(), this.buildModeModalFooter()));
  }
  static get is() { return "snk-personalized-filter-editor"; }
  static get encapsulation() { return "scoped"; }
  static get originalStyleUrls() {
    return {
      "$": ["snk-personalized-filter-editor.css"]
    };
  }
  static get styleUrls() {
    return {
      "$": ["snk-personalized-filter-editor.css"]
    };
  }
  static get properties() {
    return {
      "messagesBuilder": {
        "type": "unknown",
        "mutable": true,
        "complexType": {
          "original": "SnkMessageBuilder",
          "resolved": "SnkMessageBuilder",
          "references": {
            "SnkMessageBuilder": {
              "location": "import",
              "path": "../../../../../lib/message/SnkMessageBuilder"
            }
          }
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Respons\u00E1vel por flexibilizar e padronizar o uso de mensagens nos blocos de constru\u00E7\u00E3o."
        }
      },
      "presentationMode": {
        "type": "number",
        "mutable": false,
        "complexType": {
          "original": "EPresentationMode",
          "resolved": "EPresentationMode.CHIP | EPresentationMode.MODAL",
          "references": {
            "EPresentationMode": {
              "location": "import",
              "path": "../enum/presentationMode"
            }
          }
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Controla o modo de apresenta\u00E7\u00E3o do componente, que pode ser configurado como modal ou chip."
        },
        "attribute": "presentation-mode",
        "reflect": false,
        "defaultValue": "EPresentationMode.MODAL"
      },
      "config": {
        "type": "unknown",
        "mutable": false,
        "complexType": {
          "original": "SnkFilterItemConfig",
          "resolved": "SnkFilterItemConfig",
          "references": {
            "SnkFilterItemConfig": {
              "location": "import",
              "path": "../../snk-filter-item"
            }
          }
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Configura\u00E7\u00E3o que define as op\u00E7\u00F5es e comportamento do componente."
        }
      },
      "value": {
        "type": "unknown",
        "mutable": true,
        "complexType": {
          "original": "Array<IOption|boolean|string|number|Date>",
          "resolved": "(string | number | boolean | Date | IOption)[]",
          "references": {
            "Array": {
              "location": "global"
            },
            "IOption": {
              "location": "import",
              "path": "@sankhyalabs/ezui/dist/types/components/ez-combo-box/ez-combo-box"
            },
            "Date": {
              "location": "global"
            }
          }
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Controla o valor do componente."
        }
      }
    };
  }
  static get states() {
    return {
      "items": {}
    };
  }
  static get events() {
    return [{
        "method": "deleteFilter",
        "name": "deleteFilter",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": ""
        },
        "complexType": {
          "original": "IPersonalizedFilter",
          "resolved": "IPersonalizedFilter",
          "references": {
            "IPersonalizedFilter": {
              "location": "import",
              "path": "../../../../snk-personalized-filter/interfaces/IPersonalizedFilter"
            }
          }
        }
      }, {
        "method": "editFilter",
        "name": "editFilter",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": ""
        },
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        }
      }, {
        "method": "addFilter",
        "name": "addFilter",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": ""
        },
        "complexType": {
          "original": "void",
          "resolved": "void",
          "references": {}
        }
      }, {
        "method": "valueChanged",
        "name": "valueChanged",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": "Emitido quando o valor do filtro \u00E9 alterado."
        },
        "complexType": {
          "original": "any",
          "resolved": "any",
          "references": {}
        }
      }];
  }
  static get methods() {
    return {
      "show": {
        "complexType": {
          "signature": "() => Promise<void>",
          "parameters": [],
          "references": {
            "Promise": {
              "location": "global"
            }
          },
          "return": "Promise<void>"
        },
        "docs": {
          "text": "Apresenta o componente",
          "tags": []
        }
      }
    };
  }
  static get elementRef() { return "_element"; }
  static get watchers() {
    return [{
        "propName": "config",
        "methodName": "configWatcher"
      }];
  }
}
