<h3>{{ customTitle ? customTitle : (formMode ? labels2.Title : labels.Title) }}</h3>
<div v-if="!formMode" :id="editor_container" class="WorkflowDesignerJsonEditor"></div>
<el-form
  v-if="formMode"
  ref="form"
  :model="FormData"
  class="WorkflowDesignerWindowForm"
  label-position="top"
  label-width="150px">
  <el-form-item v-for="field in fields.filter(field => field.Type != 'Error')" :key="field.Name" :label="getLocalizationParameterLabel(field)" :prop="field.Name" :rules="getFieldRules(field)">
    <el-input v-if="field.Type == 'Text'" v-model="FormData[field.Name]" :readonly="readonly"></el-input>
    <el-input-number v-if="field.Type == 'Number'" v-model="FormData[field.Name]" :disabled="readonly"
                     controls-position="right"></el-input-number>
    <el-checkbox v-if="field.Type == 'Checkbox'" v-model="FormData[field.Name]" :disabled="readonly"></el-checkbox>
    <el-input v-if="field.Type == 'TextArea'" v-model="FormData[field.Name]" :readonly="readonly" rows="6" type="textarea"></el-input>
    <el-date-picker
      v-if="field.Type == 'DateTime'"
      v-model="FormData[field.Name]"
      value-format="yyyy-MM-ddTHH:mm:ss"
      :class="validateFieldDD(FormData[field.Name]) ? 'WorkflowDesignerInputError' : ''"
      :readonly="readonly"
      type="datetime">
    </el-date-picker>
    <el-date-picker
      v-if="field.Type == 'Date'"
      v-model="FormData[field.Name]"
      :readonly="readonly"
      format="yyyy-MM-dd"
      type="date"
      value-format="yyyy-MM-dd">
    </el-date-picker>
    <el-time-picker
      v-if="field.Type == 'Time'"
      v-model="FormData[field.Name]"
      :picker-options="{
                    selectableRange: '00:00:00 - 23:59:59'
                }"
      :readonly="readonly"
      value-format="HH:mm:ss">
    </el-time-picker>
    <el-select v-if="field.Type == 'Dropdown'" v-model="FormData[field.Name]" :disabled="readonly" placeholder="">
      <el-option
        v-for="item in field.DropdownValues"
        :key="item.Value"
        :label="item.Name"
        :value="item.Value">
      </el-option>
    </el-select>
    <el-select v-if="field.Type == 'MultiSelect'" v-model="FormData[field.Name]" :disabled="readonly" multiple placeholder="">
      <el-option
        v-for="item in field.DropdownValues"
        :key="item.Value"
        :label="item.Name"
        :value="item.Value">
      </el-option>
    </el-select>
    <el-input v-if="field.Type == 'Json'" v-model="FormData[field.Name]" :readonly="readonly"></el-input>
    <el-button v-if="field.Type == 'Json'" :class="'WorkflowDesignerTableCodeActionsButton ' + (editItem == field ? 'is-active' : '')"
               @click="showjson('DefaultValue', field)"></el-button>
  </el-form-item>
  <div style="display: flex;flex-direction: column;gap: 10px">
    <el-alert
      v-for="field in fields.filter(field => field.Type == 'Error')"
      :title="field.Title"
      :description="FormData[field.Name]"
      type="error"
      show-icon
    />
  </div>
</el-form>

<div class="WorkflowDesignerButtons">
  <el-button v-if="!readonly && !formMode" @click="onFormat">{{ labels.Format }}</el-button>
  <el-button v-if="fields" type="text" @click="onChangeFormMode">{{
      formMode ? labels2.SwitchToJson : labels2.SwitchToConstructor
    }}
  </el-button>
  <el-button v-if="!readonly" type="primary" @click="onSave">{{ ButtonTextSave }}</el-button>
  <el-button @click="onClose">{{ ButtonTextCancel }}</el-button>
</div>
<script type="application/javascript">
  function jsonform_Init(me) {
    me.VueConfig.methods.UpdateLanguage = function () {
      me.VueConfig.data = Object.assign(me.VueConfig.data, {
        labels: WorkflowDesignerConstants.EditJSONLabel,
        labels2: WorkflowDesignerConstants.EditParametersFormlabel,
        ButtonTextSave: WorkflowDesignerConstants.ButtonTextSave,
        ButtonTextCancel: WorkflowDesignerConstants.ButtonTextCancel,
      });
    }

    me.VueConfig.methods.UpdateLanguage();
    me.VueConfig.data = Object.assign(me.VueConfig.data, {
      editor_container: me.id + '_editor',
      customTitle: undefined,
      readonly: false,
      editItem: undefined,
      actionType: undefined,
      FormData: {},
      fields: null,
      formMode: false
    });

    me.failsCount = 0;

    me.VueConfig.methods.onUpdate = function (value) {
      me.VueConfig.data.readonly = me.graph.Settings.readonly;

      if (me.options && me.options.customTitle) {
        me.VueConfig.data.customTitle = me.options.customTitle;
      }
      var fields = undefined;
      var parameterDefinition = me.options.parameterDefinition;
      if (parameterDefinition && parameterDefinition.name) {
        me.VueConfig.data.actionType = parameterDefinition.name;
        if (Array.isArray(parameterDefinition.type)) {
          for (var i = 0; i <= parameterDefinition.type.length; i++) {
            fields = me.graph.getActionParameterDefinition(parameterDefinition.name, parameterDefinition.type[i]);
            if (fields && fields.length > 0)
              break;
          }
        } else {
          fields = me.graph.getActionParameterDefinition(parameterDefinition.name, parameterDefinition.type);
        }
      } else if (Array.isArray(me.options.parameterDefinition)) {
        fields = me.options.parameterDefinition;
        me.VueConfig.data.actionType = WorkflowDesignerCommon.toJSON(value)['__customtype'];
      }

      if (fields && fields.length > 0) {

        me.VueConfig.data.formMode = true;
        me.VueConfig.data.fields = fields;

        if (me.VueConfig.data.fields.length > 1 && me.VueConfig.data.fields.filter(function (f) {
          return f.Name === '';
        })[0]) {
          console.error(WorkflowDesignerConstants.EditParametersFormlabel.IncorrectForm);
          me.VueConfig.methods.showConfirm({
            title: WorkflowDesignerConstants.AlertTitle,
            message: WorkflowDesignerConstants.EditParametersFormlabel.IncorrectForm,
            isAlert: true
          });

          return;
        }

        if (!value && !me.VueConfig.data.readonly) {
          var tmp = {};

          if (me.VueConfig.data.fields.length === 1 && me.VueConfig.data.fields[0].Name === '') {
            if (typeof (me.VueConfig.data.fields[0].DefaultValue) != 'undefined') {
              if (me.VueConfig.data.fields[0].Type === 'Checkbox') {
                value = me.VueConfig.data.fields[0].DefaultValue !== null && me.VueConfig.data.fields[0].DefaultValue !== undefined && me.VueConfig.data.fields[0].DefaultValue.toString() === 'true';
              } else if (me.VueConfig.data.fields[0].Type === 'MultiSelect' && typeof (me.VueConfig.data.fields[0].DefaultValue) === 'object') {
                value = WorkflowDesignerCommon.toString(me.VueConfig.data.fields[0].DefaultValue);
              } else if (me.VueConfig.data.fields[0].Type === 'Json' && typeof (me.VueConfig.data.fields[0].DefaultValue) === 'object') {
                value = WorkflowDesignerCommon.toString(me.VueConfig.data.fields[0].DefaultValue);
              } else {
                value = me.VueConfig.data.fields[0].DefaultValue;
              }
            } else {
              if (me.VueConfig.data.fields[0].Type === 'Checkbox') {
                value = false;
              } else if (me.VueConfig.data.fields[0].Type === 'Multiselect') {
                value = [];
              } else {
                value = null;
              }
            }
          } else {
            fields.forEach(function (field) {
              if (field.Type === 'Checkbox') {
                field.DefaultValue = field.DefaultValue !== null && field.DefaultValue !== undefined && field.DefaultValue.toString() === 'true';
              }

              if (typeof (field.DefaultValue) != 'undefined') {
                if (field.Type === 'Json' && typeof (field.DefaultValue) === 'string') {
                  tmp[field.Name] = WorkflowDesignerCommon.toJSON(field.DefaultValue);
                } else if (field.Type === 'MultiSelect') {
                  if (typeof (field.DefaultValue) === 'string') {
                    tmp[field.Name] = WorkflowDesignerCommon.toJSON(field.DefaultValue);
                  } else {
                    try {
                      tmp[field.Name] = [];
                      for (let key in field.DefaultValue) {
                        tmp[field.Name].push(field.DefaultValue[key]);
                      }
                    } catch (e) {
                    }
                  }
                } else {
                  tmp[field.Name] = field.DefaultValue;
                }
              } else {
                tmp[field.Name] = null;
              }
            });
            value = WorkflowDesignerCommon.toString(tmp);
          }
        }
      }

      if (me.VueConfig.data.formMode) {

        if (value) {
          var serialized = WorkflowDesignerCommon.toJSON(value);

          if (me.VueConfig.data.fields) {
            me.VueConfig.data.fields.forEach(function (field) {
              if (field.Type === 'Json') {
                serialized[field.Name] = WorkflowDesignerCommon.toJSON(serialized[field.Name]);
              }
            });
          }

          value = WorkflowDesignerCommon.toString(serialized);
        }

        if (me.VueConfig.data.fields.length === 1 && me.VueConfig.data.fields[0].Name === '') {
          if (me.VueConfig.data.fields[0].Type === 'Text'
            || me.VueConfig.data.fields[0].Type === 'TextArea'
            || me.VueConfig.data.fields[0].Type === 'Dropdown'
            || me.VueConfig.data.fields[0].Type === 'DateTime'
            || me.VueConfig.data.fields[0].Type === 'Date'
            || me.VueConfig.data.fields[0].Type === 'Time'
          ) {
            me.VueConfig.data.FormData = WorkflowDesignerCommon.toJSON('{ "":"' + (value === null ? '' : value) + '"}');
          } else if (me.VueConfig.data.fields[0].Type === 'Json'
            || me.VueConfig.data.fields[0].Type === 'Checkbox'
            || me.VueConfig.data.fields[0].Type === 'MultiSelect'
            || me.VueConfig.data.fields[0].Type === 'Number'
          ) {
            me.VueConfig.data.FormData = WorkflowDesignerCommon.toJSON('{ "":' + value + '}');
          } else {
            me.VueConfig.data.FormData = WorkflowDesignerCommon.toJSON(value);
          }
        } else {
          var formData = WorkflowDesignerCommon.toJSON(value);
          me.VueConfig.data.fields.forEach(function (field) {
            if (field.Type == 'MultiSelect' && formData[field.Name] !== undefined && typeof (formData[field.Name]) === 'string') {
              var list = WorkflowDesignerCommon.toJSON(formData[field.Name]);
              me.VueConfig.data.FormData[field.Name] = [];
              list.forEach(function (value) {
                me.VueConfig.data.FormData[field.Name].push(value);
              });
            } else {
              me.VueConfig.data.FormData[field.Name] = formData[field.Name];
            }
          });
        }

        if (!me.VueConfig.data.FormData)
          me.VueConfig.data.FormData = {};

        for (key in me.VueConfig.data.FormData) {
          if (me.VueConfig.data.FormData.hasOwnProperty(key)) {
            if (key !== '__customtype') {
              var found = false;

              for (var j = 0; j < me.VueConfig.data.fields.length; j++) {
                if (me.VueConfig.data.fields[j] && me.VueConfig.data.fields[j].Name === key) {
                  found = true;
                  break;
                }

              }

              if (!found) {
                delete me.VueConfig.data.FormData[key];
              }
            }
          }
        }
        me.VueConfig.data.fields.forEach(function (field) {
          if (me.VueConfig.data.FormData[field.Name] === undefined) {
            if (field.Type === 'Checkbox') {
              field.DefaultValue = field.DefaultValue !== null && field.DefaultValue !== undefined && field.DefaultValue.toString() === 'true';
            }

            if (typeof (field.DefaultValue) != 'undefined') {
              me.VueConfig.data.FormData[field.Name] = field.DefaultValue;
            } else {
              me.VueConfig.data.FormData[field.Name] = null;
            }
          } else {
            if (field.Type === 'Json') {
              me.VueConfig.data.FormData[field.Name] = me.VueConfig.data.FormData[field.Name] != undefined
                ? WorkflowDesignerCommon.toCompactJSON(WorkflowDesignerCommon.toString(me.VueConfig.data.FormData[field.Name]))
                : null;
            } else if (field.Type === 'Dropdown' && me.VueConfig.data.FormData[field.Name] !== null && typeof (me.VueConfig.data.FormData[field.Name]) !== 'string') {
              me.VueConfig.data.FormData[field.Name] = WorkflowDesignerCommon.toString(me.VueConfig.data.FormData[field.Name]);
            } else if (field.Type === 'Checkbox' && typeof (me.VueConfig.data.FormData[field.Name]) !== 'boolean') {
              me.VueConfig.data.FormData[field.Name] = WorkflowDesignerCommon.toJSON(me.VueConfig.data.FormData[field.Name]);
            }
          }
        });


        // setTimeout(function(){
        //     me.VueConfig.methods.renderJSONFields();
        // }, 1);
      } else {
        setTimeout(function () {
          me.VueConfig.methods.renderEditor(value);
        }, 1);
      }
    };

    me.VueConfig.methods.getLocalizationParameterLabel = function (field) {
      if (me.VueConfig.data.labels2.CustomForms[me.VueConfig.data.actionType] != undefined &&
        me.VueConfig.data.labels2.CustomForms[me.VueConfig.data.actionType][field.Name] != undefined) {
        return me.VueConfig.data.labels2.CustomForms[me.VueConfig.data.actionType][field.Name];
      }

      var label = field.Title ? field.Title : field.Name;
      if (field.Comment && field.Comment !== '') {
        label = label + ' (' + field.Comment + ')';
      }
      return label;
    };

    me.VueConfig.methods.getFieldRules = function (field) {
      var rules = [{required: false}];
      if (field.IsRequired) {
        if (field.Type == 'MultiSelect') {
          var validator = function (rule, value, callback) {
            if (me.VueConfig.data.FormData[field.Name].length > 0) {
              callback();
            } else {
              callback(new Error(rule.message));
            }
          };
          rules.push({validator: validator, message: WorkflowDesignerConstants.FieldIsRequired, trigger: 'change'});
        } else {
          return me.requiredRule();
        }
      }

      return rules;
    };

    me.VueConfig.methods.showjson = function (name, field) {
      me.VueConfig.data.editItem = field;
      me.editItem = field;
      var onSuccess = function (value) {
        if (me.editItem) {
          me.VueConfig.data.FormData[field.Name] = value;
          me.VueConfig.data.editItem = undefined;
          delete me.editItem;
        }
      };

      var onClose = function (value) {
        me.VueConfig.data.editItem = undefined;
      };

      var params = {};
      me.VueConfig.data.jsonform = me.showjson(me.VueConfig.data.FormData[field.Name], params, onSuccess, onClose);
    };

    me.VueConfig.methods.renderEditor = function (value) {
      try {
        if (!me.editor) {
          me.editor = ace.edit(me.VueConfig.data.editor_container);
          var session = me.editor.getSession();
          session.setMode('ace/mode/json5');
          session.setOption('useWorker', false);
        }

        me.editor.setOptions({readOnly: me.graph.Settings.readonly});

        var formattedValue = value ? WorkflowDesignerCommon.toPrettyJSON(value) : '';
        me.editor.setValue(formattedValue ? formattedValue : '');
        me.editor.clearSelection();
        me.failsCount = 0;
      } catch (err) {
        me.failsCount += 1;
        if (me.failsCount > 10) {
          return;
        }
        setTimeout(function () {
          me.VueConfig.methods.renderEditor(value);
        }, 1);
      }
    };

    me.VueConfig.methods.validateFieldDD = function (value) {
      if (name == 'DateTime' && value && !moment(value, moment.ISO_8601).isValid())
        return WorkflowDesignerConstants.EditParametersFormlabel.DateShouldBeInISOFormat;
    };

    me.VueConfig.methods.renderJSONFields = function () {
      me.VueConfig.data.fields.forEach(function (field) {
        if (field.Type == 'Json') {
          if (!me.editors) me.editors = {};

          var editor = me.editors[field.Name];
          if (!editor) {
            editor = me.editors[field.Name] = ace.edit(field.Name + '_editor');
            var session = editor.getSession();
            session.setMode('ace/mode/json5');
            session.setOption('useWorker', false);
          }

          editor.setOptions({readOnly: me.graph.Settings.readonly});
          var value = me.VueConfig.data.FormData[field.Name];

          if (typeof value == 'object') {
            var formattedValue = WorkflowDesignerCommon.toString(value);
            editor.setValue(formattedValue ? formattedValue : '');
          } else {
            var formattedValue = WorkflowDesignerCommon.toPrettyJSON(value);
            editor.setValue(formattedValue ? formattedValue : '');
          }

          editor.clearSelection();
        }
      });
    }

    me.VueConfig.methods.extractFormData = function () {
      var data = WorkflowDesignerCommon.clone(me.VueConfig.data.FormData);
      me.VueConfig.data.fields.forEach(function (field) {
        if (field.Type === 'Json') {
          if (me.editors && me.editors[field.Name]) {
            var value = me.editors[field.Name].getValue();
            data[field.Name] = value;
          } else {
            data[field.Name] = data[field.Name] === '' ? undefined : data[field.Name];
          }
        }

        if (field.Type === 'MultiSelect') {
          data[field.Name] = WorkflowDesignerCommon.toString(data[field.Name]);
        }
      });
      return data;
    }

    me.VueConfig.methods.onChangeFormMode = function () {
      me.VueConfig.data.formMode = !me.VueConfig.data.formMode;
      if (me.VueConfig.data.formMode) {
        var value = me.editor.getValue();
        if (me.VueConfig.data.fields.length === 1 && me.VueConfig.data.fields[0].Name === '') {
          if (me.VueConfig.data.fields[0].Type === 'Text'
            || me.VueConfig.data.fields[0].Type === 'TextArea'
            || me.VueConfig.data.fields[0].Type === 'Dropdown'
            || me.VueConfig.data.fields[0].Type === 'DateTime') {
            me.VueConfig.data.FormData = WorkflowDesignerCommon.toJSON('{ "":"' + (value === null ? '' : value) + '"}');
          } else if (me.VueConfig.data.fields[0].Type === 'Json'
            || me.VueConfig.data.fields[0].Type === 'Checkbox'
            || me.VueConfig.data.fields[0].Type === 'MultiSelect'
            || me.VueConfig.data.fields[0].Type === 'Number'
          ) {
            me.VueConfig.data.FormData = WorkflowDesignerCommon.toJSON('{ "":' + value + '}');
          } else {
            me.VueConfig.data.FormData = WorkflowDesignerCommon.toJSON(value);
          }
        } else {
          me.VueConfig.data.FormData = WorkflowDesignerCommon.toJSON(value);
        }

        me.VueConfig.data.fields.forEach(function (field) {
          if (field.Type === 'Json') {
            me.VueConfig.data.FormData[field.Name] = me.VueConfig.data.FormData[field.Name] != undefined ? WorkflowDesignerCommon.toCompactJSON(WorkflowDesignerCommon.toString(me.VueConfig.data.FormData[field.Name])) : null;
          } else if (field.Type === 'Dropdown' && me.VueConfig.data.FormData[field.Name] !== null && typeof me.VueConfig.data.FormData[field.Name] !== 'string') {
            me.VueConfig.data.FormData[field.Name] = WorkflowDesignerCommon.toString(me.VueConfig.data.FormData[field.Name]);
          }
        });

        if (me.editor) {
          me.editor.destroy();
          delete me.editor;
        }

        // setTimeout(function(){
        //     me.VueConfig.methods.renderJSONFields();
        // });
      } else {

        var data = me.VueConfig.methods.extractFormData();
        var value;

        if (me.VueConfig.data.FormData.hasOwnProperty('')) {
          var singleValue = data[''];
          value = me.VueConfig.methods.extractSingleValue(singleValue);
        } else {
          value = WorkflowDesignerCommon.toString(data);
        }

        if (me.editors) {
          for (var editor in me.editors) {
            me.editors[editor].destroy();
            delete me.editors[editor];
          }
          delete me.editors;
        }

        setTimeout(function () {
          me.VueConfig.methods.renderEditor(value);
        }, 1);
      }
    }

    me.VueConfig.methods.extractSingleValue = function (singleValue) {
      var value = undefined;
      var fieldType = me.VueConfig.data.fields[0].Type;
      if (typeof singleValue == 'string' || fieldType == 'DateTime') {
        value = WorkflowDesignerCommon.toString(singleValue);

        value = value.indexOf('"') === 0 ? value.substring(1) : value;

        value = value.lastIndexOf('"') === value.length - 1 ? value.substring(0, value.length - 1) : value;

      } else {
        value = WorkflowDesignerCommon.toString(singleValue);
      }
      return value;
    }

    me.VueConfig.methods.onSave = function () {
      var value = undefined;
      var isValid = true;
      if (me.VueConfig.data.formMode) {

        this.$refs && this.$refs.form && this.$refs.form.validate(function (valid) {
          isValid = valid;
        });

        if (isValid) {
          var data = me.VueConfig.methods.extractFormData();
          if (data.hasOwnProperty('')) {
            var field = me.VueConfig.data.fields[0];
            var singleValue = data[''];
            value = me.VueConfig.methods.extractSingleValue(singleValue);

            if ((field.Type == 'DateTime' || field.Type == 'Date' || field.Type == 'Time') && data[field.Name] === null) {
              value = '';
            }
          } else {
            value = WorkflowDesignerCommon.toString(data);
          }
        }
      } else {
        value = me.editor.getValue();
      }

      if (isValid) {
        me.onSuccess(WorkflowDesignerCommon.toCompactJSON(value));
        me.onClose(true);
      }
    };

    me.VueConfig.methods.onClose = function () {
      me.onClose(true);
    };

    me.VueConfig.methods.onFormat = function () {
      var value = me.editor.getValue();
      me.editor.setValue(WorkflowDesignerCommon.toPrettyJSON(value));
      me.editor.clearSelection();
    };

    me.VueConfig.methods.onHideEvent = function () {
      if (me.editor) {
        me.editor.destroy();
        delete me.editor;
      }

      if (me.editors) {
        for (var editor in me.editors) {
          me.editors[editor].destroy();
          delete me.editors[editor];
        }
        delete me.editors;
      }
    }
  }
</script>
