<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"
        :rules="getFieldRules('Name')"
        class="el-form-item"
        prop="Name"
        style="flex-grow: 1;">
        <el-input v-model="FormData.Name" :readonly="readonly"></el-input>
      </el-form-item>

      <el-form-item
        :label="customLabels.State"
        :rules="getFieldRules('State')"
        class="el-form-item"
        prop="'State'"
        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;">
    <div class="el-form--inline el-form--label-top" style="display: flex">
      <el-form-item
        :label="customLabels.LoopName"
        :rules="getFieldRules('LoopName')"
        class="el-form-item"
        prop="LoopName"
        style="flex-grow: 1;">
        <el-input v-model="FormData.LoopName" :readonly="readonly"></el-input>
      </el-form-item>
      <el-form-item
        :label="customLabels.LoopStateParameterName"
        :rules="getFieldRules('LoopStateParameterName')"
        class="el-form-item"
        prop="LoopStateParameterName"
        style="flex-grow: 1;">
        <el-input v-model="FormData.LoopStateParameterName" :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.LoopCounterValueParameterName"
        :rules="getFieldRules('LoopCounterValueParameterName')"
        class="el-form-item"
        prop="LoopCounterValueParameterName"
        style="flex-grow: 1;">
        <el-input v-model="FormData.LoopCounterValueParameterName" :readonly="readonly"></el-input>
      </el-form-item>
      <el-form-item
        :label="customLabels.CounterType"
        :rules="getFieldRules('CounterType')"
        class="el-form-item"
        prop="CounterType"
        style="flex-grow: 1;">
        <el-select v-model="FormData.CounterType" :disabled="readonly" placeholder="" @change="updateDropdowns()">
          <template
            v-for="item in Field?.CounterType?.DropdownValues"
            :key="item.Value"
          >
            <el-option
              :label="item.Name"
              :value="item.Value">
            </el-option>
          </template>
        </el-select>
      </el-form-item>
    </div>

    <div v-if="FormData.CounterType === 'Int'" class="el-form--inline el-form--label-top" style="display: flex; flex-wrap: wrap">
      <el-form-item :rules="getFieldRules('StartValue')" prop="StartValue">
        <template #label>{{ customLabels.StartValue }}
          <span :style="parameterFromProcess.StartValue ? {color:parameterFromProcessColor}: {}"
                class="WorkflowDesignerParameterFromProcess"
                @click="handleStartValue">@
          </span>
        </template>
        <el-input v-if="!parameterFromProcess.StartValue" v-model="FormData.StartValue" :disabled="readonly" style="width:180px"
                  type="number"></el-input>
        <el-input v-if="parameterFromProcess.StartValue" v-model="FormData.StartValue" :disabled="readonly" style="width:180px"></el-input>
      </el-form-item>
      <el-form-item :rules="getFieldRules('EndValue')" prop="EndValue">
        <template #label>{{ customLabels.EndValue }}
          <span :style="parameterFromProcess.EndValue ? {color:parameterFromProcessColor}: {}"
                class="WorkflowDesignerParameterFromProcess"
                @click="handleEndValue">@
          </span>
        </template>
        <el-input v-if="!parameterFromProcess.EndValue" v-model="FormData.EndValue" :disabled="readonly" style="width:180px"
                  type="number"></el-input>
        <el-input v-if="parameterFromProcess.EndValue" v-model="FormData.EndValue" :disabled="readonly" style="width:180px"></el-input>
      </el-form-item>
      <el-form-item :rules="getFieldRules('Step')" prop="Step">
        <template #label>{{ customLabels.Step }}
          <span :style="parameterFromProcess.Step ? {color:parameterFromProcessColor}: {}"
                class="WorkflowDesignerParameterFromProcess"
                @click="handleStep">@
          </span>
        </template>
        <el-input v-if="!parameterFromProcess.Step" v-model="FormData.Step" :disabled="readonly" style="width:180px"
                  type="number"></el-input>
        <el-input v-if="parameterFromProcess.Step" v-model="FormData.Step" :disabled="readonly" style="width:180px"></el-input>
      </el-form-item>
    </div>

    <div v-if="FormData.CounterType == 'DateTime'" class="el-form--inline el-form--label-top">
      <el-form-item
        v-if="!(parameterFromProcess.EndValue || parameterFromProcess.StartValue)"
        :rules="getDateRangeRules()"
        prop="DateRange">
          <template #label>{{ customLabels.DateRange }}
            <span
              class="WorkflowDesignerParameterFromProcess"
              @click="handleDateRange">@
            </span>
          </template>
        <el-date-picker
          v-model="FormData.DateRange"
          :end-placeholder="customLabels.EndDate"
          :range-separator="customLabels.RangeSeparator"
          :readonly="readonly"
          :start-placeholder="customLabels.StartDate"
          type="datetimerange">
        </el-date-picker>
      </el-form-item>

      <el-form-item
        v-if="parameterFromProcess.StartValue || parameterFromProcess.EndValue "
        :rules="getFieldRules('StartValue')"
        prop="DateRange.0">
          <template #label>{{ customLabels.StartValue }}
            <span
              :style="parameterFromProcess.StartValue ? {color:parameterFromProcessColor}: {}"
              class="WorkflowDesignerParameterFromProcess"
              @click="handleDateRangeStart">@
            </span>
          </template>
        <el-date-picker
          v-if="!parameterFromProcess.StartValue"
          v-model="FormData.DateRange[0]"
          :readonly="readonly"
          :required="true"
          style="width:200px"
          type="datetime">
        </el-date-picker>
        <el-input v-if="parameterFromProcess.StartValue" v-model="FormData.DateRange[0]" :disabled="readonly"
                  style="width:200px"></el-input>
      </el-form-item>

      <el-form-item
        v-if="parameterFromProcess.StartValue || parameterFromProcess.EndValue"
        :rules="getFieldRules('EndValue')"
        prop="DateRange.1">
          <template #label>{{ customLabels.EndValue }}
            <span :style="parameterFromProcess.EndValue ? {color:parameterFromProcessColor}: {}"
                  class="WorkflowDesignerParameterFromProcess"
                  @click="handleDateRangeEnd">@
            </span>
          </template>
        <el-date-picker
          v-if="!parameterFromProcess.EndValue"
          v-model="FormData.DateRange[1]"
          :readonly="readonly"
          :required="true"
          style="width:200px"
          type="datetime">
        </el-date-picker>
        <el-input v-if="parameterFromProcess.EndValue" v-model="FormData.DateRange[1]" :disabled="readonly" style="width:200px"></el-input>
      </el-form-item>
      <el-form-item
        :label="customLabels.Step"
        :rules="getDateStepRules()"
        prop="Step">
        <el-input v-model="FormData.Step" :readonly="readonly">
        </el-input>
      </el-form-item>
    </div>

    <div class="el-form--inline el-form--label-top">
      <el-form-item :rules="getFieldRules('StepType')" prop="StepType">
        <template #label>{{ customLabels.StepType }}
          <span
            :style="parameterFromProcess.StepType ? {color:parameterFromProcessColor}: {}"
            class="WorkflowDesignerParameterFromProcess"
            @click="handleStepType">@
          </span>
        </template>
        <el-select v-if="!parameterFromProcess.StepType" v-model="FormData.StepType" :disabled="readonly" style="width:180px">
          <template
            v-for="item in Field?.StepType?.DropdownValues"
            :key="item.Value"
          >
            <el-option :label="item.Name"
                       :value="item.Value">
            </el-option>
          </template>
        </el-select>
        <el-input v-if="parameterFromProcess.StepType" v-model="FormData.StepType" :disabled="readonly" style="width:180px"></el-input>
      </el-form-item>
      <el-form-item :rules="getFieldRules('IncludeLastValue')" prop="IncludeLastValue">
        <template #label>{{ customLabels.IncludeLastValue }}
          <span
            :style="parameterFromProcess.IncludeLastValue ? {color:parameterFromProcessColor}: {}"
            class="WorkflowDesignerParameterFromProcess"
            @click="handleIncludeLastValue">@
          </span>
        </template>
        <el-checkbox
          v-if="!parameterFromProcess.IncludeLastValue"
          v-model="FormData.IncludeLastValue"
          :disabled="readonly"
          style="width:180px">
        </el-checkbox>
        <el-input v-if="parameterFromProcess.IncludeLastValue" v-model="FormData.IncludeLastValue" :disabled="readonly"
                  style="width:180px"></el-input>
      </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_loopsplugin_startloopforform_Data(me) {
    return {
      customTitle: undefined,
      readonly: false,
      FormData: {},
      Field: {},
      parameterFromProcess: {
        StartValue: false,
        EndValue: false,
        Step: false,
        StepType: false,
        IncludeLastValue: false
      },
    }
  }

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

    methods.UpdateLanguage = function () {
      Object.assign(data, {
        labels: WorkflowDesignerConstants.EditParametersFormlabel,
        customLabels: WorkflowDesignerConstants.EditParametersFormlabel.CustomForms.StartLoopFor,
        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;
      }

      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.FromProcess = false;
          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.updateDropdowns = function () {
      for (const key in data.parameterFromProcess) {
        data.parameterFromProcess[key] = false;
      }

      data.FormData.DateRange = '';
      data.FormData.StartValue = '';
      data.FormData.EndValue = '';
      data.FormData.Step = '';
    }

    methods.initializeData = function () {
      var counterType = data.FormData.CounterType;
      var step = data.FormData.Step;
      var stepType = data.FormData.StepType;
      var endValue = data.FormData.EndValue;
      var startValue = data.FormData.StartValue;
      if (counterType === 'DateTime') {
        var endValueDate = data.parameterFromProcess.EndValue ? endValue : new Date(endValue);
        var startValueDate = data.parameterFromProcess.StartValue ? startValue : new Date(startValue);

        data.FormData.Step = step;
        if (stepType === 'Decrement') {
          data.FormData.DateRange = [endValueDate, startValueDate];
        } else {
          data.FormData.DateRange = [startValueDate, endValueDate];
        }
      }

      if (counterType === 'Int') {
        data.FormData.StartValue = startValue != null ? startValue : '';
        data.FormData.EndValue = endValue != null ? endValue : '';
        data.FormData.Step = step != null ? step : '';
        data.FormData.DateRange = '';
      }
    }

    methods.isFromProcess = function (fieldName) {
      if (typeof data.Field[fieldName].FromProcess !== 'undefined'
        && data.Field[fieldName].FromProcess == true) {
        return true;
      }
      return false;
    }

    methods.changeParameterInput = function (fieldName) {
      data.parameterFromProcess[fieldName] = !data.parameterFromProcess[fieldName];
    }

    methods.getDateRangeRules = function () {
      var res = [
        {required: true, message: WorkflowDesignerConstants.FieldIsRequired, trigger: ['change', 'blur']}
      ];
      var validator = function (rule, value, callback) {
        var isValid = true;
        var dateRange = data.FormData.DateRange;
        if (!dateRange
          || dateRange.length !== 2
          || dateRange.includes(null)
          || dateRange.includes('')
        ) {
          isValid = false;
        }

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

    methods.getDateStepRules = function () {
      var res = [
        {required: true, message: WorkflowDesignerConstants.FieldIsRequired, trigger: 'blur'}
      ];
      var validator = function (rule, value, callback) {
        var step = data.FormData.Step
        if (WorkflowDesignerCommon.containsAt(step)) {
          callback();
          return
        }
        var isValid = true;
        step = step.trim();
        var stepArray = step.split(/\s+/);
        step = 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 (!(step && 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 (fieldName) {
      var isRequired = data?.Field[fieldName]?.IsRequired ?? false;
      var rules = isRequired ? me.requiredRule() : [{required: false}];

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

      if (isRequired && data.FormData.CounterType === 'DateTime' && (fieldName === 'EndValue' || fieldName === 'StartValue')) {
        var validator = function (rule, value, callback) {
          if (value != null && value != '') {
            callback();
          } else {
            callback(new Error(rule.message));
          }
        };
        rules.push({validator: validator, message: WorkflowDesignerConstants.FieldIsRequired});
      }

      return rules;
    };

    methods.onSave = function () {

      this.$refs.form.validate(function (valid) {
        if (valid) {
          if (data.FormData.CounterType == 'DateTime') {
            var dateFormat = WorkflowDesignerConstants.DateTimeFormat;
            var dateRange = data.FormData.DateRange;
            var endValueDate = data.parameterFromProcess.EndValue ? dateRange[1] : moment(dateRange[1]).format(dateFormat);
            var startValueDate = data.parameterFromProcess.StartValue ? dateRange[0] : moment(dateRange[0]).format(dateFormat);

            if (data.FormData.StepType == 'Decrement') {
              data.FormData.EndValue = startValueDate;
              data.FormData.StartValue = endValueDate
            } else {
              data.FormData.EndValue = endValueDate;
              data.FormData.StartValue = startValueDate;
            }
          }

          var value = WorkflowDesignerCommon.toString(data.FormData);

          me.onSuccess(WorkflowDesignerCommon.toCompactJSON(value));
          me.onClose(true);
        }
      });
    };

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

    methods.handleStartValue = () => {
      data.FormData.StartValue = null;
      methods.changeParameterInput('StartValue');
    };

    methods.handleEndValue = () => {
      data.FormData.EndValue = null;
      methods.changeParameterInput('EndValue');
    };

    methods.handleStep = () => {
      data.FormData.Step = null;
      methods.changeParameterInput('Step')
    };

    methods.handleDateRange = () => {
      data.FormData.DateRange = ['', ''];
      data.parameterFromProcess.EndValue = true;
      data.parameterFromProcess.StartValue = true
    };

    methods.handleDateRangeStart = () => {
      data.FormData.DateRange[0] = '';
      data.parameterFromProcess.StartValue = !data.parameterFromProcess.StartValue;
    };

    methods.handleDateRangeEnd = () => {
      data.FormData.DateRange[1] = '';
      data.parameterFromProcess.EndValue = !data.parameterFromProcess.EndValue;
    };

    methods.handleStepType = () => {
      data.FormData.StepType = data.parameterFromProcess.StepType ? data.Field.StepType?.DropdownValues[0]?.Value : null;
      methods.changeParameterInput(data.Field.StepType.Name)
    };

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