<i18n>
{
  "en": {
    "StageEdit": {
      "title": "Edit dictionary",
      "createTitle": "Create dictionary",
      "name": "Name",
      "code": "Code",
      "value": "Value",
      "documentsTitle": "Documents",
      "executionPeriodInDays": "Execution period in days",
      "notifyInHours": "Notify in hours",
      "jsonEditorMode": "Json editor mode",
      "formMode": "Form mode",
      "manualInput": "Dial the name manually",
      "selectFromList": "Select from the list",
      "InputEmptyError": "Fill in all the fields",
      "notifyUom": "UOM",
      "number": "number",
      "statusTrigger": "Status trigger",
      "statusScope": "Status scope",
      "documentApply": "Apply",
      "documentReject": "Reject",
      "documentResult": "Result documents",
      "documentsEmpty": "No documents",
      "intermediateStatus": "An intermediate stage upon application is mandatory for this service",
      "additionalInformation": "Request for additional information is mandatory for this service",
      "pauseIsMandatory": "A pause is mandatory for this service",
      "formNoName": "Form without name"
    }
  },
  "ru": {
    "StageEdit": {
      "title": "Редактирование данных этапа",
      "createTitle": "Создание этапа",
      "name": "Имя",
      "code": "Код",
      "value": "Значение",
      "documentsTitle": "Записи",
      "executionPeriodInDays": "Период предоставления (рабочие дни)",
      "notifyInHours": "Время уведомления",
      "jsonEditorMode": "Режим редактора json",
      "formMode": "Режим формы",
      "manualInput": "Набрать имя вручную",
      "selectFromList": "Выбрать имя из списка",
      "InputEmptyError": "Заполните все поля",
      "notifyUom": "Единицы измерения",
      "number": "Номер",
      "statusTrigger": "Триггер",
      "statusScope": "Возможные статусы",
      "documentApply": "Положительный",
      "documentReject": "Отрицательный",
      "documentResult": "Результирующие документы",
      "documentsEmpty": "Нет документов",
      "intermediateStatus": "Промежуточный этап по заявлению обязателен для данной услуги",
      "additionalInformation": "Запрос дополнительной информации обязателен для данной услуги",
      "pauseIsMandatory": "Приостановка обязательна",
      "formNoName": "Имя формы не указано"
    }
  }
}
</i18n>

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

          <q-input
            v-model="dialogData.name"
            v-if="manualInput"
            filled
            :label="$t('StageEdit.name')"
          />

          <q-select
            filled
            v-else
            v-model="dialogData.name"
            :options="stagesList"
            :label="$t('StageEdit.name')"
          />
          <div class="row justify-end">
            <q-btn
              flat
              @click="manualInputToggle"
              size="sm"
              no-caps
              color="primary"
              :label="
                manualInput
                  ? $t('StageEdit.selectFromList')
                  : $t('StageEdit.manualInput')
              "
            />
          </div>
          <q-input
            v-model.number="dialogData.executionPeriodInDays"
            type="number"
            filled
            :label="$t('StageEdit.executionPeriodInDays')"
          />
          <div class="row q-gutter-sm">
            <div class="col">
              <q-input
                v-model.number="currentNotify"
                :label="$t('StageEdit.notifyInHours')"
                type="number"
                filled
              />
            </div>
            <div class="col">
              <q-select
                filled
                v-model="notifyUOM"
                :options="notifyUomList"
                :label="$t('StageEdit.notifyUom')"
                emit-value
                map-options
              />
            </div>
          </div>
          <q-select
            filled
            v-model="dialogData.statusScope"
            :options="statusList"
            :label="$t('StageEdit.statusScope')"
            emit-value
            map-options
            multiple
            use-chips
            stack-label
          />
          <q-checkbox
            v-if="isStatus7ObligatoryVisible"
            v-model="dialogData.status7Obligatory"
            :label="$t('StageEdit.intermediateStatus')"
          />
          <q-checkbox
            v-if="isStatus14ObligatoryVisible"
            v-model="dialogData.status14Obligatory"
            :label="$t('StageEdit.additionalInformation')"
          />
          <q-checkbox
            v-if="isPauseObligatoryVisible"
            v-model="dialogData.pauseIsMandatory"
            :label="$t('StageEdit.pauseIsMandatory')"
          />
          <q-select
            filled
            emit-value
            map-options
            :options="statusList"
            v-model="dialogData.statusTrigger"
            :label="$t('StageEdit.statusTrigger')"
            stack-label
          />

          <div class="text-h6">{{ $t('StageEdit.documentResult') }}</div>

          <template v-if="resultDocuments.length > 0">
            <div v-for="(doc, key) in attachedDocuments" :key="doc.code + key">
              <div class="row flex items-center q-mb-lg">
                <div class="col-7">
                  <q-select
                    v-model="doc.code"
                    filled
                    :rules="[noEmptyValueRule]"
                    :options="resultDocuments"
                    label="Документ"
                    class="q-mr-md q-pb-none"
                    @input="doc.form = null"
                  />
                </div>
                <div class="col-4">
                  <q-select
                    v-model="doc.status"
                    filled
                    :options="statusDocs"
                    label="Статус"
                    emit-value
                    map-options
                    class="q-mr-md"
                  />
                </div>
                <div class="col-1">
                  <q-btn icon="delete" flat @click="deleteDocument(doc.code)" />
                </div>
              </div>
              <div class="row flex items-center q-mb-xl">
                <div class="col-7">
                  <q-select
                    filled
                    :rules="[noEmptyValueRule]"
                    :disable="doc.code === null"
                    v-model="doc.form"
                    :options="documentForms[doc.code]"
                    emit-value
                    map-options
                    label="Форма документа"
                    class="q-mr-md q-pb-none"
                  />
                </div>
                <div class="col-5">
                  <q-select
                    filled
                    v-model="doc.goal"
                    :options="goalsList"
                    label="Цель"
                    multiple
                    use-chips
                  />
                </div>
              </div>
            </div>
            <q-btn
              @click="addDocument"
              unelevated
              color="primary"
              label="Добавить документ"
              class="q-mr-md"
            />
          </template>
          <template v-else>
            <div>{{ $t('StageEdit.documentsEmpty') }}</div>
          </template>
        </div>
      </q-card-section>
      <q-card-actions align="right">
        <q-btn
          @click="edit"
          label="Cохранить"
          unelevated
          v-if="isEditForm"
          color="primary"
        />
        <q-btn
          @click="create"
          label="Создать"
          unelevated
          v-else
          color="primary"
        />

        <q-btn
          @click="dialogOpen = false"
          label="Закрыть"
          color="white"
          text-color="primary"
          outline
        />
      </q-card-actions>
    </q-card>
  </q-dialog>
</template>
<script lang="ts">
// @ts-nocheck
// @ts-ignore
import VJsonEditor from 'v-jsoneditor';
import { noEmptyValueRule } from '@utils/field-validation/basic';
import set from 'lodash/set';
import cloneDeep from 'lodash/cloneDeep';
import isEmpty from 'lodash/isEmpty';
import map from 'lodash/map';
import { notifyError } from '@utils/notify';

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

      currentNotify: '',

      notifyUOM: 'notifyInHours',

      manualInput: false,

      oldNum: void 0,

      mode: 'edit',

      curentStage: {
        value: '',
        label: '',
      },

      stagesList: [
        'Регистрация заявления срок',
        'Получение сведений',
        'Рассмотрение документов и принятие решения',
        'Запрос дополнительной информации',
        'Формирование начисления',
      ],

      notifyUomList: [
        {
          value: 'notifyInHours',
          label: 'Часы',
        },
        {
          value: 'notifyInMinutes',
          label: 'Минуты',
        },
      ],

      dialogOpen: false,

      jsoneditorMode: false,

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

      statusDocs: [
        {
          label: this.$t('StageEdit.documentApply'),
          value: 'apply',
        },
        {
          label: this.$t('StageEdit.documentReject'),
          value: 'reject',
        },
      ],

      attachedDocuments: [],
      resultDocuments: [],
      documentForms: {},
    };
  },

  methods: {
    edit() {
      if (
        !this.dialogData ||
        !this.dialogData?.name ||
        !this.dialogData?.number ||
        this.documentsEmptyField()
      ) {
        notifyError(this.$t('StageEdit.InputEmptyError'));
        return;
      }
      this.getNotifyInput();
      const card = cloneDeep(
        this.$store.getters['registryService/services/servicesCard']
      );
      card.stages = card.stages.map((i) =>
        i.uuid === this.dialogData.uuid ? this.dialogData : i
      );
      const isStatus7Obligatory = card.stages.find(
        (stage) => stage.status7Obligatory
      );
      const isStatus14Obligatory = card.stages.find(
        (stage) => stage.status14Obligatory
      );
      const isPauseMandatory = card.stages.find(
        (stage) => stage.pauseIsMandatory
      );
      card.status7Obligatory = !!isStatus7Obligatory;
      card.status14Obligatory = !!isStatus14Obligatory;
      card.pauseIsMandatory = !!isPauseMandatory;
      this.$store.dispatch('registryService/services/setCardForJson', card);
      this.dialogOpen = false;
    },
    documentsEmptyField() {
      let isEmpty = false;

      if (this.dialogData.documents) {
        Object.values(this.dialogData.documents).forEach((docs) => {
          docs.forEach((doc) => {
            if (!doc.form || !doc.code) {
              isEmpty = true;
            }
          });
        });
      }

      return isEmpty;
    },

    async create() {
      if (
        !this.dialogData ||
        !this.dialogData?.name ||
        !this.dialogData?.number
      ) {
        notifyError(this.$t('StageEdit.InputEmptyError'));
        return;
      }
      this.getNotifyInput();
      const card = cloneDeep(
        this.$store.getters['registryService/services/servicesCard']
      );
      const stages = card.stages || [];
      stages.push(this.dialogData);
      card.stages = stages;
      const isStatus7Obligatory = card.stages.find(
        (stage) => stage.status7Obligatory === true
      );
      const isStatus14Obligatory = card.stages.find(
        (stage) => stage.status14Obligatory === true
      );
      const isPauseMandatory = card.stages.find(
        (stage) => stage.pauseIsMandatory === true
      );
      card.status7Obligatory = !!isStatus7Obligatory;
      card.status14Obligatory = !!isStatus14Obligatory;
      card.pauseIsMandatory = !!isPauseMandatory;
      this.$store.dispatch('registryService/services/setCardForJson', card);
      this.dialogOpen = false;
    },

    clearModel() {
      this.$emit('commonModels', {
        StageDialog: {
          data: null,
        },
      });
      this.jsoneditorMode = false;
    },
    manualInputToggle() {
      this.manualInput = !this.manualInput;
      set(this.dialogData, 'name', '');
    },

    getNotifyInput() {
      if (!this.currentNotify) {
        return;
      }
      this.dialogData[this.notifyUOM] = this.currentNotify;
    },
    deleteDocument(code) {
      // todo test fn
      this.attachedDocuments = this.attachedDocuments.filter(
        (doc) => doc.code !== code
      );
    },
    addDocument() {
      this.attachedDocuments.push({
        code: null,
        form: null,
        status: 'apply',
        goal: null,
      });
    },
    initAttachedDocument() {
      this.attachedDocuments = [];
      if (this.dialogData?.documents) {
        Object.keys(this.dialogData.documents).forEach((status) => {
          this.dialogData.documents[status].forEach((doc) => {
            this.attachedDocuments.push({
              status,
              form: doc?.form,
              code: typeof doc === 'string' ? doc : doc.code,
              goal: typeof doc === 'string' ? null : doc.goal,
            });
          });
        });
      }
    },
    getResultDocuments() {
      if (this.card.documents) {
        this.card.documents
          .filter((doc) => doc.source === 'result')
          .forEach((doc) => {
            this.resultDocuments.push(doc.code);
            if (doc.form) {
              this.documentForms[doc.code] = doc.form.map((form) => {
                return {
                  value: form.name ?? null,
                  label: form.name ?? this.$t('StageEdit.formNoName'),
                  disable: !form.name,
                };
              });
            } else {
              this.documentForms[doc.code] = [
                {
                  value: null,
                  label: this.$t('StageEdit.formNoName'),
                  disable: true,
                },
              ];
            }
          });
      }
    },
    noEmptyValueRule,
  },
  async created() {
    await this.$store.dispatch(
      'registryService/referenceBooks/initReferenceBooks',
      [
        {
          force: true,
          id: 'gpzu_2_application_status',
        },
      ]
    );

    this.getResultDocuments();
  },
  destroyed() {
    this.clearModel();
  },
  watch: {
    'common.models.StageDialog.data': {
      immediate: true,
      handler(val) {
        if (val) {
          this.dialogOpen = true;
          if (val === 'createMode') {
            this.mode = 'create';
            this.dialogData = {};
            return;
          }
          this.dialogData = val;
          if (val.notifyInMinutes) {
            this.notifyUOM = 'notifyInMinutes';
            this.currentNotify = val.notifyInMinutes;
            delete this.dialogData.notifyInMinutes;
          }
          if (val.notifyInHours) {
            this.notifyUOM = 'notifyInHours';
            this.currentNotify = val.notifyInHours;
            delete this.dialogData.notifyInHours;
          }
          this.mode = 'edit';
        }
      },
    },
    attachedDocuments: {
      deep: true,
      handler(arrDocuments) {
        const documents = {};

        arrDocuments.forEach((doc) => {
          if (documents[doc.status] === undefined) {
            documents[doc.status] = [];
          }

          const data = {
            code: doc.code,
          };

          if (doc.form) {
            data.form = doc.form;
          }

          if (Array.isArray(doc.goal) && !isEmpty(doc.goal)) {
            data.goal = doc.goal.map((element) => parseInt(element));
          }

          documents[doc.status].push(data);
        });

        if (!isEmpty(documents)) {
          this.dialogData.documents = documents;
        } else {
          delete this.dialogData.documents;
        }
      },
    },
  },
  computed: {
    kcrImport() {
      return this.$store.getters['registryService/services/servicesCard']
        .kcrImport;
    },
    isEditForm() {
      return this.mode === 'edit';
    },
    isStatus7ObligatoryVisible() {
      return this.dialogData?.statusScope?.includes('17.1');
    },
    isStatus14ObligatoryVisible() {
      return (
        this.dialogData?.statusScope?.includes('14.1') ||
        this.dialogData?.statusScope?.includes('14.2')
      );
    },
    isPauseObligatoryVisible() {
       return this.dialogData?.statusScope?.includes('14.1');
    },
    goalsList() {
      const card = cloneDeep(
        this.$store.getters['registryService/services/servicesCard']
      );
      return (card.goalsList || []).map((i) => i.value);
    },
    statusList() {
      return map(
        this.$store.getters['registryService/referenceBooks/referenceBooks']
          .gpzu_2_application_status || {},
        (label, value) => ({ value, label: `${label.description} (${value})` })
      ).sort((a, b) => a.value - b.value);
    },

    card() {
      return this.$store.getters['registryService/services/servicesCard'];
    },
  },
};
</script>
