<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="Field?.Name?.Label"
        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.Name"
      prop="AssignmentName"
      :rules="getFieldRules(Field.AssignmentName)">
      <el-input v-model="FormData.AssignmentName" :readonly="readonly"></el-input>
    </el-form-item>

    <div class="el-form--inline el-form--label-top" style="display: flex">
      <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>
      <el-form-item
        :label="customLabels.Executors"
        prop="Executors"
        :rules="getExecutorsRules()"
        class="el-form-item"
        style="flex-grow: 4;">
        <el-select
          v-model="FormData.Executors"
          :disabled="readonly"
          :loading="loading"
          :readonly="readonly"
          :remote-method="getUsers"
          filterable
          multiple
          remote
          :reserve-keyword="false"
          style="width:100%"
          @focus="onFocusSelectUser">
          <el-option-group>
            <el-option v-for="item in actors"
                       :key="item.value"
                       :label="item.name"
                       :value="item">
            </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>
      </el-form-item>
      <el-form-item
        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>

    <el-form-item
      :label="customLabels.Description"
      prop="Description"
      :rules="getFieldRules(Field.Description)">
      <el-input
        v-model="FormData.Description"
        :readonly="readonly"
        :rows="3"
        type="textarea"></el-input>
    </el-form-item>

    <div class="el-form--inline el-form--label-top" style="display: flex">
      <el-form-item
        :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
        :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
        :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
        :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_assignmentcreateform_Data(me) {
    return {
      customTitle: undefined,
      readonly: false,
      FormData: {},
      Field: {},
      parameterFromProcess: {
        IsActive: false,
      },
      actors: [],
      inputTagVisible: false,
      inputTagValue: '',
      userIdentities: [],
      loading: false
    }
  }

  function customforms_assignmentplugin_assignmentcreateform_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.AssignmentCreate,
        ButtonTextSave: WorkflowDesignerConstants.ButtonTextSave,
        ButtonTextCancel: WorkflowDesignerConstants.ButtonTextCancel,
        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;
      }

      let fields = undefined;
      const parameterDefinition = me.options.parameterDefinition;

      if (parameterDefinition && parameterDefinition.name) {
        for (let 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) {
          const 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 () {
      const 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 || '';

      const 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: observers.isActor, identity: observers.identity, userName: observers.userName});
        });
      }

      const executors = FormData.Executors
      if (executors === null || executors === undefined) {
        FormData.Executors = [];
      } else {
        FormData.Executors = JSON.parse(executors);
        FormData.Executors.forEach(function (executor) {
          if (!executor.isActor) {
            data.userIdentities.push({value: executor.value, isActor: executor.isActor, userName: executor.userName});
          }
        });
      }

      FormData.Tags = JSON.parse(FormData.Tags ?? '[]');
    };

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

    methods.getUsers = function (query) {
      data.loading = true;
      setTimeout(function () {
        const users = me.graph.designer.getuseridentities(query, 1, 20);
        data.userIdentities = users.map(function (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 () {
      let inputValue = data.inputTagValue;
      if (inputValue) {
        data.FormData.Tags.push(inputValue);
      }
      data.inputTagVisible = false;
      data.inputTagValue = '';
    };

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

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

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

        let 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.getExecutorsRules = function () {
      const res = me.requiredRule();
      const executors = data.FormData.Executors;
      const validator = function (rule, value, callback) {
        if (executors == null || executors.length <= 0) {
          callback(new Error(rule.message));
        } else {
          callback();
        }
      };
      res.push({validator, message: WorkflowDesignerConstants.FieldIsNotCorrected, trigger: 'blur'});
      return res;
    }

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

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

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

      return rules;
    };

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

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

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

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


