import { Host, h } from '@stencil/core';
import { ApplicationContext, ElementIDUtils, UserInterface } from '@sankhyalabs/core';
import { SelectedItemType } from "../../../snk-filter-field-search/interfaces";
import { CheckMode, ApplicationUtils } from "@sankhyalabs/ezui/dist/collection/utils";
import { fieldBuilder } from "@sankhyalabs/ezui/dist/collection/components/ez-form-view/fieldbuilder/FieldBuilder";
import { FilterOperand } from '../../interfaces/index';
import { FilterOperandDefault, FilterOperandTypeTextSearch, FIELD_TYPE_SEARCH_AND_TEXT } from "./filter-operands/filter-operands";
import store from '../../../../lib/store';
import { convertType } from '@sankhyalabs/core/dist/dataunit/metadata/DataType';
export class SnkExpressionItem {
  constructor() {
    this.application = ApplicationContext.getContextValue("__SNK__APPLICATION__");
    this.filterOperandDefault = FilterOperandDefault;
    this.filterOperandTypeTextSearch = FilterOperandTypeTextSearch;
    this.DEFAULT_FIELD_NAME = 'NOT_DEFINED';
    this._showValueVariable = false;
    this._fieldSelected = undefined;
    this._optionNotNull = false;
    this.expression = undefined;
    this.canRemove = true;
    this.messagesBuilder = undefined;
    this.isDefaultFilter = false;
    this.entityURI = undefined;
  }
  expressionChanged(newValue, oldValue) {
    if (newValue !== oldValue) {
      this.ezFilterItemChange.emit(newValue);
      this.updateFieldSelected();
    }
  }
  componentWillLoad() {
    this._dataSourceFetcher = store.get(`filterFieldsDataSource.${this.entityURI}`);
    store.onChange(`filterFieldsDataSource.${this.entityURI}`, () => {
      this._dataSourceFetcher = store.get(`filterFieldsDataSource.${this.entityURI}`);
    });
    if (this.expression) {
      this.updateFieldSelected();
      this._optionNotNull = this.expression.operand === 'NULL' || this.expression.operand === 'NOT_NULL';
    }
  }
  componentDidRender() {
    var _a;
    this._showValueVariable = (_a = this._elValueVariable) === null || _a === void 0 ? void 0 : _a.value;
  }
  updateFieldSelected() {
    const field = {
      dataType: this.expression.type,
      description: this.expression.description,
      name: this.expression.fieldName,
      label: this.expression.fieldLabel,
      entityName: this.expression.entityName,
      onlyDate: false,
      path: this.expression.description,
      properties: this.expressionPropsToFieldProps(this.expression.props),
      type: SelectedItemType.FIELD,
      uri: "",
      userInterface: this.expression.userInterface
    };
    this._fieldSelected = field;
  }
  buildExpression(entityName, fieldName, entityPath) {
    if (entityPath.length > 0) {
      entityPath.shift();
    }
    return entityPath.length > 0 ? `${entityPath.join("->")}->${fieldName}` : `${entityName}.${fieldName}`;
  }
  setValueExpression(key, value) {
    if (key === "fieldName") {
      this.expression.description = value.path;
      this.expression.expression = this.buildExpression(value.entityName, value.name, value.entityPath);
      this.expression.fieldName = value.name;
      this.expression.fieldLabel = value.label;
      this.expression.type = value.dataType;
      this.expression.userInterface = value.userInterface;
      this.expression.entityName = value.entityName;
      this.expression.value = undefined;
      this.expression.props = this.fieldPropsToExpressionProps(value.properties);
    }
    else {
      this.expression[key] = value;
    }
    this.expressionChanged(this.expression);
  }
  fieldPropsToExpressionProps(properties) {
    const parsedProps = [];
    if (!properties) {
      return parsedProps;
    }
    for (const key in properties) {
      let propValue = properties[key];
      if (typeof propValue == "object") {
        propValue = JSON.stringify(propValue);
      }
      parsedProps.push({ name: key, value: propValue });
    }
    return parsedProps;
  }
  expressionPropsToFieldProps(properties) {
    const parsedProps = {};
    if (!properties) {
      return parsedProps;
    }
    properties.forEach(prop => {
      try {
        parsedProps[prop.name] = JSON.parse(prop.value);
      }
      catch (_a) {
        parsedProps[prop.name] = prop.value;
      }
    });
    return parsedProps;
  }
  getMessage(key, params) {
    return this.application.messagesBuilder.getMessage(key, params);
  }
  handleSelectItem(filterField) {
    if (this.hasNoChanges(filterField)) {
      this._elFilterInput.value = filterField.path;
      return;
    }
    if (filterField.type === SelectedItemType.FIELD) {
      const field = filterField;
      this._fieldSelected = field;
      this.setValueExpression("fieldName", field);
    }
  }
  hasNoChanges(filterField) {
    return filterField.name === this.expression.fieldName && filterField.path === this.expression.description;
  }
  handleFocus() {
    if (this._elFilterFieldSearch)
      this._elFilterFieldSearch.show();
  }
  handleChangeFilterInput(evt) {
    this._elFilterFieldSearch.applyFilter(evt.detail);
  }
  handleChangeValueVariable(showValueVariable) {
    this._showValueVariable = showValueVariable;
    if (this._elFieldDynamic) {
      this._elFieldDynamic.value = undefined;
      this._elFieldDynamic.enabled = !showValueVariable;
    }
    this.expression["paramVariable"] = showValueVariable;
    this.expressionChanged(this.expression);
  }
  openSnkFilterParamConfig() {
    var _a;
    (_a = this._elFilterParamConfigRef) === null || _a === void 0 ? void 0 : _a.open(this.expression).then(this.onOpenPromiseReady.bind(this)).catch(error => {
      console.error(error);
    });
  }
  onOpenPromiseReady(changes) {
    this.expression = changes;
  }
  buildOptionsOperator() {
    var _a;
    if (FIELD_TYPE_SEARCH_AND_TEXT.includes((_a = this._fieldSelected) === null || _a === void 0 ? void 0 : _a.userInterface)) {
      return this.translateOperandOptions(this.filterOperandTypeTextSearch);
    }
    else {
      return this.translateOperandOptions(this.filterOperandDefault);
    }
  }
  translateOperandOptions(options) {
    return options.map(option => ({ label: this.getMessage(option.label), value: option.value }));
  }
  handleChangeOperator(optionSelected) {
    this.checkOptionIsNull(optionSelected);
    this.setValueExpression("operand", optionSelected);
  }
  checkOptionIsNull(optionSelected) {
    const filterOperandValue = FilterOperand[optionSelected];
    if ([FilterOperand.NULL, FilterOperand.NOT_NULL].includes(filterOperandValue)) {
      this._optionNotNull = true;
      if (this._elFieldDynamic) {
        this._elFieldDynamic.enabled = false;
        this._elFieldDynamic.value = undefined;
      }
    }
    else {
      this._optionNotNull = false;
      if (this._elFieldDynamic) {
        this._elFieldDynamic.enabled = this._showValueVariable ? false : true;
      }
    }
  }
  confirmRemove(evt) {
    evt.preventDefault();
    evt.stopPropagation();
    ApplicationUtils.confirm(this.getMessage("snkPersonalizedFilter.confirmExpression.title"), this.getMessage("snkPersonalizedFilter.confirmExpression.description"))
      .then((canRemove) => {
      if (canRemove) {
        this.ezFilterItemRemove.emit(this.expression);
      }
    });
  }
  buildFieldByType() {
    var _a, _b, _c;
    if (!this._fieldSelected)
      return;
    const inputFieldData = (_a = fieldBuilder(this.configureFieldByType())) === null || _a === void 0 ? void 0 : _a.$children$.shift();
    if (this._optionNotNull && inputFieldData || ((_b = this._elValueVariable) === null || _b === void 0 ? void 0 : _b.value) && inputFieldData || this.expression.paramVariable || this._showValueVariable || !((_c = this._fieldSelected) === null || _c === void 0 ? void 0 : _c.dataType)) {
      inputFieldData.$attrs$.enabled = false;
    }
    if (this.expression.value != undefined) {
      inputFieldData.$attrs$.value = this.getExpressiontValue(this.expression);
    }
    inputFieldData.$attrs$.onEzChange = (event) => {
      this.setValueExpression("value", event.target.value);
    };
    if (this.expression.userInterface === 'SWITCH' && this.expression.value == undefined) {
      this.setValueExpression("value", false);
    }
    return h(inputFieldData.$tag$, Object.assign(Object.assign({}, inputFieldData.$attrs$), { ref: (el) => {
        this._elFieldDynamic = el;
      }, label: this.expression.fieldLabel || this._fieldSelected.label }));
  }
  getExpressiontValue(expression) {
    return convertType(expression.type, expression.value);
  }
  configureFieldByType() {
    var _a, _b;
    const field = {
      userInterface: this._fieldSelected.userInterface,
      name: this._fieldSelected.name,
      label: this._fieldSelected.label,
      canShowError: false
    };
    switch (field.userInterface) {
      case UserInterface.OPTIONSELECTOR:
        field.props = {
          options: (_b = (_a = this._fieldSelected) === null || _a === void 0 ? void 0 : _a.properties) === null || _b === void 0 ? void 0 : _b.options,
        };
        break;
      case UserInterface.LONGTEXT:
        field.rows = 1;
        break;
      case UserInterface.SEARCH:
        field.optionLoader = searchArgument => this.setCriteriaSearch(searchArgument, this.application);
        break;
      default:
        break;
    }
    return field;
  }
  setCriteriaSearch({ mode, argument }, application) {
    var _a, _b, _c;
    if (application == undefined)
      return;
    const searchOptions = {
      showInactives: false
    };
    const options = {
      entity: (_c = (_b = (_a = this._fieldSelected) === null || _a === void 0 ? void 0 : _a.properties) === null || _b === void 0 ? void 0 : _b.ENTITYNAME) !== null && _c !== void 0 ? _c : this._fieldSelected.entityName,
      searchOptions,
      entityDescription: this._fieldSelected.description
    };
    return application.executePreparedSearch(mode, argument, options);
  }
  render() {
    var _a;
    return (h(Host, null, h("div", { class: "dashes" }), h("div", { class: "box" }, h("div", { class: "box__container" }, h("div", { class: "box__container--input-filter" }, h("ez-filter-input", Object.assign({ ref: ref => this._elFilterInput = ref, value: (_a = this._fieldSelected) === null || _a === void 0 ? void 0 : _a.path, label: this.getMessage("snkPersonalizedFilter.info.labelSearchField"), canShowError: false, onEzChange: (evt) => this.handleChangeFilterInput(evt), onFocus: () => this.handleFocus() }, { [ElementIDUtils.DATA_ELEMENT_ID_ATTRIBUTE_NAME]: `expressionFilterInput_${this.expression.fieldName || this.DEFAULT_FIELD_NAME}` })), h("snk-filter-field-search", { ref: ref => this._elFilterFieldSearch = ref, searchable: false, onEzSelectFilterItem: (ev) => this.handleSelectItem(ev.detail), fieldsDataSource: this._dataSourceFetcher })), h("div", { class: "box__container--input-operator" }, h("ez-combo-box", Object.assign({ label: this.getMessage("snkPersonalizedFilter.info.labelOperator"), value: this.expression.operand, canShowError: false, options: this.buildOptionsOperator(), onEzChange: (evt) => { var _a; return this.handleChangeOperator((_a = evt.detail) === null || _a === void 0 ? void 0 : _a.value); }, suppressEmptyOption: true }, { [ElementIDUtils.DATA_ELEMENT_ID_ATTRIBUTE_NAME]: `comboBoxOperand_${this.expression.fieldName || this.DEFAULT_FIELD_NAME}` }))), h("div", { class: "box__container--input-value" }, !this._fieldSelected ? (h("ez-number-input", { label: this.getMessage('snkPersonalizedFilter.info.labelDefaultValue'), canShowError: false, enabled: !this._showValueVariable && !this._optionNotNull })) : (this.buildFieldByType())), h("div", { class: "box__container--input-value-variable" }, !this._optionNotNull &&
      h("ez-tooltip", { message: this.getMessage("snkPersonalizedFilter.info.checkVariableDisabled"), active: this.isDefaultFilter }, h("ez-check", { ref: ref => this._elValueVariable = ref, value: this.expression.paramVariable, label: this.getMessage("snkPersonalizedFilter.info.labelValueVarible"), mode: CheckMode.SWITCH, onEzChange: (evt) => this.handleChangeValueVariable(evt.detail), enabled: !this.isDefaultFilter })), (this._showValueVariable && !this._optionNotNull) &&
      h("ez-icon", Object.assign({ class: "box__container--input-value-variable--icon", size: "large", iconName: "settings-inverted" }, { [ElementIDUtils.DATA_ELEMENT_ID_ATTRIBUTE_NAME]: 'iconConfig' }, { title: this.getMessage("snkPersonalizedFilter.info.titleTooltip"), onClick: () => this.openSnkFilterParamConfig() })), h("snk-filter-param-config", { ref: (el) => this._elFilterParamConfigRef = el, messagesBuilder: this.messagesBuilder })), h("div", { class: "box__container--button-delete" }, h("div", { class: "box__container--button-delete--icon" }, h("ez-button", { mode: "icon", iconName: "delete", enabled: this.canRemove, label: this.getMessage("snkPersonalizedFilter.info.labelDeleteItem"), onClick: (evt) => this.confirmRemove(evt) })))))));
  }
  static get is() { return "snk-expression-item"; }
  static get encapsulation() { return "scoped"; }
  static get originalStyleUrls() {
    return {
      "$": ["snk-expression-item.css"]
    };
  }
  static get styleUrls() {
    return {
      "$": ["snk-expression-item.css"]
    };
  }
  static get properties() {
    return {
      "expression": {
        "type": "unknown",
        "mutable": false,
        "complexType": {
          "original": "IExpressionItem",
          "resolved": "IExpressionItem",
          "references": {
            "IExpressionItem": {
              "location": "import",
              "path": "../../interfaces/IExpressionItem"
            }
          }
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Express\u00E3o que ser\u00E1 representada visualmente."
        },
        "defaultValue": "undefined"
      },
      "canRemove": {
        "type": "boolean",
        "mutable": false,
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Controla a exibi\u00E7\u00E3o do bot\u00E3o Remover."
        },
        "attribute": "can-remove",
        "reflect": true,
        "defaultValue": "true"
      },
      "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."
        }
      },
      "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"
      },
      "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
      }
    };
  }
  static get states() {
    return {
      "_showValueVariable": {},
      "_fieldSelected": {},
      "_optionNotNull": {}
    };
  }
  static get events() {
    return [{
        "method": "ezFilterItemChange",
        "name": "ezFilterItemChange",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": "Emitido quando acontece altera\u00E7\u00F5es na express\u00E3o."
        },
        "complexType": {
          "original": "IExpressionItem",
          "resolved": "IExpressionItem",
          "references": {
            "IExpressionItem": {
              "location": "import",
              "path": "../../interfaces/IExpressionItem"
            }
          }
        }
      }, {
        "method": "ezFilterItemRemove",
        "name": "ezFilterItemRemove",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": "Emitido ao confirmar uma remo\u00E7\u00E3o."
        },
        "complexType": {
          "original": "IExpressionItem",
          "resolved": "IExpressionItem",
          "references": {
            "IExpressionItem": {
              "location": "import",
              "path": "../../interfaces/IExpressionItem"
            }
          }
        }
      }];
  }
  static get watchers() {
    return [{
        "propName": "expression",
        "methodName": "expressionChanged"
      }];
  }
}
