<h3>{{ ParentItem.Name ? ParentItem.Name : 'Unnamed code action' }} {{ labels.Title }}</h3>
<b class="CustomLabel">{{ labels.Usings }}</b>
<el-select
  v-model="UsingsValue"
  :title="labels.Usings"
  allow-create
  collapse-tags
  filterable
  multiple
  placeholder="Select"
  style="width: 100%; margin-bottom: 15px;"
  @change="onUsingsChange">
<el-option
  v-for="item in Usings"
  :key="item"
  :label="item"
  :value="item">
</el-option>
</el-select>
<div dir="ltr">{{ ReturnValue }} <b>{{ ParentItem.Name }}</b> ({{ FuncSignature }}) {</div>
<div :id="editor_container" class="WorkflowDesignerJsonEditor" style="height: calc(100% - 215px)"></div>
<div class="WorkflowDesignerButtons">
<el-button v-if="!readonly" type="info" @click="onCompile">{{ labels.Compile }}</el-button>
<el-button v-if="!readonly" type="primary" @click="onSave">{{ ButtonTextSave }}</el-button>
<el-button @click="onClose">{{ ButtonTextCancel }}</el-button>
</div>
<el-dialog
  v-model="infodialog.visible"
  :modal-append-to-body="false"
  :title="infodialog.title"
  :visible="infodialog.visible"
  width="50%">
<span v-html="infodialog.message"></span>
<template #footer>
      <span class="dialog-footer">
      <el-button @click="infodialog.visible = false">{{ labels.OK }}</el-button>
  </span>
</template>
</el-dialog>
<script type="application/javascript">
  var funcSignature = 'ProcessInstance processInstance, WorkflowRuntime runtime, string parameter'

  function codeform_Data(me) {
    return {
      ParentItem: {},
      editor_container: me.id + '_editor',
      readonly: false,
      Usings: null,
      UsingsValue: null,
      Name: '',
      ReturnValue: 'void',
      FuncSignature: funcSignature,
      infodialog: {
        title: '',
        message: '',
        visible: false,
      }
    }
  }

  function codeform_Init(me) {
    const {VueConfig} = me;
    const {state: data, methods} = VueConfig;

    methods.UpdateLanguage = function () {
      Object.assign(data, {
        labels: WorkflowDesignerConstants.EditCodeLabel,
        ButtonTextSave: WorkflowDesignerConstants.ButtonTextSave,
        ButtonTextCancel: WorkflowDesignerConstants.ButtonTextCancel
      });
    }

    methods.UpdateLanguage();

    var updateDataFromParent = function () {
      var ParentItem = data.ParentItem;
      data.Name = ParentItem.Name;
      data.Type = ParentItem.Type;
      data.IsAsync = ParentItem.IsAsync;

      if (!ParentItem.IsGlobal) {
        var commonUsings = data.CommonUsings;
        var additionalUsings = ParentItem.Usings ? decodeURIComponent(ParentItem.Usings).split(';') : [];
        var excludedUsings = ParentItem.ExcludedUsings ? decodeURIComponent(ParentItem.ExcludedUsings).split(';') : [];
        additionalUsings = additionalUsings.filter(function (additionalUsing) {
          return additionalUsing !== ''
        });
        excludedUsings = excludedUsings.filter(function (excludedUsing) {
          return excludedUsing !== ''
        });
        var selectedUsings = [];
        var allUsings = [];
        commonUsings.forEach(function (commonUsing) {
          if (!excludedUsings.includes(commonUsing)) {
            selectedUsings.push(commonUsing);
          }
          if (!allUsings.includes(commonUsing)) {
            allUsings.push(commonUsing);
          }
        });

        additionalUsings.forEach(function (additionalUing) {
          if (!selectedUsings.includes(additionalUing)) {
            selectedUsings.push(additionalUing);
          }
          if (!allUsings.includes(additionalUing)) {
            allUsings.push(additionalUing);
          }
        });

        allUsings.sort();
        selectedUsings.sort();


        data.Usings = allUsings;
        data.UsingsValue = selectedUsings;
      } else {
        if (ParentItem.Usings !== undefined && ParentItem.Usings !== null && ParentItem.Usings !== '') {
          data.Usings = decodeURIComponent(ParentItem.Usings).split(';').filter(function (using) {
            return using !== ''
          });
          data.UsingsValue = decodeURIComponent(ParentItem.Usings).split(';').filter(function (using) {
            return using !== ''
          });
        } else {
          data.Usings = WorkflowDesignerCommon.clone(me.graph.data.AdditionalParams.Usings);
          data.UsingsValue = WorkflowDesignerCommon.clone(me.graph.data.AdditionalParams.Usings);
        }
      }

      //      me.VueConfig.methods.onUsingsChange(data.UsingsValue);
      //  me.VueConfig.methods.onUsingsChange(me.graph.data.CodeActionsCommonUsings && me.graph.data.CodeActionsCommonUsings.split(";") || []);

      var code = ParentItem.ActionCode;
      if (ParentItem.Type === 'Action') {
        data.ReturnValue = ParentItem.IsAsync ? 'async Task ' : 'void ';
        data.FuncSignature = ParentItem.IsAsync ? funcSignature + ', CancellationToken token' : funcSignature;

        if (!code) {
          code = '// TODO Insert your code here';
        }
      }
      if (ParentItem.Type === 'Condition') {
        data.ReturnValue = ParentItem.IsAsync ? 'async Task<bool> ' : 'bool ';
        data.FuncSignature = ParentItem.IsAsync ? funcSignature + ', CancellationToken token' : funcSignature;

        if (!code) {
          code = 'bool result = true;\n\n// TODO Insert your code here\n\nreturn result;';
        }
      }
      if (ParentItem.Type === 'RuleGet') {
        data.ReturnValue = ParentItem.IsAsync ? 'async Task<IEnumerable<string>> ' : 'IEnumerable<string> ';
        data.FuncSignature = ParentItem.IsAsync ? funcSignature + ', CancellationToken token' : funcSignature;

        if (!code) {
          code = 'var result = new List<string>();\n\n// TODO Insert your code here\n\nreturn result;';
        }
      }

      if (ParentItem.Type === 'RuleCheck') {
        data.ReturnValue = ParentItem.IsAsync ? 'async Task<bool> ' : 'bool ';
        data.FuncSignature = ParentItem.IsAsync ?
          funcSignature + ', string identityId, CancellationToken token' : funcSignature + ', string identityId';

        if (!code) {
          code = 'bool result = true;\n\n// TODO Insert your code here\n\nreturn result;';
        }
      }

      setTimeout(function () {
        methods.renderEditor(decodeURIComponent(code));
      }, 10);
    }

    methods.onUpdate = function (dataFromParent) {
      data.readonly = me.graph.Settings.readonly;
      data.ParentItem = dataFromParent.item;
      data.CommonUsings = dataFromParent.commonUsings
      updateDataFromParent();
    }

    methods.onShow = function () {
      me.unwatch = me.Root.$watch('ParentItem', function () {
        updateDataFromParent();
      }, {deep: true})
    }

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

        WorkflowDesignerWindows.Autocompleter.enableAceEditor({
          editor: me.editor,
          getUsingsCallback: function () {
            return me.VueConfig.data.usings;
          },
          getVariablesCallback: function () {
            return WorkflowDesignerWindows.getVariablesList(me.VueConfig.data.Type, me.VueConfig.data.IsAsync);
          }
        });
      }

      me.editor.setOptions({readOnly: me.graph.Settings.readonly});
      me.editor.setValue(value ? value : '');
      me.editor.clearSelection();
    }

    methods.onUsingsChange = function (values) {
      if (!values || !values.length) {
        return;
      }

      values.forEach(function (value) {
        if (!data.Usings.includes(value)) {
          data.Usings.push(value);
        }
      });
      data.Usings.sort();
    }

    methods.onSave = function () {
      var actionCode = encodeURIComponent(me.editor.getValue());
      var usings = [];
      var exludedUsings = [];

      if (!data.ParentItem.IsGlobal) {
        var selectedUsings = data.UsingsValue;
        var commonUsings = data.CommonUsings;

        selectedUsings.forEach(function (selectedUsing) {
          if (!commonUsings.includes(selectedUsing)) {
            usings.push(selectedUsing);
          }
        });

        commonUsings.forEach(function (commonUsing) {
          if (!selectedUsings.includes(commonUsing)) {
            exludedUsings.push(commonUsing)
          }
        });
      } else {
        usings = data.UsingsValue;
        exludedUsings = [];
      }

      var usingsString = usings.join(';');
      if (usingsString !== '') {
        usingsString += ';'; //for compatibility with older versions
      }
      var exludedUsingsString = exludedUsings.join(';');
      if (exludedUsingsString !== '') {
        exludedUsingsString += ';';
      }
      me.unwatch();
      me.onSuccess({
        Usings: encodeURIComponent(usingsString),
        ExcludedUsings: encodeURIComponent(exludedUsingsString),
        ActionCode: actionCode
      });
      me.onClose(true);
    }

    methods.onClose = function () {
      data.infodialog.visible = false;
      me.unwatch();
      me.onClose(true);
    }

    methods.onCompile = function () {
      var item = {
        Name: data.Name,
        Type: data.Type,
        IsGlobal: false,
        IsAsync: data.IsAsync,
        ActionCode: encodeURIComponent(me.editor.getValue()),
        Usings: encodeURIComponent(data.UsingsValue.join(';'))
      }

      var callbackfn = function (response) {
        var infodialog = data.infodialog;
        infodialog.title = response.Success ? WorkflowDesignerConstants.EditCodeLabel.Success : WorkflowDesignerConstants.EditCodeLabel.Error;
        infodialog.message = response.Success ? WorkflowDesignerConstants.EditCodeLabel.CompileSucceeded : response.Message;
        infodialog.visible = true;
      }

      me.graph.designer.compile(item, callbackfn);
    }

    methods.onHideEvent = function () {
      me.graph.setParam('codeform_showusings', data.showusings);

      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>
