<h3>{{ParentItem.Name ? ParentItem.Name : "Unnamed code acttion"}} {{ labels.Title }}</h3>
<b class="CustomLabel">{{ labels.Usings }}</b>
<el-select
    v-model="UsingsValue"
    @change="onUsingsChange"
    multiple
    collapse-tags
    allow-create
    filterable
    style="width: 100%; margin-bottom: 15px;"
    :title="labels.Usings" 
    placeholder="Select">
        <el-option
            v-for="item in Usings"
            :key="item"
            :label="item"
            :value="item">
        </el-option>
</el-select>
<div style="white-space: nowrap;">{{ ReturnValue }} <b>{{ ParentItem.Name }}</b> ({{FuncSignature}}){</div>
<div :id="editor_container" class="WorkflowDesignerJsonEditor" style="height: calc(100% - 195px)"></div>
}
<div class="WorkflowDesignerButtons">
    <el-button v-if="!readonly" @click="onCompile" type="info">{{ labels.Compile }}</el-button>
    <el-button v-if="!readonly" @click="onSave" type="primary">{{ ButtonTextSave }}</el-button>
    <el-button @click="onClose">{{ ButtonTextCancel }}</el-button>
</div>
<el-dialog
    :title="infodialog.title"
    :before-close="function() {infodialog.visible = false}"
    :visible="infodialog.visible"
    :modal-append-to-body="false"
    width="50%">
    <span v-html="infodialog.message"></span>
    <span slot="footer" class="dialog-footer">
        <el-button @click="infodialog.visible = false">{{labels.OK}}</el-button>
    </span>
</el-dialog>
<script type="application/javascript">
    function codeform_Init(me){
        var funcSignature = "ProcessInstance processInstance, WorkflowRuntime runtime, string parameter";
        me.VueConfig.data = Object.assign(me.VueConfig.data, {
            editor_container: me.id + "_editor",
            readonly: false,
            labels: WorkflowDesignerConstants.EditCodeLabel,                
            ButtonTextSave: WorkflowDesignerConstants.ButtonTextSave,
            ButtonTextCancel: WorkflowDesignerConstants.ButtonTextCancel,
            Usings: null,
            UsingsValue: null,
            Name: "",
            ReturnValue: "void",
            FuncSignature: funcSignature,
            infodialog: {
                title: "",
                message: "",
                visible: false,
                onSuccess: function(){
                    me.VueConfig.data.infodialog.visible = false;
                    me.onClose(true);
                }
            },
        });
        
        var updateDataFromParent = function () {
            var data = me.VueConfig.data;
            var ParentItem = data.ParentItem;
            data.Name = ParentItem.Name;
            data.Type = ParentItem.Type;
            data.IsAsync = ParentItem.IsAsync;

            if (!ParentItem.IsGlobal)
            {
                var commonUsings = me.VueConfig.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(){
                me.VueConfig.methods.renderEditor(decodeURIComponent(code));
            }, 10);
        }

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

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

        me.VueConfig.methods.renderEditor = function(value){
            if(!me.editor){
                me.editor = ace.edit(me.VueConfig.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();
        };

        me.VueConfig.methods.onUsingsChange = function(values){
            if (!values || !values.length) {
                return;
            }
            var data = me.VueConfig.data;
            values.forEach(function(value) {
                if (!data.Usings.includes(value)) {
                    data.Usings.push(value);
                }
            });
            data.Usings.sort();
        };

        me.VueConfig.methods.onSave = function(){

            var actionCode = encodeURIComponent(me.editor.getValue());
            var usings = [];
            var exludedUsings = [];

            if (!me.VueConfig.data.ParentItem.IsGlobal) {
                var selectedUsings = me.VueConfig.data.UsingsValue;
                var commonUsings = me.VueConfig.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 = me.VueConfig.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);
        };

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

        me.VueConfig.methods.onCompile = function(){
            var data = me.VueConfig.data;
            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 = me.VueConfig.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);
        };
        
        me.VueConfig.methods.onHideEvent = function(){
            me.graph.setParam("codeform_showusings", me.VueConfig.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>