<i18n>
{
  "en": {
    "VerificationEdit": {
      "title": "verification edit",
      "createTitle": "verification create",
      "type": "Type",
      "code": "Code",
      "goal": "Goal",
      "autolVerificationsTitle": "Autochecks",
      "manualVerificationsTitle": "Manual checks",
      "rejectCode": "Reject code",
      "name": "Name",
      "invertLabel": "Invert label",
      "basedOn": "Based on",
      "applicableForObjectType": "Applicable for",
      "noResult": "No directories",
      "applicability": "Applicability",
      "applicabilityApplication": "Conditions of applicability to an application",
      "applicabilityAttribute": "Attribute path in statement",
      "applicabilityEquality": "Comparison operator",
      "applicabilityValue": "What value to compare with",
      "subjectType": "Subject type",
      "attribute": "attribute",
      "applicabilityType": "applicability type",
      "addApplicabilityTitle": "New applicability",
      "conditionType": "Condition type",
      "jsonEditorMode": "Json editor mode",
      "formMode": "Form mode"

    }
  },
  "ru": {
    "VerificationEdit": {
      "title": "Редактирование данных проверки",
      "createTitle": "Новая проверка",
      "type": "Тип",
      "code": "Код",
      "goal": "Цели",
      "rejectCode": "Код отказа",
      "autolVerificationsTitle": "Aвтопроверки ",
      "manualVerificationsTitle": "Ручные проверки",
      "name": "Наименование",
      "invertLabel": "Инвертированое значение",
      "basedOn": "Основан на",
      "applicableForObjectType": "Применим к",
      "noResult": "Обьект не выбран",
      "applicability" : "Условия проверки",
      "applicabilityApplication": "Условия применимости к заявлению",
      "applicabilityAttribute": "Путь к атрибуту в заявлении",
      "applicabilityEquality": " Оператор сравнения",
      "applicabilityValue": "С каким значением сравнивать",
      "subjectType": "Субъект",
      "attribute": "Атрибут субъекта",
      "applicabilityType": "Тип условия",
      "addApplicabilityTitle": "Новое условие",
      "conditionType": "Тип Выражения",
      "applicabilityError": "Выберите тип условия",
      "jsonEditorMode": "Режим редактора json",
      "formMode": "Режим формы"
    }
  }
}
</i18n>

<template>
  <q-dialog v-model="dialogOpen" @hide="clearModel">
    <q-card class="full-width no-shadow" style="max-width: 800px">
      <q-card-section>
        <div class="text-h6">
          {{
            isEditForm
              ? $t('VerificationEdit.title')
              : $t('VerificationEdit.createTitle')
          }}
        </div>
      </q-card-section>
      <q-card-section class="q-pb-md q-gutter-y-md">
        <q-btn-toggle
          v-if="isEditForm"
          v-model="jsoneditorMode"
          toggle-color="primary"
          :options="toggleBtnOptions"
        />
        <v-json-editor
          v-if="jsoneditorMode"
          ref="jsoneditor"
          v-model="dialogData"
          :options="{ mode: 'code' }"
          height="400px"
        />
        <div v-if="dialogData && !jsoneditorMode" class="q-gutter-y-md">
          <q-input
            v-model="dialogData.code"
            filled
            :readonly="isEditForm"
            :label="$t('VerificationEdit.code')"
          />

          <q-select
            v-if="dialogData.type"
            v-model="dialogData.type"
            filled
            emit-value
            map-options
            :options="verificationType"
            :label="$t('VerificationEdit.type')"
          />

          <q-input
            v-model="dialogData.name"
            filled
            type="textarea"
            :label="$t('VerificationEdit.name')"
          />

          <q-input
            v-model="dialogData.invertLabel"
            filled
            type="textarea"
            :label="$t('VerificationEdit.invertLabel')"
          />

          <div v-if="dialogData.basedOn" class="row q-gutter-sm">
            <div class="col">
              {{ $t('VerificationEdit.basedOn') }}
            </div>

            <div class="col">
              <q-select
                v-model="dialogData.basedOn.type"
                filled
                :options="basedOnTypes"
                :label="$t('VerificationEdit.type')"
              />
            </div>

            <div class="col">
              <q-input
                v-model="dialogData.basedOn.code"
                filled
                :label="$t('VerificationEdit.code')"
              />
            </div>

            <div class="col">
              <q-input
                v-model="dialogData.basedOn.title"
                filled
                :label="$t('VerificationEdit.name')"
              />
            </div>
          </div>

          <q-input
            v-model="dialogData.rejectCode"
            filled
            :label="$t('VerificationEdit.rejectCode')"
          />

          <q-input
            v-if="dialogData.applicableForObjectType"
            v-model="dialogData.applicableForObjectType"
            filled
            readonly
            :label="$t('VerificationEdit.applicableForObjectType')"
          />

          <div
            v-if="dialogData.applicability && dialogData.type === 'manual'"
            class="q-gutter-sm"
          >
            <div class="text-h6">
              {{ $t('VerificationEdit.applicability') }}
            </div>

            <div v-if="application">
              <div>
                {{ $t('VerificationEdit.applicabilityApplication') }}
              </div>

              <div v-if="application.condition" class="row q-gutter-sm">
                <div class="col">
                  <q-input
                    v-model="application.condition.attribute"
                    filled
                    :label="$t('VerificationEdit.applicabilityAttribute')"
                  />
                </div>

                <div class="col">
                  <q-select
                    v-model="application.condition.equality"
                    filled
                    :label="$t('VerificationEdit.applicabilityEquality')"
                    :options="equalityType"
                  />
                </div>

                <div class="col">
                  <q-input
                    v-model="application.condition.value"
                    filled
                    :label="$t('VerificationEdit.applicabilityValue')"
                  />
                </div>
              </div>

              <div v-if="application.and">
                (и)
                <div
                  v-for="(item, index) in application.and"
                  :key="`condition-${index}`"
                >
                  <div v-if="item.condition" class="row q-gutter-sm">
                    <div class="col">
                      <q-input
                        v-model="item.condition.attribute"
                        filled
                        :label="$t('VerificationEdit.applicabilityAttribute')"
                      />
                    </div>

                    <div class="col">
                      <q-select
                        v-model="item.condition.equality"
                        filled
                        :label="$t('VerificationEdit.applicabilityEquality')"
                        :options="equalityType"
                      />
                    </div>

                    <div class="col">
                      <q-input
                        v-model="item.condition.value"
                        filled
                        :label="$t('VerificationEdit.applicabilityValue')"
                      />
                    </div>
                  </div>
                </div>
              </div>
              <div v-if="application.or">
                (или)
                <div
                  v-for="(item, index) in application.or"
                  :key="`condition-${index}`"
                >
                  <div v-if="item.condition" class="row q-gutter-sm">
                    <div class="col">
                      <q-input
                        v-model="item.condition.attribute"
                        filled
                        :label="$t('VerificationEdit.applicabilityAttribute')"
                      />
                    </div>

                    <div class="col">
                      <q-select
                        v-model="item.condition.equality"
                        filled
                        :label="$t('VerificationEdit.applicabilityEquality')"
                        :options="equalityType"
                      />
                    </div>

                    <div class="col">
                      <q-input
                        v-model="item.condition.value"
                        filled
                        :label="$t('VerificationEdit.applicabilityValue')"
                      />
                    </div>
                  </div>
                </div>
              </div>
            </div>

            <div v-if="subjects">
              <div v-for="(item, index) in subjects" :key="`subject-${index}`">
                <div v-if="item.conditions" class="q-gutter-y-md">
                  <div>Условия применимости к субъектам заявления</div>
                  <q-input
                    v-model="item.subjectType"
                    filled
                    :label="$t('VerificationEdit.subjectType')"
                  />

                  <div v-if="item.conditions.condition" class="row q-gutter-sm">
                    <div class="col">
                      <q-input
                        v-model="item.conditions.condition.attribute"
                        filled
                        :label="$t('VerificationEdit.attribute')"
                      />
                    </div>

                    <div class="col">
                      <q-select
                        v-model="item.conditions.condition.equality"
                        filled
                        :label="$t('VerificationEdit.applicabilityEquality')"
                        :options="equalityType"
                      />
                    </div>

                    <div class="col">
                      <q-input
                        v-model="item.conditions.condition.value"
                        filled
                        :label="$t('VerificationEdit.applicabilityValue')"
                      />
                    </div>
                  </div>
                  <div v-if="item.conditions.and">
                    (и)
                    <div
                      v-for="(condition, index) in item.conditions.and"
                      :key="`condition-${index}`"
                      class="q-gutter-sm"
                    >
                      <div v-if="condition.condition" class="row q-gutter-sm">
                        <div class="col">
                          <q-input
                            v-model="condition.condition.attribute"
                            filled
                            :label="$t('VerificationEdit.attribute')"
                          />
                        </div>

                        <div class="col">
                          <q-select
                            v-model="condition.condition.equality"
                            filled
                            :label="
                              $t('VerificationEdit.applicabilityEquality')
                            "
                            :options="equalityType"
                          />
                        </div>

                        <div class="col">
                          <q-input
                            v-model="condition.condition.value"
                            filled
                            :label="$t('VerificationEdit.applicabilityValue')"
                          />
                        </div>
                      </div>
                    </div>
                  </div>
                  <div v-if="item.conditions.or">
                    (или)
                    <div
                      v-for="(condition, index) in item.conditions.or"
                      :key="`condition-${index}`"
                    >
                      <div v-if="condition.condition" class="row">
                        <div class="col">
                          <q-input
                            v-model="condition.condition.attribute"
                            filled
                            :label="$t('VerificationEdit.attribute')"
                          />
                        </div>

                        <div class="col">
                          <q-select
                            v-model="condition.condition.equality"
                            filled
                            :label="
                              $t('VerificationEdit.applicabilityEquality')
                            "
                            :options="equalityType"
                          />
                        </div>

                        <div class="col">
                          <q-input
                            v-model="condition.condition.value"
                            filled
                            :label="$t('VerificationEdit.applicabilityValue')"
                          />
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
            <div>
              <q-btn
                v-if="!addApplicability"
                color="white"
                text-color="primary"
                outline
                @click="addApplicability = true"
              >
                Добавить условие
              </q-btn>
            </div>

            <div
              v-if="addApplicability && newApplicabilityModel"
              class="q-gutter-sm"
            >
              {{ $t('VerificationEdit.addApplicabilityTitle') }}
              <div class="q-gutter-sm">
                <q-select
                  v-model="newApplicabilityModel.applicabilityType"
                  filled
                  :label="$t('VerificationEdit.applicabilityType')"
                  :options="applicabilityType"
                />

                <q-select
                  v-model="newApplicabilityModel.conditionType"
                  filled
                  :label="$t('VerificationEdit.conditionType')"
                  :options="conditionType"
                  emit-value
                  map-options
                />

                <q-input
                  v-if="
                    newApplicabilityModel.applicabilityType &&
                    newApplicabilityModel.applicabilityType === 'subjects'
                  "
                  v-model="newApplicabilityModel.subjectType"
                  filled
                  :label="$t('VerificationEdit.subjectType')"
                />
              </div>

              <div class="row q-gutter-sm">
                <div class="col">
                  <q-input
                    v-model="newApplicabilityModel.attribute"
                    filled
                    :label="$t('VerificationEdit.attribute')"
                  />
                </div>

                <div class="col">
                  <q-select
                    v-model="newApplicabilityModel.equality"
                    filled
                    :label="$t('VerificationEdit.applicabilityEquality')"
                    :options="equalityType"
                  />
                </div>

                <div class="col">
                  <q-input
                    v-model="newApplicabilityModel.value"
                    filled
                    :label="$t('VerificationEdit.applicabilityValue')"
                  />
                </div>
              </div>
              <q-btn unelevated color="primary" @click="addNewApplicability">
                Добавить
              </q-btn>
            </div>
          </div>
        </div>
      </q-card-section>
      <q-card-actions align="right">
        <q-btn
          v-if="isEditForm"
          label="Cохранить"
          unelevated
          color="primary"
          @click="edit"
        />
        <q-btn
          v-else
          label="Создать"
          unelevated
          color="primary"
          @click="create"
        />

        <q-btn
          label="Закрыть"
          color="white"
          text-color="primary"
          outline
          @click="dialogOpen = false"
        />
      </q-card-actions>
    </q-card>
  </q-dialog>
</template>
<script lang="ts">
// @ts-nocheck
// @ts-ignore
import VJsonEditor from 'v-jsoneditor';
import get from 'lodash/get';
import cloneDeep from 'lodash/cloneDeep';

export default {
  components: {
    VJsonEditor,
  },
  props: ['common', 'model'],
  data() {
    return {
      jsoneditorMode: false,

      toggleBtnOptions: [
        {
          label: this.$t('VerificationEdit.jsonEditorMode'),
          value: true,
        },
        {
          label: this.$t('VerificationEdit.formMode'),
          value: false,
        },
      ],

      dialogData: null,

      mode: 'edit',

      addApplicability: false,

      dialogOpen: false,

      defaultModel: {
        code: '',
        type: 'manual',
        name: '',
        invertLabel: '',
        applicability: {
          application: null,
          subjects: [],
        },
        basedOn: {
          type: '',
          code: '',
          title: '',
        },
        rejectCode: '',
      },

      defaultApplicabilityModel: {
        applicabilityType: '',
        conditionType: 'condition',
        subjectType: '',
        attribute: '',
        equality: '',
        value: '',
      },

      newApplicabilityModel: null,

      verificationType: [
        {
          label: 'Ручная проверка',
          value: 'manual',
        },
        {
          label: 'Автопроверка',
          value: 'auto',
        },
      ],
      conditionType: [
        {
          label: 'Базовое условие',
          value: 'condition',
        },
        {
          label: 'И',
          value: 'and',
        },
        {
          label: 'Или',
          value: 'or',
        },
        {
          label: 'Исключающая или',
          value: 'xor',
        },
      ],
      applicabilityType: ['application', 'subjects'],
      equalityType: [
        '==',
        '!=',
        '<',
        '>',
        '>=',
        '<=',
        'in',
        'not in',
        'like',
        'not like',
        'is null',
        'not null',
      ],
      basedOnTypes: ['document', 'mvz', 'application'],
    };
  },

  computed: {
    application() {
      return get(this.dialogData, 'applicability.application');
    },
    subjects() {
      return get(this.dialogData, 'applicability.subjects');
    },
    isEditForm() {
      return this.mode === 'edit';
    },
  },

  watch: {
    'common.models.verificationDialog.data': {
      immediate: true,
      handler: function (val) {
        if (val) {
          this.dialogOpen = true;
          if (val === 'createMode') {
            this.mode = 'create';
            this.dialogData = cloneDeep(this.defaultModel);
            return;
          }
          this.dialogData = val;
        }
      },
    },
  },

  mounted() {
    this.newApplicabilityModel = cloneDeep(this.defaultApplicabilityModel);
  },

  destroyed() {
    this.clearModel();
  },

  methods: {
    addNewApplicability() {
      if (
        !this.newApplicabilityModel ||
        !this.newApplicabilityModel.applicabilityType
      ) {
        this.$t('VerificationEdit.applicabilityError');
        return;
      }

      const applicability =
        (this.dialogData && this.dialogData.applicability) || {};

      const {
        applicabilityType,
        subjectType,
        conditionType,
      } = this.newApplicabilityModel;

      const isBaseConditionType = conditionType === 'condition';

      const condition = {
        condition: {
          attribute: get(this.newApplicabilityModel, 'attribute'),
          equality: get(this.newApplicabilityModel, 'equality'),
          value: get(this.newApplicabilityModel, 'value'),
        },
      };

      if (applicabilityType === 'application') {
        if (isBaseConditionType) {
          if (!applicability.application) {
            applicability.application = {};
          }

          applicability.application[conditionType] = condition.condition;
        } else {
          if (!applicability.application[conditionType]) {
            applicability.application[conditionType] = [];
          }

          applicability.application[conditionType].push(condition);
        }
      }

      if (applicabilityType === 'subjects') {
        if (!applicability.subjects) {
          applicability.subjects = [];
        }

        const isSubjectsType = applicability.subjects.some(
          (i) => i.subjectType.toString() === subjectType
        );

        if (isSubjectsType) {
          applicability.subjects.forEach((i) => {
            if (i.subjectType.toString() === subjectType && i.conditions) {
              if (isBaseConditionType) {
                i.conditions[conditionType] = condition.condition;
              } else {
                if (!i.conditions[conditionType]) {
                  i.conditions[conditionType] = [];
                }

                i.conditions[conditionType].push(condition);
              }
            }
          });
        } else {
          const newSubject = {
            subjectType: subjectType,
            conditions: {},
          };

          if (isBaseConditionType) {
            newSubject.conditions[conditionType] = condition.condition;
          } else {
            newSubject.conditions[conditionType] = [];
            newSubject.conditions[conditionType].push(condition);
          }

          applicability.subjects.push(newSubject);
        }
      }

      this.dialogData.applicability = applicability;
      this.newApplicabilityModel = cloneDeep(this.defaultApplicabilityModel);
      this.addApplicability = false;
      this.$nextTick(() => this.$forceUpdate());
    },

    edit() {
      const card = this.$store.getters['registryService/services/servicesCard'];
      const result = card.verifications.map((it) =>
        it.code === this.dialogData.code ? this.dialogData : it
      );
      card.verifications = result;

      this.$store.dispatch('registryService/services/setCardForJson', card);
      this.dialogOpen = false;
    },
    async create() {
      if (!this.dialogData) return;
      const card = cloneDeep(
        this.$store.getters['registryService/services/servicesCard']
      );
      const verifications = card.verifications || [];
      verifications.push(this.dialogData);
      card.verifications = verifications;
      this.$store.dispatch('registryService/services/setCardForJson', card);
      this.dialogOpen = false;
    },

    clearModel() {
      this.jsoneditorMode = false;
      this.$emit('commonModels', {
        verificationDialog: {
          data: null,
        },
      });
    },
  },
};
</script>
