<h3>{{ labels.Title }}</h3>
<el-form ref="form"
         :model="FormData"
         class="WorkflowDesignerWindowForm"
         label-position="top"
         label-width="150px">
  <div class="SettingsWithPadding">
    <div class="el-form--inline el-form--label-top">
      <el-form-item :label="labels.Name" :rules="requiredRule(ActivityRules)" class="el-form-item" prop="Name" style="flex-grow: 1;">
        <el-input v-model="FormData.Name" :placeholder="labels.Name" :readonly="readonly"></el-input>
      </el-form-item>
      <el-form-item v-if="expertMode" :label="labels.State" class="el-form-item" prop="State" style="flex-grow: 1;">
        <el-input v-model="FormData.State" :placeholder="labels.State" :readonly="readonly"></el-input>
      </el-form-item>
    </div>
    <el-form-item v-if="expertMode" size="small">
      <el-checkbox v-model="FormData.IsInitial" :disabled="readonly" :label="labels.IsInitial" name="type"
                   @change="onInitialChange"></el-checkbox>
      <el-checkbox v-model="FormData.IsForSetState" :disabled="readonly" :label="labels.IsForSetState" name="type"></el-checkbox>
      <el-checkbox v-model="FormData.IsAutoSchemeUpdate" :disabled="readonly" :label="labels.IsAutoSchemeUpdate" name="type"></el-checkbox>
    </el-form-item>
  </div>

  <div style="margin-bottom: 10px;">

    <h4 class="WorkflowDesignerTitleWithCreate Underline SettingsHeader">
      {{ labels.Condition }}
      <a v-if="!readonly"
         @click="addRow(FormData.Conditions,
              {Action: {ActionParameter:null}, Type: 'Expression', Expression:null})">{{ ButtonTextCreate }}</a>
    </h4>
    <div>
      <table v-if="FormData.Conditions?.length > 0" class="WorkflowDesignerTable">
        <tr>
          <th></th>
          <th>{{ labels.ConditionType }}</th>
          <th>{{ labels.ConditionAction }}</th>
          <th v-if="hasConditionAnyAction()">{{ labels.ConditionActionParameter }}</th>
          <th>{{ labels.ConditionInversion }}</th>
          <th v-if="expertMode">{{ labels.ResultOnPreExecution }}</th>
        </tr>
        <tr v-for="(condition, index) in FormData.Conditions" :key="index"
            :class="dragOverIndex == index && dragOverBlock  == condition ? 'dragOver' : ''"
            @dragend="dragend($event)" @dragover="dragover(condition, index, $event)"
            @dragstart="dragstart(index, $event, FormData.Conditions)">
          <td :draggable="!readonly" class='WorkflowDesignerTableMoveCol'>
            <div v-if="!readonly" class='WorkflowDesignerTableMoveButton'></div>
          </td>
          <td>
            <el-select
              v-model="condition.Type"
              :class="validateField('Type', condition) ? 'WorkflowDesignerInputError' : ''"
              :disabled="readonly"
              :title="validateField('Type', condition)"
              clearable
              filterable
              placeholder=""
              style="width: 100%;">
              <el-option key="Action" :label="labels.ActionLabel" value="Action"></el-option>
              <el-option key="Expression" :label="labels.ExpressionLabel" value="Expression"></el-option>
            </el-select>
          </td>
          <td v-if="condition.Type == 'Action'">
            <el-select
              v-model="condition.Action.ActionName"
              :class="validateField('Action.ActionName', condition) ? 'WorkflowDesignerInputError' : ''"
              :disabled="readonly"
              :title="validateField('Action.ActionName', condition)"
              clearable
              filterable
              placeholder=""
              style="width: 100%;">
              <el-option v-for="item in conditions" :key="item" :label="item" :value="item"></el-option>
            </el-select>
          </td>
          <td v-if="condition.Type == 'Action'">
            <div style="flex-flow: nowrap; display: flex;align-items: center;">
              <el-autocomplete v-model="condition.Action.ActionParameter" :disabled="readonly" :fetch-suggestions="querySearch"
                               style="margin-right: 5px;"
                               @focus="setCurrentItem(condition)"></el-autocomplete>
            </div>
          </td>
          <td v-if="condition.Type == 'Expression'">
            <div style="flex-flow: nowrap; display: flex;align-items: center;">
              <el-input
                v-model="condition.Expression"
                :class="validateField('Expression', condition) ? 'WorkflowDesignerInputError' : ''"
                :readonly="readonly"
                :title="validateField('Expression', condition)">
              </el-input>
            </div>
          </td>
          <td v-if="condition.Type == 'Expression' && hasConditionAnyAction()"></td>

          <td v-if="condition.Type == 'Action' || condition.Type == 'Expression'">
            <el-checkbox v-model="condition.ConditionInversion" :disabled="readonly"></el-checkbox>
          </td>
          <td v-if="expertMode && (condition.Type == 'Action' || condition.Type == 'Expression')">
            <el-select
              v-model="condition.ResultOnPreExecution"
              :disabled="readonly"
              clearable
              filterable
              placeholder=""
              style="width: 100%;">
              <el-option key="True" :value="true" label="True"></el-option>
              <el-option key="False" :value="false" label="False"></el-option>
            </el-select>
          </td>
          <td :style="!readonly ? 'width: 94px;' : 'width: 42px;'">
            <el-button-group>
              <el-button
                :class="'WorkflowDesignerTableCodeActionsButton ' + (editItem == condition ? 'is-active' : '')"
                @click="condition.Type == 'Action' ? showjson('Action.ActionParameter', condition, {name: condition.Action.ActionName ,type: ['Condition']}) : showjson('Expression', condition, {expression: true})"></el-button>
              <el-button v-if="!readonly" :disabled="FormData.Conditions?.length == 1" class="WorkflowDesignerTableDeleteButton"
                         @click="removeRow(FormData.Conditions, index)"></el-button>
            </el-button-group>
          </td>
        </tr>
      </table>
    </div>
  </div>
  <div style="margin-bottom: 10px;">
    <h4 class="SettingsHeader">
      <span>{{ labels.Transition }}</span>
      <a v-if="!readonly" style="cursor:pointer" @click="addRow(FormData.Conditions, {Action:{}})"></a>
    </h4>
    <form class="el-form--inline el-form--label-top SettingsWithPadding" style="display: flex;">
      <div class="el-form--label-top TwoItemRow">
        <el-form-item :label="labels.WhenTrue" :readonly="readonly" :rules="getFieldRules('WhenTrueTo')" prop="WhenTrueTo">
          <el-select
            v-model="FormData.WhenTrueTo"
            :disabled="readonly"
            filterable
            placeholder=""
            style="width: 100%;">
            <el-option v-for="item in activities" :key="item.Name" :label="item.Name" :value="item.Name"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item v-if="expertMode" :label="labels.Classifier" :readonly="readonly">
          <el-select
            v-model="FormData.WhenTrueClassifier"
            :disabled="readonly"
            style="width: 100%;">
            <el-option v-for="key in Object.keys(labels.ClassifierValues)"
                       :key="key" :label="labels.ClassifierValues[key]" :value="key"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item :label="labels.WhenFalse" :readonly="readonly" :rules="getFieldRules('WhenFalseTo')" prop="WhenFalseTo">
          <el-select
            v-model="FormData.WhenFalseTo"
            :disabled="readonly"
            filterable
            placeholder=""
            style="width: 100%;">
            <el-option v-for="item in activities" :key="item.Name" :label="item.Name" :value="item.Name"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item v-if="expertMode" :label="labels.Classifier" :readonly="readonly">
          <el-select v-if="expertMode"
                     v-model="FormData.WhenFalseClassifier"
                     :disabled="readonly"
                     style="width: 100%;">
            <el-option v-for="key in Object.keys(labels.ClassifierValues)"
                       :key="key" :label="labels.ClassifierValues[key]" :value="key"></el-option>
          </el-select>
        </el-form-item>
      </div>
    </form>
  </div>
  <div style="margin-bottom: 10px;">
    <el-button icon="IconComment" v-if="!readonly && !itemHasComment" circle @click="showUserComment()"></el-button>
    <h4 v-if="itemHasComment" style="padding-bottom: 1px;border-bottom: 1px solid rgba(34,36,38,.15);">{{ labels.UserComment }}</h4>
    <el-input
      v-if="itemHasComment"
      v-model="FormData.UserComment"
      :placeholder="labels.UserComment"
      :rows="5"
      type="textarea"
    >
    </el-input>
  </div>
</el-form>
<div class="WorkflowDesignerButtons">
  <el-button link @click="expertMode = !expertMode">{{ expertMode ? SwitchToDefaultMode : SwitchToExpertMode }}</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 decision_Data(me) {
    return {
      readonly: false,
      expertMode: false,
      actions: [],
      activities: [],
      activitiesStore: me.graph.data.Activities,
      conditions: me.graph.getConditionNames() || [],
      conditionsStore: me.graph.data.CodeActions,
      states: [],
      editItem: null,
      itemHasComment: false,
      FormData: {}
    }
  }

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

    methods.UpdateLanguage = function () {
      Object.assign(data, {
        labels: Object.assign(
          {},
          WorkflowDesignerConstants.ActivityFormLabel,
          WorkflowDesignerConstants.TransitionFormLabel,
          WorkflowDesignerConstants.Decision),
        ButtonTextSave: WorkflowDesignerConstants.ButtonTextSave,
        ButtonTextCancel: WorkflowDesignerConstants.ButtonTextCancel,
        ButtonTextCreate: WorkflowDesignerConstants.ButtonTextCreate,
        ButtonTextDelete: WorkflowDesignerConstants.ButtonTextDelete,
        SwitchToDefaultMode: WorkflowDesignerConstants.SwitchToDefaultMode,
        SwitchToExpertMode: WorkflowDesignerConstants.SwitchToExpertMode,
      });
    }

    methods.UpdateLanguage();

    me.transitionManager = me.graph.GetComponentByType('WorkflowDesignerTransitionManager');
    me.activityManager = me.graph.GetComponentByType('WorkflowDesignerActivityManager');

    methods.GetTransitionsFrom = function (activityName) {
      var transitions = {};
      var foundTransitions = me.transitionManager.GetTransitionsFrom(activityName);
      foundTransitions.forEach(function (control) {
        var item = control.item;
        if (item.Conditions && item.Conditions[0] && (item.Conditions[0].Type === 'Expression' || item.Conditions[0].Type === 'Action')) {
          transitions.true = control;
        } else {
          transitions.false = control;
        }
      });
      return transitions;
    };

    methods.updateActivitiesList = function (value) {
      data.activities = [];
      me.graph.data.Activities.forEach(function (element) {
        if (element == me.linkItem) //not add current activity
          return;
        data.activities.push(element);
      });
    }

    me.VueConfig.watch = {
      conditionsStore: function (val) {
        data.conditions = me.graph.getConditionNames();
      },
      activitiesStore: function (val) {
        methods.updateActivitiesList();
      },
    }

    methods.onUpdate = function (item) {
      var transitions = methods.GetTransitionsFrom(item.Name);
      var formdata = data.FormData;

      data.transitions = transitions;
      formdata.Name = item.Name;
      formdata.ExecutionTimeout = item.ExecutionTimeout ? WorkflowDesignerCommon.clone(item.ExecutionTimeout) : {RetryCount: '1'};
      formdata.IdleTimeout = item.IdleTimeout ? WorkflowDesignerCommon.clone(item.IdleTimeout) : {RetryCount: '1'};
      formdata.State = item.State;
      formdata.IsInitial = item.IsInitial;
      formdata.IsFinal = item.IsFinal;
      formdata.IsForSetState = item.IsForSetState;
      formdata.IsAutoSchemeUpdate = item.IsAutoSchemeUpdate;
      formdata.UserComment = item.UserComment;
      formdata.Implementation = Array.isArray(item.Implementation) ? WorkflowDesignerCommon.clone(item.Implementation) : [];
      formdata.PreExecutionImplementation = Array.isArray(item.PreExecutionImplementation) ? WorkflowDesignerCommon.clone(item.PreExecutionImplementation) : [];
      formdata.Annotations = Array.isArray(item.Annotations) ? WorkflowDesignerCommon.clone(item.Annotations) : [];
      formdata.Conditions = transitions.true && transitions.true.item.Conditions ? WorkflowDesignerCommon.clone(transitions.true.item.Conditions) : [{
        Action: {ActionParameter: null},
        Type: 'Expression',
        Expression: null
      }];
      formdata.Conditions.forEach(function (condition) {
        if (!condition.Action)
          condition.Action = {};
      });
      formdata.WhenTrueTo = transitions.true ? transitions.true.to.GetName() : '';
      formdata.WhenFalseTo = transitions.false ? transitions.false.to.GetName() : '';
      formdata.WhenTrueClassifier = transitions.true ? transitions.true.item.Classifier : WorkflowDesignerConstants.NotSpecified;
      formdata.WhenFalseClassifier = transitions.false ? transitions.false.item.Classifier : WorkflowDesignerConstants.NotSpecified;

      me.linkItem = item;
      me.activityControl = me.activityManager.find(item.Name);
      data.originalItem = WorkflowDesignerCommon.clone(formdata);
      data.readonly = me.graph.Settings.readonly;
      data.actions = me.graph.getActionNames();
      methods.updateActivitiesList();
      data.itemHasComment = formdata.UserComment != null && formdata.UserComment?.length > 0;

      if ((formdata.State)
        || (formdata.Conditions.find(item => typeof (item.ResultOnPreExecution) === 'boolean'))
        || (formdata.WhenTrueClassifier && formdata.WhenTrueClassifier !== WorkflowDesignerConstants.NotSpecified)
        || (formdata.WhenFalseClassifier && formdata.WhenFalseClassifier !== WorkflowDesignerConstants.NotSpecified)) {
        data.expertMode = true;
      }
    };

    methods.showUserComment = function () {
      data.itemHasComment = true;
    }

    methods.onInitialChange = function () {
      var formdata = data.FormData;
      formdata.IsFinal = formdata.IsInitial ? false : formdata.IsFinal;
    };

    methods.onFinalChange = function () {
      var formdata = data.FormData;
      formdata.IsInitial = formdata.IsFinal ? false : formdata.IsInitial;
    };

    methods.setCurrentItem = function (item) {
      this.currentItem = item;
    };
    methods.querySearch = function (queryString, cb) {
      if (data.readonly)
        return cb([]);

      var res = me.graph.getAutoCompleteSuggestions2('actionparameter', this.currentItem.ActionName, queryString);
      cb(res);
    };

    methods.getFieldRules = function (field) {
      var res = [{required: true, message: WorkflowDesignerConstants.FieldIsRequired, trigger: 'blur'}];

      if (field === 'Name') {
        var validator = function (rule, value, callback) {
          var isValid = true;
          me.graph.data.Transitions.forEach(function (a) {
            if (a != me.linkItem && a.Name == value) {
              isValid = false;
            }
          });

          if (isValid) {
            callback();
          } else {
            callback(new Error(rule.message));
          }
        };
        res.push({validator: validator, message: WorkflowDesignerConstants.FieldMustBeUnique});
      }
      return res;
    };

    methods.validateField = function (name, item) {
      if (name !== 'Name' && name !== 'Actor.Name' && name !== 'Type' && name !== 'Action.ActionName' && name !== 'Expression')
        return;

      if (!WorkflowDesignerCommon.getValueByPropertyName(item, name)) {
        return WorkflowDesignerConstants.FieldIsRequired;
      }

      if (name === 'Type') {
        var conditions = data.FormData.Conditions;
        var labels = data.labels;
        if (item.Type === 'Always' && conditions.filter(function (c) {
          return c.Type == item.Type
        })?.length > 1) {
          return labels.AlwaysConditionShouldBeSingle;
        }

        if (item.Type === 'Otherwise' && conditions.filter(function (c) {
          return c.Type == item.Type
        })?.length > 1) {
          return labels.OtherwiseConditionShouldBeSingle;
        }
      }
    };

    methods.ActivityRules = function (res) {
      //validate on unique Activity name
      var validator = function (rule, value, callback) {
        var isValid = true;
        me.graph.data.Activities.forEach(function (a) {
          if (a != me.linkItem && a.Name == value) {
            isValid = false;
          }
        });

        if (isValid) {
          callback();
        } else {
          callback(new Error(rule.message));
        }
      };

      res.push({validator: validator, message: WorkflowDesignerConstants.FieldMustBeUnique});

      return res;
    };
    methods.addRow = function (items, item) {
      items.push(item || {});
    };

    methods.removeRow = function (items, index) {
      items.splice(index, 1);
    };

    methods.showjson = function (name, item, params) {
      data.editItem = item;
      me.editItem = item;

      var onSuccess = function (value) {
        if (me.editItem) {
          WorkflowDesignerCommon.setValueByPropertyName(me.editItem, name, value);
          data.editItem = undefined;
          delete me.editItem;
        }
      };

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

      var value = WorkflowDesignerCommon.getValueByPropertyName(item, name);
      data.jsonform = me.showjson(value, params, onSuccess, onClose);
    };

    methods.hasConditionAnyAction = function () {
      let result = false;
      for (var i = 0; i < data.FormData.Conditions?.length; i++) {
        if (data.FormData.Conditions[i].Type === 'Action') {
          result = true;
          break;
        }
      }
      return result;
    }

    methods.saveTransition = function () {
      var FormData = data.FormData;
      var transitions = data.transitions;

      var targetActivities = {
          true: me.activityManager.find(FormData.WhenTrueTo),
          false: me.activityManager.find(FormData.WhenFalseTo)
        }
      ;

      if (transitions.true) {
        transitions.true.setTo(targetActivities.true);
      } else {
        transitions.true = me.transitionManager.CreateNewTransition(me.activityControl, targetActivities.true);
      }
      transitions.true.item.Conditions = FormData.Conditions;
      transitions.true.item.Classifier = FormData.WhenTrueClassifier;

      if (transitions.false) {
        transitions.false.setTo(targetActivities.false);
      } else {
        transitions.false = me.transitionManager.CreateNewTransition(me.activityControl, targetActivities.false);
      }
      transitions.false.item.Classifier = FormData.WhenFalseClassifier;
    }

    methods.validate = function () {
      var validateFunc = methods.validateField;
      var formData = data.FormData;

      if (Array.isArray(formData.Conditions) && formData.Conditions?.length === 0) {
        data.showconditionerror = WorkflowDesignerConstants.TransitionFormLabel.ConditionsListShouldNotBeEmpty;
        return false;
      }

      for (var i = 0; i < formData.Conditions?.length; i++) {
        var item = formData.Conditions[i];
        if (validateFunc('Type', item) ||
          (item.Type === 'Action' && validateFunc('Action.ActionName', item)) ||
          (item.Type === 'Expression' && validateFunc('Expression', item)))
          return false;
      }

      return true;
    };


    methods.onSave = function () {
      if (this.$refs) {
        WorkflowDesignerCommon.validateForms(this.$refs).then(isValid => {
          if (isValid && methods.validate()) {
            methods.saveTransition();
            me.onSuccess(data.FormData);
            me.onClose(true);
          }
        }).catch(() => { }) // Validation failed
      }
    };

    methods.onClose = function () {

      if (data.readonly) {
        me.onClose(true);
        return;
      }

      var originalItem = data.originalItem;
      var item = data.FormData;

      if (WorkflowDesignerCommon.deepCompare(originalItem, item)) {
        me.onClose(true);
      } else {
        me.showConfirm();
        return false;
      }
    };

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

    me.showConfirm = function () {
      methods.showConfirm({
        title: WorkflowDesignerConstants.DialogConfirmText,
        message: WorkflowDesignerConstants.CloseWithoutSaving,
        onSuccess: function () {
          methods.onCloseSave();
        }
      });
    };
  }
</script>
