import { h, forceUpdate } from '@stencil/core';
import { ApplicationContext, ObjectUtils, StringUtils, UserInterface, } from '@sankhyalabs/core';
import { DEFAULT_TYPE, TAGS_BY_TYPE, VARS_BY_TYPE } from '../../../../lib/utils/constants';
import { getConvertedValue } from '@sankhyalabs/core/dist/dataunit/metadata/DataType';
import { CheckMode } from '@sankhyalabs/ezui/dist/collection/utils';
import { getEnabledByProperty, getValidatedFieldValue, getValueByProperty } from '../../FormConfigHelper';
export class FieldConfig {
  constructor() {
    this.fieldLabel = undefined;
    this.fieldLabelErrorMessage = undefined;
    this.fieldDefaultValue = undefined;
    this.fieldCleanOnCopy = undefined;
    this.fieldRequired = undefined;
    this.fieldReadOnly = undefined;
    this._defaultType = undefined;
    this.dataUnit = undefined;
    this.fieldConfig = undefined;
    this.fieldDescriptor = undefined;
    this.messagesBuilder = undefined;
  }
  observeFieldLabel() {
    if (this.validateFieldLabel) {
      this.fieldLabelErrorMessage = undefined;
    }
  }
  async show(_anchorElement) {
    this._popoupElement.opened = true;
    this.initializeValues();
    forceUpdate(this);
  }
  validateFieldLabel() {
    var _a;
    if ((_a = this.fieldLabel) === null || _a === void 0 ? void 0 : _a.trim())
      return true;
    this.applyErrorMessage();
    return false;
  }
  getMessage(key, params) {
    return this.messagesBuilder.getMessage(key, params);
  }
  isAllowDefault() {
    var _a;
    const allowDefault = (_a = this.fieldDescriptor.properties) === null || _a === void 0 ? void 0 : _a.allowDefault;
    if (allowDefault == undefined) {
      return true;
    }
    return allowDefault === 'true';
  }
  enabledValueDefault() {
    var _a, _b, _c;
    const allowDefault = (_a = this.fieldDescriptor.properties) === null || _a === void 0 ? void 0 : _a.allowDefault;
    const hasVariableVar = (VARS_BY_TYPE.UserInterface.hasOwnProperty((_b = this.fieldDescriptor) === null || _b === void 0 ? void 0 : _b.userInterface)
      || ((_c = this.fieldDescriptor) === null || _c === void 0 ? void 0 : _c.userInterface) === UserInterface.SEARCH);
    return hasVariableVar && (allowDefault == undefined || allowDefault === 'true');
  }
  getDefaultType() {
    var _a, _b;
    return (_b = (_a = this.fieldDefaultValue) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : DEFAULT_TYPE.fixed;
  }
  emitFieldChanged() {
    this.fieldConfigChanged.emit(this.fieldConfig);
  }
  handleLabelChanged({ detail }) {
    this.fieldLabel = detail;
  }
  handleDefaultTypeChanged({ detail }) {
    const optionSelected = detail.value;
    if (optionSelected == undefined)
      return;
    this._defaultType = optionSelected;
    this.fieldDefaultValue = { type: this._defaultType };
  }
  handleDefaultValueChanged({ detail }) {
    this.fieldDefaultValue.value = detail === null || detail === void 0 ? void 0 : detail.value;
  }
  onChangeDefaultValue(fieldValue) {
    this.fieldDefaultValue.value = getValidatedFieldValue(fieldValue, this.dataUnit, this.fieldConfig.name);
  }
  handleClearDuplicateChanged({ detail }) {
    this.fieldCleanOnCopy = detail;
  }
  handleRequiredChanged({ detail }) {
    this.fieldRequired = detail;
  }
  handleReadOnlyChanged({ detail }) {
    this.fieldReadOnly = detail;
  }
  loadDefaultValue() {
    var _a;
    if ((_a = this.fieldConfig.defaultValue) === null || _a === void 0 ? void 0 : _a.type) {
      this._defaultType = this.fieldConfig.defaultValue.type;
      return;
    }
    this._defaultType = DEFAULT_TYPE.fixed;
    this.fieldConfig.defaultValue = { type: this._defaultType };
  }
  buildOptions() {
    let interfaceField = this.fieldDescriptor.userInterface;
    if (interfaceField === UserInterface.SEARCH) {
      interfaceField = UserInterface.INTEGERNUMBER;
    }
    return VARS_BY_TYPE.UserInterface[interfaceField];
  }
  renderDefaultValueEditor() {
    if (this._defaultType === DEFAULT_TYPE.variable) {
      return (h("ez-combo-box", { label: this.getMessage('snkConfigOptions.label.valueDefault'), enabled: this.isAllowDefault(), onEzChange: (e) => this.handleDefaultValueChanged(e), value: this.fieldDefaultValue.value, options: this.buildOptions() }));
    }
    return this.fieldDescriptor.userInterface &&
      this.buildFieldDefaultValueElement();
  }
  buildFieldDefaultValueElement() {
    var _a;
    const { userInterface, properties, dataType } = this.fieldDescriptor;
    const allowDefault = properties === null || properties === void 0 ? void 0 : properties.allowDefault;
    let value;
    let enabled = StringUtils.getBooleanValue(allowDefault, !this.fieldReadOnly);
    if (userInterface === UserInterface.FILE) {
      enabled = false;
    }
    if (enabled) {
      value = (_a = this.fieldDefaultValue) === null || _a === void 0 ? void 0 : _a.value;
      if (value != undefined) {
        value = getConvertedValue(dataType, value);
      }
    }
    const configField = {
      value,
      enabled,
      label: this.fieldConfig.label,
      name: this.fieldConfig.name,
      required: this.fieldRequired,
      userInterface,
    };
    switch (userInterface) {
      case UserInterface.SWITCH:
        return this.buildInputDefault(configField, undefined, CheckMode.SWITCH);
      case UserInterface.CHECKBOX:
        return this.buildInputDefault(configField, undefined, CheckMode.REGULAR);
      case UserInterface.OPTIONSELECTOR:
      case UserInterface.DECIMALNUMBER:
        return this.buildInputDefault(configField, properties);
      default:
        return this.buildInputDefault(configField);
    }
  }
  buildInputDefault({ value, enabled, label, name, required, userInterface }, properties = undefined, mode = undefined) {
    let options;
    let precision = 0;
    let prettyPrecision = 0;
    const TagName = userInterface == undefined || TAGS_BY_TYPE[userInterface] == undefined
      ? TAGS_BY_TYPE.DEFAULT
      : TAGS_BY_TYPE[userInterface];
    if (userInterface === UserInterface.OPTIONSELECTOR) {
      const prop = properties === null || properties === void 0 ? void 0 : properties.options;
      if (typeof prop === 'string') {
        const parsed = ObjectUtils.stringToObject(prop);
        options = Object.keys(parsed).map(key => {
          return { value: key, label: parsed[key] };
        });
      }
      else {
        options = prop;
      }
    }
    else if (userInterface === UserInterface.DECIMALNUMBER) {
      precision = Number((properties === null || properties === void 0 ? void 0 : properties.precision) || 2);
      prettyPrecision = Number((properties === null || properties === void 0 ? void 0 : properties.prettyPrecision) || precision);
    }
    return h(TagName, Object.assign({ value: value, enabled: enabled, label: label, "data-field-name": name, key: name, onEzChange: (evt) => this.onChangeDefaultValue(evt === null || evt === void 0 ? void 0 : evt.detail) }, (this.getConditionalAttributes(userInterface, required, options, precision, prettyPrecision, mode))));
  }
  getConditionalAttributes(userInterface, required, options, precision, prettyPrecision, mode) {
    const useSearchPlus = userInterface == UserInterface.SEARCHPLUS;
    switch (userInterface) {
      case UserInterface.SEARCH:
      case UserInterface.SEARCHPLUS:
        return {
          suppressEmptyOption: required,
          optionLoader: (searchArgument) => this.onSearchDefaultValue(searchArgument, { useSearchPlus }),
        };
      case UserInterface.OPTIONSELECTOR:
        return {
          suppressEmptyOption: required,
          options,
        };
      case UserInterface.CHECKBOX:
      case UserInterface.SWITCH:
        return {
          mode,
        };
      case UserInterface.INTEGERNUMBER:
      case UserInterface.DECIMALNUMBER:
        return {
          precision,
          prettyPrecision,
          onEzStartChange: (evt) => this.onChangeDefaultValue(evt === null || evt === void 0 ? void 0 : evt.detail),
        };
      case UserInterface.DATE:
      case UserInterface.DATETIME:
      case UserInterface.TIME:
        return {
          onEzStartChange: (evt) => this.onChangeDefaultValue(evt === null || evt === void 0 ? void 0 : evt.detail),
        };
      default:
        return {};
    }
  }
  onSearchDefaultValue(searchArgument, ctxOptions) {
    if (this._application && this.fieldConfig) {
      return this._application.executeSearch(searchArgument, this.fieldConfig.name, this.dataUnit, ctxOptions);
    }
  }
  initializeValues() {
    this.fieldLabel = this.fieldConfig.label;
    this.fieldDefaultValue = this.fieldConfig.defaultValue;
    this.fieldRequired = this.fieldConfig.required;
    this.fieldReadOnly = this.fieldConfig.readOnly;
    this.fieldCleanOnCopy = this.fieldConfig.cleanOnCopy;
  }
  handleApplyChanges() {
    if (!this.validateFieldLabel())
      return;
    this.fieldConfig.label = this.fieldLabel;
    this.fieldConfig.defaultValue = this.fieldDefaultValue;
    this.fieldConfig.required = this.fieldRequired;
    this.fieldConfig.readOnly = this.fieldReadOnly;
    this.fieldConfig.cleanOnCopy = this.fieldCleanOnCopy;
    this.emitFieldChanged();
    this._popoupElement.opened = false;
  }
  applyErrorMessage() {
    this.fieldLabelErrorMessage = `${this.getMessage('snkConfigOptions.validation.requiredField')} ${this.getMessage('snkConfigOptions.label.nameField')}`;
  }
  handleDiscardChanges() {
    this.initializeValues();
    this._popoupElement.opened = false;
  }
  componentWillLoad() {
    this.loadDefaultValue();
    this._application = ApplicationContext.getContextValue('__SNK__APPLICATION__');
  }
  render() {
    return (h("ez-popup", { heightMode: 'auto', size: 'auto', "ez-title": this.getMessage('snkConfigOptions.fieldConfig.title'), onEzClosePopup: () => this.handleDiscardChanges(), ref: ref => this._popoupElement = ref }, h("div", { class: 'field-config-container' }, h("ez-text-input", { label: this.getMessage('snkConfigOptions.label.nameField'), value: this.fieldLabel, errorMessage: this.fieldLabelErrorMessage, hasInvalid: !!this.fieldLabelErrorMessage, onEzChange: (e) => this.handleLabelChanged(e) }), h("ez-combo-box", { label: this.getMessage('snkConfigOptions.label.typeValueDefault'), suppressEmptyOption: true, enabled: this.enabledValueDefault(), onEzChange: (e) => this.handleDefaultTypeChanged(e), value: this.getDefaultType() }, h("option", { value: DEFAULT_TYPE.fixed }, this.getMessage('snkConfigOptions.options.valueFixed')), h("option", { value: DEFAULT_TYPE.variable }, this.getMessage('snkConfigOptions.options.variable'))), this.renderDefaultValueEditor(), h("ez-check", { label: this.getMessage('snkConfigOptions.label.clearDuplicate'), value: this.fieldCleanOnCopy, onEzChange: (e) => this.handleClearDuplicateChanged(e) }), h("ez-check", { label: this.getMessage('snkConfigOptions.label.requiredField'), enabled: getEnabledByProperty('required', 'systemRequired', this.fieldDescriptor), value: getValueByProperty('required', this.fieldDescriptor, this.fieldRequired), onEzChange: (e) => this.handleRequiredChanged(e) }), h("ez-check", { label: this.getMessage('snkConfigOptions.label.protectedField'), enabled: getEnabledByProperty('readOnly', 'systemReadOnly', this.fieldDescriptor), value: getValueByProperty('readOnly', this.fieldDescriptor, this.fieldReadOnly), onEzChange: (e) => this.handleReadOnlyChanged(e) }), h("div", { class: 'actions' }, h("ez-button", { label: this.getMessage('snkConfigOptions.fieldConfig.buttons.cancel'), onClick: () => this.handleDiscardChanges() }), h("ez-button", { label: this.getMessage('snkConfigOptions.fieldConfig.buttons.confirm'), class: "ez-button--primary", onClick: () => this.handleApplyChanges() })))));
  }
  static get is() { return "field-config"; }
  static get encapsulation() { return "scoped"; }
  static get originalStyleUrls() {
    return {
      "$": ["field-config.css"]
    };
  }
  static get styleUrls() {
    return {
      "$": ["field-config.css"]
    };
  }
  static get properties() {
    return {
      "dataUnit": {
        "type": "unknown",
        "mutable": false,
        "complexType": {
          "original": "DataUnit",
          "resolved": "DataUnit",
          "references": {
            "DataUnit": {
              "location": "import",
              "path": "@sankhyalabs/core"
            }
          }
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": ""
        }
      },
      "fieldConfig": {
        "type": "any",
        "mutable": true,
        "complexType": {
          "original": "IFieldConfig",
          "resolved": "IFieldConfig",
          "references": {
            "IFieldConfig": {
              "location": "import",
              "path": "@sankhyalabs/ezui/src/utils/interfaces/IFieldConfig"
            }
          }
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": ""
        },
        "attribute": "field-config",
        "reflect": true
      },
      "fieldDescriptor": {
        "type": "unknown",
        "mutable": false,
        "complexType": {
          "original": "FieldDescriptor",
          "resolved": "FieldDescriptor",
          "references": {
            "FieldDescriptor": {
              "location": "import",
              "path": "@sankhyalabs/core"
            }
          }
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": ""
        }
      },
      "messagesBuilder": {
        "type": "unknown",
        "mutable": true,
        "complexType": {
          "original": "SnkMessageBuilder",
          "resolved": "SnkMessageBuilder",
          "references": {
            "SnkMessageBuilder": {
              "location": "import",
              "path": "../../../../lib/message/SnkMessageBuilder"
            }
          }
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": ""
        }
      }
    };
  }
  static get states() {
    return {
      "fieldLabel": {},
      "fieldLabelErrorMessage": {},
      "fieldDefaultValue": {},
      "fieldCleanOnCopy": {},
      "fieldRequired": {},
      "fieldReadOnly": {},
      "_defaultType": {}
    };
  }
  static get events() {
    return [{
        "method": "fieldConfigChanged",
        "name": "fieldConfigChanged",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": ""
        },
        "complexType": {
          "original": "IFieldConfig",
          "resolved": "IFieldConfig",
          "references": {
            "IFieldConfig": {
              "location": "import",
              "path": "@sankhyalabs/ezui/src/utils/interfaces/IFieldConfig"
            }
          }
        }
      }];
  }
  static get methods() {
    return {
      "show": {
        "complexType": {
          "signature": "(_anchorElement: HTMLElement) => Promise<void>",
          "parameters": [{
              "tags": [],
              "text": ""
            }],
          "references": {
            "Promise": {
              "location": "global"
            },
            "HTMLElement": {
              "location": "global"
            }
          },
          "return": "Promise<void>"
        },
        "docs": {
          "text": "",
          "tags": []
        }
      }
    };
  }
  static get watchers() {
    return [{
        "propName": "fieldLabel",
        "methodName": "observeFieldLabel"
      }];
  }
}
