<template>
  <div>
    <q-card class="flex no-shadow q-py-md q-mx-md q-mb-lg q-mt-md">
      <div class="flex q-px-md">
        <q-btn
          padding="xs"
          class="text-grey-7 q-mr-md"
          color="grey-3"
          icon="arrow_back"
          @click="goBack"
        />
        <h1 class="text-h5 q-ma-none">
          {{ $t('registries.objectCard.title') }} {{ objModel.orderId }}
        </h1>
      </div>
      <div v-show="!loading && !revisionNumber" class="q-px-md q-ml-auto">
        <q-btn
          v-show="!isEqual"
          class="q-ml-sm"
          outline
          :label="$t('registries.objectCard.cancel')"
          color="negative"
          @click="cancelChangesConfirm"
        />
        <q-btn
          v-show="!isEqual"
          class="q-ml-sm"
          outline
          :label="$t('registries.objectCard.save')"
          color="positive"
          @click="updateConfirm"
        />
        <q-btn
          v-if="$AC.haveScope(USER_SCOPES.CLOUD_ADMIN)"
          class="q-ml-sm"
          :label="$t('registries.objectCard.delete')"
          color="primary"
          @click="deleteConfirm"
        />
        <q-btn
          v-if="haveXmlReportLink"
          class="q-ml-sm"
          :label="$t('registries.objectCard.downloadXml')"
          color="primary"
          @click="
            fetchDocumentAttachment(
              model,
              'download',
              'orderId',
              'xmlReportLink'
            )
          "
        />
      </div>
      <div
        v-if="!loading && revisionNumber"
        class="q-px-md q-ml-auto q-gutter-y-md"
      >
        <q-btn
          class="q-ml-sm"
          :label="$t('registries.objectCard.recoverRevision')"
          color="primary"
          @click="recoverRevision"
        />
        <q-btn
          class="q-ml-sm"
          :label="$t('registries.objectCard.toCurrentRevision')"
          color="primary"
          @click="goToCurrentRevision"
        />
      </div>
    </q-card>
    <q-card class="no-shadow q-py-md q-mx-md q-mb-lg q-mt-md">
      <q-inner-loading :showing="loading">
        <q-spinner-gears color="primary" size="50px" />
      </q-inner-loading>
      <div v-show="!loading" class="q-gutter-y-md q-mx-md q-mt-md">
        <!--        <base-label-value padded-label>-->
        <!--          <template #label>-->
        <!--            {{ $t('registries.objectCard.service') }}-->
        <!--          </template>-->
        <!--          <template #value>-->
        <!--            {{ objModel.serviceFullName }}-->
        <!--          </template>-->
        <!--        </base-label-value>-->
        <!--        <base-label-value padded-label v-if="objModel.Goal">-->
        <!--          <template v-slot:label>-->
        <!--            {{ $t('registries.objectCard.requestGoal') }}-->
        <!--          </template>-->
        <!--          <template v-slot:value>-->
        <!--            <reference-book-item-->
        <!--              dictionary="gpzu_5_goal_request"-->
        <!--              :value="get(objModel, 'Goal')"-->
        <!--            />-->
        <!--          </template>-->
        <!--        </base-label-value>-->
        <base-label-value
          v-if="!isAccreditation && has(objModel, 'status.internal')"
          value-type="QBadge"
          padded-label
        >
          <template #label>
            {{ $t('registries.objectCard.status.internal') }}
          </template>
          <template #value>
            <q-badge class="q-pa-sm" text-color="white" color="primary">
              <reference-book-item
                dictionary="gpzu_2_application_status"
                name="description"
                :value="get(objModel, 'status.internal')"
              />
            </q-badge>
          </template>
        </base-label-value>
        <base-label-value
          v-if="isAccreditation && has(objModel, 'entityStatus')"
          value-type="QBadge"
          padded-label
        >
          <template #label>
            {{ $t('registries.objectCard.status.internal') }}
          </template>
          <template #value>
            <q-badge class="q-pa-sm" text-color="white" color="primary">
              <reference-book-item
                dictionary="accreditation_it_1_0_1__application_status"
                name="description"
                :value="get(objModel, 'entityStatus')"
              />
            </q-badge>
          </template>
        </base-label-value>
        <base-label-value v-if="objModel.departmentFullName" padded-label>
          <template #label>
            {{ $t('registries.department') }}
          </template>
          <template #value>
            {{ objModel.departmentFullName }}
          </template>
        </base-label-value>
        <base-label-value
          v-if="objModel.document && objModel.orderId"
          padded-label
        >
          <template #label>
            {{ $t('registries.objectCard.statement') }}
          </template>
          <template #value>
            <q-chip clickable class="q-ma-none" @click="goToStatement">
              {{ objModel.orderId }}
            </q-chip>
          </template>
        </base-label-value>
        <base-label-value padded-label v-if="get(objModel, 'document.resDate')">
          <template #label>
            {{ $t('registries.objectCard.dateFinish') }}
          </template>
          <template #value>
            {{
              convertDateFormat(
                get(objModel, 'document.resDate'),
                DateFormat.invertedDate,
                DateFormat.date
              )
            }}
          </template>
        </base-label-value>
        <base-label-value v-if="objModel.document" padded-label>
          <template #label>
            {{ $t('registries.objectCard.decisionNumber') }}
          </template>
          <template #value>
            {{ objModel.document.resNumber }}
          </template>
        </base-label-value>
        <base-label-value v-if="objModel.applicationSystem" padded-label>
          <template #label>
            {{ $t('registries.objectCard.startDate') }}
          </template>
          <template #value>
            {{
              convertDateFormat(
                objModel.applicationSystem.startDate,
                DateFormat.invertedDate,
                DateFormat.date
              )
            }}
          </template>
        </base-label-value>
        <base-label-value v-if="isCashback" padded-label>
          <template #label>
            {{ $t('registries.objectCard.paymentStatus') }}
          </template>
          <template #value>
            {{ paymentStatus }}
          </template>
        </base-label-value>

        <base-label-value
          v-if="isCashback && objModel.codeErrorPayment"
          padded-label
        >
          <template #label>
            {{ $t('registries.objectCard.codeErrorPayment') }}
          </template>
          <template #value>
            {{ objModel.codeErrorPayment }}
          </template>
        </base-label-value>
        <base-label-value
          v-if="isCashback && objModel.descriptionErrorPayment"
          padded-label
        >
          <template #label>
            {{ $t('registries.objectCard.descriptionErrorPayment') }}
          </template>
          <template #value>
            {{ objModel.descriptionErrorPayment }}
          </template>
        </base-label-value>
        <base-label-value v-if="objModel.finishSignDate" padded-label>
          <template #label>
            {{ $t('registries.objectCard.finishSignDate') }}
          </template>
          <template #value>
            {{
              convertDateFromBackendFormat(
                objModel.finishSignDate,
                DateFormat.date
              )
            }}
          </template>
        </base-label-value>
        <base-label-value v-if="objModel.signer" padded-label>
          <template #label>
            {{ $t('registries.objectCard.signerFullName') }}
          </template>
          <template #value>
            {{ objModel.signer.fullName }}
          </template>
        </base-label-value>
      </div>
    </q-card>
    <base-tabs :current-tab="tabs.current" :tabs="tabs.list" />
  </div>
</template>

<script lang="ts">
import { Component, Prop, Watch } from 'vue-property-decorator';
import { mixins } from 'vue-class-component';
import ReturnToParentView from '@/mixins/ReturnToParentView';
import { Dictionary, RawLocation } from 'vue-router/types/router';
import {
  convertDateFormat,
  convertDateFromBackendFormat,
} from '@utils/format-date';
import { DateFormat } from '@constants/utils/format-date';
import { DocumentApi, VersioningApi } from '@openapi/registry-data';
import { CardNeedToUpdateType } from '@constants/models/Card';
import { BaseCardCommon } from '@/interfaces';
import { USER_SCOPES } from '@constants/entities/Scope';
import { RegistryApi } from '@openapi/registry-service';
import { fetchDocumentAttachment } from '@utils/fetch-document-attachment';
import { notifyError, notifySuccess } from '@utils/notify';
import get from 'lodash/get';
import has from 'lodash/has';
import isEqual from 'lodash/isEqual';

const registryApi = new RegistryApi();

const ACCREDITATION_CODE = 'RegistryAccreditation';
const CHILDRENS_REST_CASHBACK_CODE = 'RegistryKompensDetskOtdMIR';
const REFUGEE_REGISTRY_CODE = 'registryRefugeeRegistry';

@Component({
  methods: {
    convertDateFormat,
    convertDateFromBackendFormat,
    fetchDocumentAttachment,
    has,
    get,
  },
})
export default class RegistryObject extends mixins(ReturnToParentView) {
  @Prop() model: any;
  @Prop() common!: BaseCardCommon;

  USER_SCOPES = USER_SCOPES;

  DateFormat = DateFormat;
  title = '';
  loading = true;
  id = this.common.id;
  registryCode = this.$route.query.reg as string;
  registryId = this.$route.query.regid as string;
  objModel: any = {}; // todo type RegistryRecord
  schema = {};

  @Watch('common.active')
  activeHandler(val: string) {
    this.tabs.current = val;
  }

  @Watch('revisionNumber')
  async revisionNumberHandler(num: string, prev: string) {
    if (num !== prev) {
      this.fetchData();
      this.$store.commit(
        'utils/cards/needToUpdate',
        CardNeedToUpdateType.MODEL
      );
    }
  }

  @Watch('paymentStatusSaved')
  onPaymentStatusSaved(value: boolean) {
    if (value === true) {
      this.objModel = this.model;
      this.$store.commit(`utils/cards/addModel`, {
        model: false,
        path: 'registryRefugeeRegistry.paymentStatusSaved',
      });
    }
  }

  created() {
    this.init();
  }

  get statementLink() {
    return {
      name: 'cards',
      params: {
        id: this.objModel.applicationId,
        path: 'statements',
      },
      query: {
        active: 'author',
        components: this.$store.getters['cardComponents/statements/components'],
      },
    };
  }

  get revisionNumber() {
    return this.$route.query.num;
  }

  get haveXmlReportLink() {
    return this.model?.xmlReportLink;
  }

  get isEqual() {
    return isEqual(this.objModel, this.model);
  }

  get registry() {
    const models: any = this.$store.getters[`utils/cards/models`] || {};
    return models[this.registryCode];
  }

  get haveLinkedRegistries() {
    const list = this.registry?.linkedRegistries || [];
    return list.length > 0;
  }

  get paymentStatusSaved() {
    return this.registry?.code === REFUGEE_REGISTRY_CODE
      ? this.$store.getters[`utils/cards/models`].registryRefugeeRegistry
          ?.paymentStatusSaved
      : null;
  }

  get tabs() {
    return {
      current: this.common?.active,
      list: [
        {
          name: this.$t('registries.objectCard.dataTitle'),
          path: 'data',
          visible: true,
        },
        {
          name: this.$t('registries.objectCard.documentsTitle'),
          path: 'documents',
          visible: true,
        },
        {
          name: this.$t('registries.objectCard.connectionsTitle'),
          path: 'connections',
          visible: this.haveLinkedRegistries,
        },
        // FIXME: Костыль для быстрого скрытия вкладки документы
        // {
        //   name: this.$t('registries.objectCard.versionsTitle'),
        //   path: 'versions',
        //   visible: this.revisionNumber === undefined,
        // },
      ],
    };
  }

  get isAccreditation() {
    return this.registryCode === ACCREDITATION_CODE;
  }

  get isCashback() {
    return this.registryCode === CHILDRENS_REST_CASHBACK_CODE;
  }

  get paymentStatus(): string {
    return (
      this.objModel?.export?.status ??
      this.$t('registries.objectCard.noPaymentStatus')
    );
  }

  init() {
    this.fetchData();
    this.fetchRegistryData();
  }

  updateConfirm() {
    this.$q
      .dialog({
        title: this.$t('registries.objectCard.save') as string,
        message: this.$t('registries.objectCard.saveInfo') as string,
        cancel: true,
      })
      .onOk(() => {
        this.updateObject();
      });
  }

  async updateObject() {
    const documentApi = new DocumentApi();
    return documentApi
      .updateDocument(this.registryCode, [this.model])
      .then(({ data }: any) => {
        if (data.success) {
          this.objModel = this.model;
          this.$store.commit(`utils/cards/addModel`, {
            model: this.model,
            path: 'registry-object',
          });
          this.$store.commit(
            'utils/cards/needToUpdate',
            CardNeedToUpdateType.VERSION
          );
        }
      });
  }

  cancelChangesConfirm() {
    this.$q
      .dialog({
        title: this.$t('registries.objectCard.cancel') as string,
        message: this.$t('registries.objectCard.cancelInfo') as string,
        cancel: true,
      })
      .onOk(() => {
        this.cancelChanges();
      });
  }

  cancelChanges() {
    this.fetchData();
  }

  deleteConfirm() {
    this.$q
      .dialog({
        title: this.$t('registries.objectCard.delete') as string,
        message: this.$t('registries.objectCard.deleteInfo') as string,
        cancel: true,
      })
      .onOk(() => {
        this.deleteRegistry().then(() => {
          this.goBack();
        });
      });
  }

  async deleteRegistry() {
    const documentApi = new DocumentApi();
    return documentApi.deleteDocument(this.registryCode, [this.model.id]);
  }

  async fetchData() {
    this.loading = true;
    if (this.revisionNumber) {
      await this.fetchRevision();
    } else {
      await this.fetchCurrent();
    }
    this.$store.commit(
      'utils/cards/needToUpdate',
      CardNeedToUpdateType.VERSION
    );
  }

  async fetchCurrent() {
    if (!this.id) return; // todo remove when IBaseCardCommon.id become required
    const documentApi = new DocumentApi();
    return documentApi
      .getDocument(this.registryCode, this.id)
      .then(({ data }) => {
        this.objModel = data;
        this.$store.commit(`utils/cards/addModel`, {
          model: data,
          path: this.common.path,
        });
      })
      .then(() => {
        this.loading = false;
      });
  }

  async fetchRevision() {
    console.log('[RegistryObject][fetchRevision]');
    if (!this.id) return; // todo remove when IBaseCardCommon.id become required
    const versioningApi = new VersioningApi();
    return versioningApi
      .getDocumentForRevision(
        this.registryCode,
        this.id,
        this.revisionNumber as string
      )
      .then(({ data }) => {
        this.objModel = data;
        this.$store.commit(`utils/cards/addModel`, {
          model: data,
          path: this.common.path,
        });
      })
      .then(() => {
        this.loading = false;
      });
  }

  async recoverRevision() {
    console.log('[RegistryObject][recoverRevision]');
    if (!this.id) return; // todo remove when IBaseCardCommon.id become required
    const versioningApi = new VersioningApi();
    return versioningApi
      .recoverRevision1(
        this.registryCode,
        this.id,
        this.revisionNumber.toString()
      )
      .then(({ data }) => {
        if (data.success) {
          this.goToCurrentRevision();
          notifySuccess(
            this.$t('registries.objUploadedSuccessfully') as string,
            'check_circle_outline'
          );
        }
      })
      .catch((e) => {
        notifyError(e);
      });
  }

  fetchRegistryData() {
    return registryApi
      .getRegistry(this.registryId, 'form')
      .then(({ data: registry }) => {
        if (!this.registry) {
          this.$store.commit(`utils/cards/addModel`, {
            model: registry,
            path: registry.code,
          });
        }
      });
  }

  goBack() {
    this.returnToParentViews(
      `/registries/${this.registryId}`,
      '/cards/personal-accounts'
    );
  }

  goToStatement() {
    this.$router.push(this.statementLink);
  }

  goToCurrentRevision() {
    const route = this.$route;
    // Route.query
    const newQuery: Dictionary<string | (string | null)[]> = {
      ...route.query,
      active: 'data',
    };
    delete newQuery.num;

    this.$router.push({ ...route, query: newQuery } as RawLocation);
  }
}
</script>
