<i18n>
{
  "en": {
    "RequestCard": {
      "familyName": "Family name",
      "firstName": "First Name",
      "patronymic": "Patronymic",
      "birthDate": "Birth date",
      "sex": "Sex",
      "placeOfBirth": "Place of birth",
      "series": "Series",
      "documentNumber": "Number",
      "dateOfIssue": "Date of issue",
      "issuerAuthority": "Issued by",
      "tab": "Request parameters",
      "requestXML": "Request.xml",
      "downloadXML": "Download xml",
      "noChecksResult": "No results for the request data",
      "noFile": "File not found"
    }
  },
  "ru": {
    "RequestCard": {
      "familyName": "Фамилия",
      "firstName": "Имя",
      "patronymic": "Отчество",
      "birthDate": "Дата рождения",
      "sex": "Пол",
      "placeOfBirth": "Место рождения",
      "series": "Серия",
      "documentNumber": "Номер",
      "dateOfIssue": "Дата выдачи",
      "issuerAuthority": "Кем выдан",
      "tab": "Данные запроса",
      "requestXML": "Запрос.xml",
      "downloadXML": "Скачать xml",
      "noChecksResult": "Нет результатов по данным запроса",
      "noFile": "Файл не найден"
    }
  }
}
</i18n>

<template>
  <div v-if="common.active === 'request' && !loading" class="q-pb-md">
    <q-card class="no-shadow q-gutter-y-md q-mx-md no-border-radius">
      <div
        class="q-gutter-y-md bg-white q-px-lg q-pb-md q-pt-sm q-mt-md q-mx-md rounded-borders"
      >
        <FormGeneratorWrapper
          v-if="!loading"
          :model="formRequest"
          :schema="reqSchema"
          :hide-nulls="true"
        />
        <div v-if="!formRequest && !loading" class="full-width text-center">
          {{ $t('RequestCard.noChecksResult') }}
        </div>
        <div class="q-mt-lg">
          <a
            target="_blank"
            :download="$t('RequestCard.requestXML')"
            @click="downloadXml"
          >
            <q-btn
              dense
              :disable="!Boolean(get(model, 'originalMessageId'))"
              :style="{
                background: '#d9e2eb',
                padding: '8px 6px',
                color: '#222',
                fontSize: '12px',
                fontWeight: '400',
                lineHeight: '16px',
              }"
              class="cursor-pointer"
            >
              {{ $t('RequestCard.downloadXML') }}
            </q-btn>
          </a>
        </div>
      </div>
    </q-card>
  </div>
</template>

<script lang="ts">
import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
import FormGeneratorWrapper from '@components/common/node-generator/FormGeneratorWrapper.vue';
import {
  createDictionaryMapFromSchema,
  swapModelValueWithDict,
} from '@utils/dict-map-utils';
import { convertDateFromBackendFormat } from '@utils/format-date';
import { InteragencyApi } from '@openapi/registry-service';
import get from 'lodash/get';
import head from 'lodash/head';
import { DocumentApi } from '@openapi/document-registry';
import { BaseCardCommon } from '@interfaces/components';
import { InteragencyRequest } from '@interfaces/entities/InteragencyRequest';
import { Schema } from '@devsun/eva-models';
import { notifyError } from '@utils/notify';

const interagencyApi = new InteragencyApi();
const documentApi = new DocumentApi();

@Component({
  components: {
    FormGeneratorWrapper,
  },
  methods: {
    get,
  },
})
export default class InterRequestTabRequest extends Vue {
  @Prop({}) private common?: BaseCardCommon;
  @Prop({}) private model?: InteragencyRequest;

  private reqSchema: Schema.MetaClassSchemaRaw | undefined = undefined;

  private baseRequestObject: InteragencyRequest | any = {};

  private formRequest: any = null;

  private statement: any | null = null;

  private loading = true;

  private dictionaryMap: any = {};

  private get statementId(): string {
    const statement = this.$route.query.statement;
    return statement ? String(statement).trim() : '';
  }

  @Watch('model', {
    immediate: true,
  })
  modelWatcher(val: InteragencyRequest): void {
    if (val?.request && val?.requestData === undefined) {
      this.getFormSchema(val.class).then(async (schema) => {
        if (schema) {
          await this.initDictionaries(schema);
          return this.initRequestDataDefault(val);
        }
      });
    }
  }

  @Watch('formRequest')
  async formRequestWatcher(val: any): Promise<void> {
    if (!val || !this.model) {
      return;
    }
    this.setTotalModel(
      {
        requestData: await this.setValuesFromDictionaries(val),
      },
      this.model
    );
  }

  downloadXml(): Promise<void> {
    return new Promise((resolve, reject) => {
      this.$store
        .dispatch('mz/history/getCurrentXml', {
          type: 'requestFsmev',
          id: this.model?.originalMessageId,
        })
        .then((data) => {
          resolve(data);
        })
        .catch(() => {
          this.$store
            .dispatch('mz/history/getCurrentXml', {
              type: 'requestSmev',
              id: this.model?.originalMessageId,
            })
            .then((data) => {
              resolve(data);
            })
            .catch((e) => {
              notifyError(this.$t('RequestCard.noFile').toString());
              reject(e);
            });
        });
    });
  }

  async initDictionaries(
    schema: Schema.MetaClassSchemaRaw
  ): Promise<Array<any> | undefined> {
    const schemaMap = schema.dictionaries ?? {};
    this.dictionaryMap = {
      ...schemaMap,
      ...createDictionaryMapFromSchema(schema),
    };
    const dicts = new Set(Object.values(this.dictionaryMap));

    if (Object.keys(this.dictionaryMap).length) {
      return this.$store.dispatch(
        'registryService/referenceBooks/initReferenceBooks',
        [...dicts].map((id: any) => {
          return { id };
        })
      );
    }
  }

  async setValuesFromDictionaries(data: any) {
    let result = { ...data };
    console.log('[Request][setValuesFromDictionaries] MAP', this.dictionaryMap);
    for (const path in this.dictionaryMap) {
      const dictCode = this.dictionaryMap[path];
      const dict = await this.$store.dispatch(
        'registryService/referenceBooks/fetchReferenceBook',
        { id: dictCode }
      );
      result = swapModelValueWithDict(path, result, dict);
    }

    return result;
  }

  setBaseRequestObject(): void {
    this.baseRequestObject['requestData.regNumber'] = get(
      this.statement,
      'common.regNumber'
    );
    this.baseRequestObject[
      'requestData.receiveDate'
    ] = convertDateFromBackendFormat(get(this.model, 'receiveDate', ''));
    this.baseRequestObject[
      'requestData.sendDate'
    ] = convertDateFromBackendFormat(get(this.model, 'sendDate', ''));
  }

  setTotalModel(customObject: unknown, model: InteragencyRequest): void {
    const totalModel = Object.assign(customObject, model);
    this.$store.commit('utils/cards/addModel', {
      model: totalModel,
      path: this.common?.path,
    });
  }

  initRequestDataDefault(data: InteragencyRequest): void {
    if (data?.request) {
      this.formRequest = {
        requestData: data.request,
      };
    }
    this.loading = false;
  }

  async getFormSchemaFromRegistry(serviceId: string): Promise<
    Schema.MetaClassSchemaRaw | undefined
  > {
    const FORM_KEY = 'formRequest';
    const mzClassName = get(this.model, 'class');

    try {
      const { data: interagencies } = await interagencyApi.pagingInteragency(
        undefined,
        undefined,
        `class==${mzClassName}`,
        undefined,
        undefined,
        FORM_KEY
      );
      const interagency = head(interagencies.records);
      const form = get(interagency, FORM_KEY);
      if (Array.isArray(form)) {
        const neededForm = form.find(f => f.parentServiceId === serviceId);
        if (neededForm) {
          return neededForm;
        }
        return form[0];
      }
      return form;
    } catch (err) {
      console.error(
        `[inter requests][get form schema from registry] ${mzClassName}`
      );
    }
  }

  async getFormSchema(
    className: string
  ): Promise<Schema.MetaClassSchemaRaw | undefined> {
    try {
      const { data: statement } = await documentApi.getDocument(
        'Applications',
         this.statementId
      );
      const serviceID = get(statement, 'system.serviceId') || get(this.model, 'statement.system.serviceId');;
      let schema = await this.getFormSchemaFromRegistry(serviceID);
      const schemaCode =
        'InterRequests_' +
        'CardsInterRequestTabRequest' +
        String(className).toUpperCase();

      if (!schema) {
        console.warn('--------------------------');
        console.warn('--------------------------');
        console.warn(
          '[MZ Request tab] No form (view schema) found in service registry for mz:',
          get(this.model, 'requestName'),
          get(this.model, 'class')
        );
        serviceID &&
          console.warn(
            'You can add a form at this address:',
            `${location.origin}/microws/cards/services/${serviceID}?active=forms&components=index,processes,forms,directories,verifications,documents,interagencies,stages,form_model,digital_regulations`
          );
        console.warn('--------------------------');
        console.warn('--------------------------');

        schema = await this.$store.dispatch(
          'utils/components/fetchModelByCode',
          schemaCode
        );
      }

      this.reqSchema = schema;

      return schema;
    } catch (err) {
      console.error(err);
      notifyError(this.$t('StatementCard.errorLoadingModel').toString());
    }
  }
}
</script>
