import { h, Host, forceUpdate } from '@stencil/core';
import { FilterGroupCondition } from '../../interfaces/IExpressionItem';
import { ApplicationUtils } from "@sankhyalabs/ezui/dist/collection/utils";
import { ApplicationContext, ElementIDUtils, StringUtils } from '@sankhyalabs/core';
export class SnkExpressionGroup {
  constructor() {
    this.FIRST_LEVEL = "0";
    this.LIMIT_GROUP_LEVEL = 4;
    this.application = ApplicationContext.getContextValue("__SNK__APPLICATION__");
    this._conditionOperator = FilterGroupCondition.AND;
    this._group = undefined;
    this._selfTop = 0;
    this.canAddExpression = true;
    this._showDashes = true;
    this.parentTop = 0;
    this.group = undefined;
    this.messagesBuilder = undefined;
    this.filterId = undefined;
    this.entityURI = undefined;
    this.isDefaultFilter = false;
  }
  /**
   * Listener para capturar adição e remoção de grupos e items de expressão.
   */
  todoCompletedHandler(_) {
    this.updateDashes();
  }
  /*
   * Retorna o grupo da expressão.
   */
  async getExpressionGroup() {
    return this._group;
  }
  watchGroup(newValue) {
    this._group = newValue;
    this._conditionOperator = this.getOperand();
  }
  componentWillLoad() {
    this._group = this.group;
    this._conditionOperator = this.getOperand();
    if (!this.getDataGroupLevel()) {
      this._element.setAttribute('data-group-level', this.FIRST_LEVEL);
    }
    this.canAddExpression = this.group.items.every(this.isFilledItem);
  }
  componentDidRender() {
    this.setSelfTop();
  }
  changeHandler() {
    this.ezExpressionGroupLayoutChanged.emit();
  }
  /**
   * Função que define o valor atualizado da propriedade top do elemento em tela para calcular o tamanho do tracejado.
   */
  setSelfTop() {
    this._selfTop = this._element.getBoundingClientRect().top;
  }
  /**
   * Função que calcula o tamanho que deve ter o tracejado.
   */
  getDashedHeight() {
    return this._selfTop - this.parentTop;
  }
  getOperand() {
    return !this._group.operand ? FilterGroupCondition.AND : this._group.operand;
  }
  getMessage(key, params) {
    return this.application.messagesBuilder.getMessage(key, params);
  }
  updateDashes() {
    this._showDashes = false;
    this.setSelfTop();
    this._showDashes = true;
  }
  renderExpressionItems() {
    var _a;
    return (_a = this._group.items) === null || _a === void 0 ? void 0 : _a.map((item) => (h("snk-expression-item", { key: item.id, class: "ez-padding-top--small snk-expression-group__item", expression: item, canRemove: this._group.items.length > 1, onEzFilterItemChange: () => this.handleFilterItemChange(), onEzFilterItemRemove: (evt) => this.handleFilterItemRemove(evt, item.id), messagesBuilder: this.messagesBuilder, entityURI: this.entityURI, isDefaultFilter: this.isDefaultFilter })));
  }
  renderGroups() {
    var _a;
    const currentLevel = parseInt(this.getDataGroupLevel() || '0');
    const newLevel = currentLevel + 1;
    return (_a = this._group.childrenGroups) === null || _a === void 0 ? void 0 : _a.map((group) => (h("snk-expression-group", { key: group.id, group: group, messagesBuilder: this.messagesBuilder, parentTop: this._selfTop, "data-group-level": newLevel, onEzFilterGroupRemove: (evt) => this.handleFilterGroupRemove(evt, group.id), entityURI: this.entityURI })));
  }
  handleFilterGroupRemove(evt, groupId) {
    this.onStopPropagation(evt);
    this._group.childrenGroups = this._group.childrenGroups.filter(group => group.id !== groupId);
    forceUpdate(this);
    this.ezFilterGroupChange.emit(this._group);
    this.changeHandler();
  }
  handleFilterItemRemove(evt, itemId) {
    this.onStopPropagation(evt);
    this._group.items = this._group.items.filter(item => item.id !== itemId);
    forceUpdate(this);
    this.ezFilterGroupChange.emit(this._group);
    this.changeHandler();
    this.canAddExpression = true;
  }
  isFilledItem(item) {
    if (!item.fieldName || !item.operand)
      return false;
    if (item.operand === 'NULL' || item.operand === 'NOT_NULL') {
      return true;
    }
    else {
      return item.paramVariable || (item.userInterface === 'SWITCH') ? true : !!item.value;
    }
  }
  handleFilterItemChange() {
    this.ezFilterGroupChange.emit(this._group);
    this.canAddExpression = this.group.items.every(this.isFilledItem);
  }
  handleAddExpression() {
    const newItem = {
      id: StringUtils.generateUUID(),
      entityName: "",
      fieldName: "",
      description: "",
      label: this.getMessage("snkPersonalizedFilter.info.labelDefaultValue"),
      type: undefined,
      expression: undefined,
      operand: undefined,
      paramVariable: false,
      value: undefined,
      systemConfig: null,
      userConfig: null
    };
    this._group.items.push(newItem);
    forceUpdate(this);
    this.ezFilterGroupChange.emit(this.group);
    this.changeHandler();
    this.canAddExpression = false;
  }
  handleAddGroup() {
    var _a;
    const newGroup = {
      id: StringUtils.generateUUID(),
      items: [
        {
          id: StringUtils.generateUUID(),
          entityName: "",
          fieldName: "",
          description: "",
          label: this.getMessage("snkPersonalizedFilter.info.labelDefaultValue"),
          type: undefined,
          expression: undefined,
          operand: undefined,
          paramVariable: false,
          value: undefined,
          systemConfig: null,
          userConfig: null
        }
      ],
      childrenGroups: [],
      operand: FilterGroupCondition.AND
    };
    this._group.childrenGroups = (_a = this._group.childrenGroups) !== null && _a !== void 0 ? _a : [];
    this._group.childrenGroups.push(newGroup);
    forceUpdate(this);
    if (!this.group.operand) {
      this.group.operand = FilterGroupCondition.AND;
    }
    this.ezFilterGroupChange.emit(this.group);
    this.changeHandler();
  }
  buildGroupStyle() {
    return {
      height: `${this.getDashedHeight()}px`,
      marginTop: `${-(this.getDashedHeight()) + 20}px`,
    };
  }
  handleConditionOperatorChange(newOperator) {
    this._conditionOperator = newOperator;
    this._group.operand = FilterGroupCondition[newOperator];
    this.ezFilterGroupChange.emit(this._group);
  }
  confirmRemoveGroup(evt) {
    this.onStopPropagation(evt);
    ApplicationUtils.confirm(this.getMessage("snkPersonalizedFilter.confirmGroup.title"), this.getMessage("snkPersonalizedFilter.confirmGroup.description"))
      .then((canRemove) => {
      if (canRemove) {
        this.ezFilterGroupRemove.emit(this._group);
      }
    });
  }
  getTooltipMessageForOperator() {
    const groupLevel = this.getDataGroupLevel();
    if (groupLevel === this.FIRST_LEVEL && this._group.items.length === 1) {
      return this.getMessage("snkPersonalizedFilter.operador.firstLevel");
    }
    if (this._conditionOperator === FilterGroupCondition.AND) {
      return this.getMessage("snkPersonalizedFilter.operador.and");
    }
    else if (this._conditionOperator === FilterGroupCondition.OR) {
      return this.getMessage("snkPersonalizedFilter.operador.or");
    }
  }
  getDataGroupLevel() {
    return this._element.getAttribute('data-group-level');
  }
  canAddGroup() {
    const dataGroupLevel = Number(this.getDataGroupLevel() || this.FIRST_LEVEL);
    return dataGroupLevel < this.LIMIT_GROUP_LEVEL;
  }
  isFirstLevel() {
    return Boolean(this.getDataGroupLevel() === this.FIRST_LEVEL);
  }
  onStopPropagation(evt) {
    evt.preventDefault();
    evt.stopPropagation();
  }
  getMessageAddTooltip() {
    if (this.isFirstLevel()) {
      const allValidItems = this.group.items.every(item => {
        if (!item.fieldName || !item.operand)
          return false;
        return item.paramVariable || !!item.value;
      });
      return allValidItems ? this.getMessage("snkPersonalizedFilter.info.labelAddNewExpression") : this.getMessage("snkPersonalizedFilter.info.labelDisabledAddExpressionButton");
    }
    else {
      return this.canAddExpression ? this.getMessage("snkPersonalizedFilter.info.labelAddNewExpression") : this.getMessage("snkPersonalizedFilter.info.labelDisabledAddExpressionButton");
    }
  }
  canChangeGroupCondition() {
    const membersCount = this._group.items.length + this._group.childrenGroups.length;
    return membersCount > 1;
  }
  render() {
    const canAddGroup = this.canAddGroup();
    return (h(Host, null, h("div", { class: !this.isFirstLevel() && this._showDashes ? 'dashes' : 'hidden', style: this.buildGroupStyle() }), h("div", { class: !this.isFirstLevel() && this._showDashes ? 'horizontal-dashes' : 'hidden' }), h("div", { class: 'ez-flex ez-flex--align-items-center' }, h("div", { class: 'snk-expression-group__container-condition ez-flex ez-flex-item--align-center ez-flex--align-items-center', "data-condition": this._conditionOperator, title: this.getTooltipMessageForOperator() }, h("label", { class: "ez-label ez-padding-right--medium ez-padding-left--medium ez-title--primary" }, this.getMessage("snkPersonalizedFilter.info.condition")), h("div", null, h("ez-combo-box", Object.assign({ class: "snk-expression-group__container-option", canShowError: false, mode: "slim", suppressEmptyOption: true, enabled: this.canChangeGroupCondition(), value: this._conditionOperator, onEzChange: (evt) => this.handleConditionOperatorChange(evt.detail.value) }, { [ElementIDUtils.DATA_ELEMENT_ID_ATTRIBUTE_NAME]: `comboBoxConditions_level_${this.getDataGroupLevel()}` }), h("option", { value: FilterGroupCondition.AND }, this.getMessage("snkPersonalizedFilter.info.conditionAnd")), h("option", { value: FilterGroupCondition.OR }, this.getMessage("snkPersonalizedFilter.info.conditionOr"))))), h("ez-button", { class: "ez-padding-right--medium ez-padding-left--medium", mode: "icon", iconName: "plus", size: "small", enabled: this.canAddExpression, title: this.getMessageAddTooltip(), onClick: () => this.handleAddExpression() }), h("ez-button", { label: this.getMessage("snkPersonalizedFilter.info.addGroup"), size: "small", enabled: canAddGroup, title: !canAddGroup ? this.getMessage('snkPersonalizedFilter.info.labelDisabledAddGroupButton', { LIMIT_GROUP_LEVEL: this.LIMIT_GROUP_LEVEL + 1 }) : '', onClick: () => this.handleAddGroup() }, h("ez-icon", { class: "ez-padding-right--small", slot: "leftIcon", iconName: "plus" })), !this.isFirstLevel() && h("ez-button", { title: this.getMessage("snkPersonalizedFilter.info.labelDeleteExpression"), class: "ez-padding-left--medium", mode: "icon", iconName: "delete", size: "small", onClick: (evt) => this.confirmRemoveGroup(evt) })), h("div", { class: "ez-padding-top--small snk-expression-group__container-expression" }, h("div", { class: "ez-padding-top--small" }, this.renderExpressionItems())), h("div", { class: "ez-padding-top--small snk-expression-group__container-expression" }, h("div", { class: "ez-padding-top--small" }, this.renderGroups()))));
  }
  static get is() { return "snk-expression-group"; }
  static get encapsulation() { return "scoped"; }
  static get originalStyleUrls() {
    return {
      "$": ["snk-expression-group.css"]
    };
  }
  static get styleUrls() {
    return {
      "$": ["snk-expression-group.css"]
    };
  }
  static get properties() {
    return {
      "parentTop": {
        "type": "number",
        "mutable": true,
        "complexType": {
          "original": "number",
          "resolved": "number",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Tamanho do elemento pai do grupo"
        },
        "attribute": "parent-top",
        "reflect": false,
        "defaultValue": "0"
      },
      "group": {
        "type": "unknown",
        "mutable": true,
        "complexType": {
          "original": "IExpressionGroup",
          "resolved": "IExpressionGroup",
          "references": {
            "IExpressionGroup": {
              "location": "import",
              "path": "../../interfaces/IExpressionItem"
            }
          }
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Grupo que ser\u00E1 representado visualmente pelo componente."
        }
      },
      "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."
        }
      },
      "filterId": {
        "type": "string",
        "mutable": true,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Id do filtro que ser\u00E1 carregado."
        },
        "attribute": "filter-id",
        "reflect": false
      },
      "entityURI": {
        "type": "string",
        "mutable": true,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Identificador da unidade de dados."
        },
        "attribute": "entity-u-r-i",
        "reflect": false
      },
      "isDefaultFilter": {
        "type": "boolean",
        "mutable": false,
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Define se o filtro em quest\u00E3o \u00E9 um filtro padr\u00E3o."
        },
        "attribute": "is-default-filter",
        "reflect": false,
        "defaultValue": "false"
      }
    };
  }
  static get states() {
    return {
      "_conditionOperator": {},
      "_group": {},
      "_selfTop": {},
      "canAddExpression": {},
      "_showDashes": {}
    };
  }
  static get events() {
    return [{
        "method": "ezFilterGroupChange",
        "name": "ezFilterGroupChange",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": "Emitido quando ocorrer altera\u00E7\u00F5es no grupo."
        },
        "complexType": {
          "original": "IExpressionGroup",
          "resolved": "IExpressionGroup",
          "references": {
            "IExpressionGroup": {
              "location": "import",
              "path": "../../interfaces/IExpressionItem"
            }
          }
        }
      }, {
        "method": "ezFilterGroupRemove",
        "name": "ezFilterGroupRemove",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": "Emitido ao pressionar o bot\u00E3o de remover grupo."
        },
        "complexType": {
          "original": "IExpressionGroup",
          "resolved": "IExpressionGroup",
          "references": {
            "IExpressionGroup": {
              "location": "import",
              "path": "../../interfaces/IExpressionItem"
            }
          }
        }
      }, {
        "method": "ezExpressionGroupLayoutChanged",
        "name": "ezExpressionLayoutChanged",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": "Emitido ao alterar quantidade de grupos ou express\u00F5es"
        },
        "complexType": {
          "original": "null",
          "resolved": "null",
          "references": {}
        }
      }];
  }
  static get methods() {
    return {
      "getExpressionGroup": {
        "complexType": {
          "signature": "() => Promise<IExpressionGroup>",
          "parameters": [],
          "references": {
            "Promise": {
              "location": "global"
            },
            "IExpressionGroup": {
              "location": "import",
              "path": "../../interfaces/IExpressionItem"
            }
          },
          "return": "Promise<IExpressionGroup>"
        },
        "docs": {
          "text": "",
          "tags": []
        }
      }
    };
  }
  static get elementRef() { return "_element"; }
  static get watchers() {
    return [{
        "propName": "group",
        "methodName": "watchGroup"
      }];
  }
  static get listeners() {
    return [{
        "name": "ezExpressionLayoutChanged",
        "method": "todoCompletedHandler",
        "target": "window",
        "capture": false,
        "passive": false
      }];
  }
}
