<h3>{{ customTitle ? customTitle : labels.Title }}</h3>
<el-form
  ref="form"
  :model="FormData"
  class="WorkflowDesignerWindowForm"
  label-position="top"
  label-width="150px">
  <div v-if="Field.State != undefined" class="SettingsWithPadding">
    <div class="el-form--inline el-form--label-top">
      <el-form-item
        :label="customLabels.Name"
        prop="Name"
        :rules="getFieldRules(Field.Name)"
        class="el-form-item"
        style="flex-grow: 1;">
        <el-input v-model="FormData.Name" :readonly="readonly"></el-input>
      </el-form-item>

      <el-form-item
        :label="customLabels.State"
        prop="State"
        :rules="getFieldRules(Field.State)"
        class="el-form-item"
        style="flex-grow: 1;">
        <el-input v-model="FormData.State" :readonly="readonly"></el-input>
      </el-form-item>
    </div>
  </div>

  <h4 v-if="Field.State != undefined" style="padding-bottom: 1px;border-bottom: 1px solid rgba(34,36,38,.15);">
    {{ customLabels.Heading }}</h4>

  <div :class="Field.State != undefined ?'SettingsWithPadding' : '' " style="margin-bottom: 10px;">
    <el-form-item
      :label="customLabels.Code"
      prop="AssignmentCode"
      :rules="getFieldRules(Field.AssignmentCode)"
      class="el-form-item"
      style="flex-grow: 4;">
      <el-input v-model="FormData.AssignmentCode" :readonly="readonly"></el-input>
    </el-form-item>
    <div>
      <h4 class="WorkflowDesignerTitleWithCreate">
        {{ customLabels.ReplacementExecutors }}
        <a v-if="!readonly" @click="addValue(FormData.ReplacementExecutors)">{{ ButtonTextCreate }}</a>
      </h4>
    </div>
  </div>

  <div id="WorkflowDesignerParametersList" style="margin-bottom: 10px">
    <table class="WorkflowDesignerTable">
      <tr v-if="FormData.ReplacementExecutors.length > 0">
        <th></th>
        <th>{{ customLabels.OldExecutor }}</th>
        <th>{{ customLabels.NewExecutor }}</th>
      </tr>
      <tr v-for="(replacementExecutor, index) in FormData.ReplacementExecutors" :key="index"
          :class="dragOverIndex == index && dragOverBlock  == replacementExecutor ? 'dragOver' : ''"
          @dragend="dragend($event, FormData.ReplacementExecutors)" @dragover="dragover(replacementExecutor, index, $event)"
          @dragstart="dragstart(index, $event)">
        <td :draggable="!readonly" class='WorkflowDesignerTableMoveCol'>
          <div v-if="!readonly" class='WorkflowDesignerTableMoveButton'></div>
        </td>
        <td>
          <el-select
            v-model="replacementExecutor.oldExecutor"
            :disabled="readonly"
            :loading="loading"
            :readonly="readonly"
            :remote-method="getUsers"
            filterable
            remote
            reserve-keyword
            style="width:100%"
            @focus="onFocusSelectUser">
            <el-option-group>
              <el-option
                :label="customLabels.AllExecutors"
                :value="allExecutorsOption">
              </el-option>
              <el-option v-for="actor in actors"
                         :key="actor.value"
                         :label="actor.name"
                         :value="actor">
              </el-option>
            </el-option-group>
            <el-option-group>
              <el-option
                v-for="user in userIdentities"
                :key="user.value"
                :label="user.userName"
                :value="user">
              </el-option>
            </el-option-group>
          </el-select>
        </td>
        <td>
          <el-select
            v-model="replacementExecutor.newExecutor"
            :class="validateExecutorField(replacementExecutor.newExecutor) ? 'WorkflowDesignerInputError' : ''"
            :disabled="readonly"
            :loading="loading"
            :readonly="readonly"
            :remote-method="getUsers"
            :title="validateExecutorField(replacementExecutor.newExecutor)"
            filterable
            remote
            reserve-keyword
            style="width:100%"
            @focus="onFocusSelectUser">
            <el-option
              v-for="user in userIdentities"
              :key="user.value"
              :label="user.userName"
              :value="user">
            </el-option>
          </el-select>
        </td>
        <td v-if="!readonly">
          <el-button class="WorkflowDesignerTableDeleteButton" @click="removeRow(FormData.ReplacementExecutors, index)"></el-button>
        </td>
      </tr>
    </table>
  </div>

  <div :class="Field.State != undefined ?'SettingsWithPadding' : '' " style="margin-bottom: 10px;">
    <div class="el-form--inline el-form--label-top" style="display: flex">
      <el-form-item size="small">
        <span style="margin-right: 20px"><b>{{ customLabels.Change }}:</b> </span>
        <el-checkbox
          v-model="FormData.ChangeStatus"
          :disabled="readonly"
          :label="customLabels.Status">
        </el-checkbox>
        <el-checkbox
          v-model="FormData.ChangeState"
          :disabled="readonly"
          :label="customLabels.State">
        </el-checkbox>
        <el-checkbox
          v-model="FormData.ChangeDeadlineToStart"
          :disabled="readonly"
          :label="customLabels.DeadlineToStart">
        </el-checkbox>
        <el-checkbox
          v-model="FormData.ChangeDeadlineToComplete"
          :disabled="readonly"
          :label="customLabels.DeadlineToComplete">
        </el-checkbox>
        <el-checkbox
          v-model="FormData.ChangeTags"
          :disabled="readonly"
          :label="customLabels.Tags">
        </el-checkbox>
        <el-checkbox
          v-model="FormData.ChangeObservers"
          :disabled="readonly"
          :label="customLabels.Observers">
        </el-checkbox>
      </el-form-item>
    </div>

    <div class="el-form--inline el-form--label-top" style="display: flex">
      <el-form-item
        v-if="FormData.ChangeStatus"
        prop="StatusState"
        :rules="getFieldRules(Field.StatusState)"
        class="el-form-item"
        style="flex-grow: 1">
          <template #label>{{ customLabels.StatusState }}
            <span
              :style="parameterFromProcess.StatusState ? {color:parameterFromProcessColor}: {}"
              class="WorkflowDesignerParameterFromProcess"
              @click="toggleStatus">@
            </span>
          </template>
        <el-select v-if="!parameterFromProcess.StatusState" v-model="FormData.StatusState" :disabled="readonly"
                   :title="Field?.StatusState?.Comment" style="width: 100%">
          <el-option
            v-for="item in Field?.StatusState?.DropdownValues"
            :key="item.Value"
            :label="item.Name"
            :value="item.Value">
          </el-option>
        </el-select>
        <el-input v-if="parameterFromProcess.StatusState" v-model="FormData.StatusState" :disabled="readonly"
                  style="width: 100%"></el-input>
      </el-form-item>

      <el-form-item
        v-if="FormData.ChangeState"
        prop="IsActive"
        :rules="getFieldRules(Field.IsActive)"
        class="el-form-item"
        style="flex-grow: 1;">
          <template #label>{{ customLabels.IsActive }}
            <span
              :style="parameterFromProcess.IsActive ? {color:parameterFromProcessColor}: {}"
              class="WorkflowDesignerParameterFromProcess"
              @click="toggleActive">@
            </span>
          </template>
        <el-checkbox
          v-if="!parameterFromProcess.IsActive"
          v-model="FormData.IsActive"
          :disabled="readonly"
          style="width:150px">
        </el-checkbox>
        <el-input v-if="parameterFromProcess.IsActive" v-model="FormData.IsActive" :disabled="readonly" style="width:150px"></el-input>
      </el-form-item>
    </div>

    <div class="el-form--inline el-form--label-top" style="display: flex">
      <el-form-item
        v-if="FormData.ChangeDeadlineToStart"
        :label="customLabels.DeadlineToStart"
        prop="DeadlineToStart"
        :rules="getDateStepRules(FormData.DeadlineToStart)"
        class="el-form-item"
        style="flex-grow: 1;">
        <el-input v-model="FormData.DeadlineToStart" :readonly="readonly">
        </el-input>
      </el-form-item>

      <el-form-item
        v-if="FormData.ChangeDeadlineToComplete"
        :label="customLabels.DeadlineToComplete"
        prop="DeadlineToComplete"
        :rules="getDateStepRules(FormData.DeadlineToComplete)"
        class="el-form-item"
        style="flex-grow: 1;">
        <el-input v-model="FormData.DeadlineToComplete" :readonly="readonly">
        </el-input>
      </el-form-item>
    </div>

    <div class="el-form--inline el-form--label-top" style="display: flex">
      <el-form-item
        v-if="FormData.ChangeObservers"
        :label="customLabels.Observers"
        prop="Observers"
        :rules="getFieldRules(Field.Observers)"
        style="width:100%">
        <el-select
          v-model="FormData.Observers"
          :disabled="readonly"
          :loading="loading"
          :readonly="readonly"
          :remote-method="getUsers"
          filterable
          multiple
          remote
          :reserve-keyword="false"
          style="width:100%"
          @focus="onFocusSelectUser">
          <el-option
            v-for="user in userIdentities"
            :key="user.value"
            :label="user.userName"
            :value="user">
          </el-option>
        </el-select>
      </el-form-item>
    </div>
    <div class="el-form--inline el-form--label-top" style="display: flex">
      <el-form-item
        v-if="FormData.ChangeTags"
        :label="customLabels.Tags"
        prop="Tags"
        :rules="getFieldRules(Field.Tags)"
        style="width:100%">
        <el-tag
          v-for="tag in FormData.Tags"
          :key="tag"
          :closable="!readonly"
          :disable-transitions="false"
          class="el-form-item"
          style="margin-right: 5px;flex-grow: 1;"
          @close="handleClose(FormData.Tags, tag)">
          {{ tag }}
        </el-tag>
        <el-input
          v-if="inputTagVisible"
          ref="saveTagInput"
          v-model="inputTagValue"
          :readonly="readonly"
          class="el-form-item"
          size="small"
          style="line-height:normal;width: 150px;flex-grow: 1;"
          @blur="handleTagInputConfirm"
          @keydown.enter="handleTagInputConfirm">
        </el-input>
        <el-button v-if="!inputTagVisible && !readonly" class="el-form-item" size="small" @click="showTagInput">+
          {{ customLabels.NewTag }}
        </el-button>
      </el-form-item>
    </div>
  </div>
</el-form>

<div class="WorkflowDesignerButtons">
  <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 customforms_assignmentplugin_assignmentchangeform_Data(me) {
    return {
      actors: [],
      customTitle: undefined,
      readonly: false,
      FormData: {
        ReplacementExecutors: []
      },
      Field: {},
      parameterFromProcess: {
        IsActive: false,
        StatusState: false
      },
      inputTagVisible: false,
      inputTagValue: '',
      userIdentities: [],
      loading: false,
      allExecutorsOption: {value: null, isActor: false, name: null }
    }
  }

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

    methods.UpdateLanguage = function () {
      Object.assign(data, {
        FieldIsRequired: WorkflowDesignerConstants.FieldIsRequired,
        labels: WorkflowDesignerConstants.EditParametersFormlabel,
        customLabels: WorkflowDesignerConstants.EditParametersFormlabel.CustomForms.AssignmentChange,
        ButtonTextSave: WorkflowDesignerConstants.ButtonTextSave,
        ButtonTextCancel: WorkflowDesignerConstants.ButtonTextCancel,
        ButtonTextCreate: WorkflowDesignerConstants.ButtonTextCreate,
        parameterFromProcessColor: WorkflowDesignerConstants.ParameterFromProcessColor,
      })
    }

    methods.UpdateLanguage();

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

      if (me.options && me.options.customTitle) {
        data.customTitle = me.options.customTitle;
      }

      var fields = undefined;
      var parameterDefinition = me.options.parameterDefinition;

      if (parameterDefinition && parameterDefinition.name) {
        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 if (Array.isArray(me.options.parameterDefinition)) {
        fields = me.options.parameterDefinition;
      }

      if (fields && fields.length > 0) {
        fields.forEach(function (field) {
          field.Label = field.Title ? field.Title : field.Name;
          if (field.Comment && field.Comment !== '') {
            field.Label = field.Label + ' (' + field.Comment + ')';
          }

          data.Field[field.Name] = field;
        });

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

          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') {
              tmp[field.Name] = field.DefaultValue;
            } else {
              tmp[field.Name] = null;
            }
          });

          value = WorkflowDesignerCommon.toString(tmp);
        }
      }

      data.FormData = WorkflowDesignerCommon.toJSON(value);

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

      for (const key in data.FormData) {
        if (typeof data.parameterFromProcess[key] !== 'undefined' && WorkflowDesignerCommon.containsAt(data.FormData[key]))
          data.parameterFromProcess[key] = true;
        if (key !== '__customtype' && data.FormData.hasOwnProperty(key))
          if (!data.Field.hasOwnProperty(key))
            delete data.FormData[key];
      }

      data.FormData = me.graph.insertDefaultValuesInForm(data.Field, data.FormData);

      methods.initializeData();
    };


    methods.initializeData = function () {
      var FormData = data.FormData;

      data.actors = me.graph.getActorNames().map(actor => {
        return{value: actor, isActor: true, name: actor}
      });

      FormData.DeadlineToStart = FormData.DeadlineToStart || '';
      FormData.DeadlineToComplete = FormData.DeadlineToComplete || '';

      var observers = FormData.Observers
      if (observers === null || observers === undefined) {
        FormData.Observers = [];
      } else {
        FormData.Observers = JSON.parse(observers);
        FormData.Observers.forEach(function (observers) {
          data.userIdentities.push({value: observers.identity, isActor: false, identity: observers.identity, userName: observers.userName});
        });
      }

      var executors = FormData.ReplacementExecutors
      if (executors === null || executors === undefined) {
        FormData.ReplacementExecutors = [];
      } else {
        FormData.ReplacementExecutors = JSON.parse(executors);
        FormData.ReplacementExecutors.forEach(function (item) {
          var oldExecutor = item.oldExecutor;
          var newExecutor = item.newExecutor;
          if (!oldExecutor.isActor && oldExecutor.value !== null) {
            data.userIdentities.push({value: oldExecutor.value, isActor: oldExecutor.isActor, userName: oldExecutor.userName});
          }
          data.userIdentities.push({value: newExecutor.identity, isActor: newExecutor.isActor, identity: newExecutor.identity, userName: newExecutor.userName});
        });
      }

      var tags = FormData.Tags;
      FormData.Tags =
        tags === null || tags === undefined
          ? [] : JSON.parse(tags);
    };

    methods.onFocusSelectUser = function (event) {
      if (event.sourceCapabilities != null) {
        methods.getUsers('');
      }
    };

    methods.getUsers = function (query) {
      data.loading = true;
      setTimeout(function () {
        var users = me.graph.designer.getuseridentities(query, 1, 20);
        data.userIdentities = users.map(user => {
          return {value: user.Identity, isActor: false, identity: user.Identity, userName: user.UserName};
        })
        data.loading = false;
      }, 200);
    };

    methods.handleClose = function (items, item) {
      items.splice(items.indexOf(item), 1);
    };

    methods.showTagInput = function () {
      data.inputTagVisible = true;
      this.$nextTick(function (_) {
        this.$refs.saveTagInput.$refs.input.focus();
      });
    };

    methods.handleTagInputConfirm = function (evt, foo, bar) {
      let inputValue = data.inputTagValue;
      if (inputValue) {
        data.FormData.Tags.push(inputValue);
      }
      data.inputTagVisible = false;
      data.inputTagValue = '';
    };

    methods.addValue = function (items) {
      items.push({oldExecutor: {value: null, isActor: false}, newExecutor: ''});

      setTimeout(function () {
        var objDiv = document.getElementById('WorkflowDesignerParametersList');
        objDiv.scrollTop = objDiv.scrollHeight;
      }, 100);
    };

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

    methods.validateExecutorField = function (item) {
      if (item == null || item.length == 0)
        return WorkflowDesignerConstants.FieldIsRequired;
    };

    methods.getDateStepRules = function (interval) {
      var res = [];
      var validator = function (rule, value, callback) {
        if (interval == null || interval == '' || WorkflowDesignerCommon.containsAt(interval)) {
          callback();
          return;
        }

        var isValid = true;
        interval = interval.trim();
        var stepArray = interval.split(/\s+/);
        interval = stepArray.join(' ');

        var yearsRegex = new RegExp('\d*\s*((years)|(year)|(y))(\W|\d|$)');
        var monthsRegex = new RegExp('\d*\s*((months)|(month)|(mm))(\W|\d|$)');
        var daysRegex = new RegExp('\d*\s*((days)|(day)|(d))(\W|\d|$)');
        var hoursRegex = new RegExp('\d*\s*((hours)|(hour)|(h))(\W|\d|$)');
        var minutesRegex = new RegExp('\d*\s*((minutes)|(minute)|(m))(\W|\d|$)');
        var secondsRegex = new RegExp('\d*\s*((seconds)|(second)|(s))(\W|\d|$)');
        var millisecondsRegex = new RegExp('\d*\s*((milliseconds)|(millisecond)|(ms))(\W|\d|$)');

        var isCorrect = true;
        stepArray.forEach(function (step) {
          isCorrect &= yearsRegex.test(step)
            || monthsRegex.test(step)
            || daysRegex.test(step)
            || hoursRegex.test(step)
            || minutesRegex.test(step)
            || secondsRegex.test(step)
            || millisecondsRegex.test(step);
        });

        if (!(interval && isCorrect)) {
          isValid = false;
        }

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

    methods.getFieldRules = function (field) {
      if (!field) return [];

      var rules = field.IsRequired ? me.requiredRule() : [{required: false}];

      if (data.parameterFromProcess[field.Name]) {
        rules.push(WorkflowDesignerCommon.containsAtRule);
      }

      return rules;
    };

    methods.validate = function () {
      var replacements = data.FormData.ReplacementExecutors;
      for (var i = 0; i < replacements.length; i++) {
        if (replacements[i].newExecutor == null || replacements[i].newExecutor.length == 0 || replacements[i].oldExecutor == null) {
          return false;
        }
      }
      return true;
    };

    methods.onSave = function () {
      this.$refs.form.validate(function (valid) {
        if (valid && methods.validate()) {
          var dataClone = WorkflowDesignerCommon.clone(data.FormData);
          dataClone.Observers = JSON.stringify(dataClone.Observers);
          dataClone.ReplacementExecutors = JSON.stringify(dataClone.ReplacementExecutors);
          dataClone.Tags = JSON.stringify(dataClone.Tags);

          var value = WorkflowDesignerCommon.toString(dataClone);
          me.onSuccess(WorkflowDesignerCommon.toCompactJSON(value));
          me.onClose(true);
        }
      });
    };

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

    methods.toggleStatus = function () {
      data.FormData.StatusState = null;
      data.parameterFromProcess.StatusState = !data.parameterFromProcess.StatusState
    }

    methods.toggleActive = function () {
      data.FormData.IsActive = data.parameterFromProcess.IsActive ? false : null;
      data.parameterFromProcess.IsActive = !data.parameterFromProcess.IsActive
    }
  }
</script>
