<template>
  <div class="q-pa-md q-gutter-y-md">
    <div
      class="flex justify-between items-center bg-white q-pa-md rounded-borders"
    >
      <div class="text-h5">
        {{ $t('interagencies.label') }}
      </div>

      <div class="q-gutter-x-sm">
        <q-btn
          :loading="importInteragenciesLoading"
          color="primary"
          :label="$t('interagencies.importInteragenciesBtn')"
          @click="importInteragencies"
        />
        <q-btn
          color="primary"
          :label="$t('interagencies.exportInteragenciesBtn')"
          @click="() => (isExportModalOpen = true)"
        />
        <q-btn
          icon="add"
          color="primary"
          :label="$t('base.create')"
          @click="() => (isCreateModalOpen = true)"
        />
      </div>
    </div>

    <div class="bg-white q-pa-md rounded-borders">
      <base-table
        v-model="pagination.search"
        :columns="columns"
        :data="records"
        :use-search="true"
        :pagination.sync="pagination"
        :loading="loading"
        :hide-refresh="true"
        save-query
        @update="getInteragencies"
        @requestTable="getInteragencies"
      />
    </div>

    <q-dialog class="full-width" v-model="isCreateModalOpen">
      <create-interagency-card
        :loading="isCreating"
        @close="isCreateModalOpen = false"
        @submit="onSubmitNewInteragencyClick"
      />
    </q-dialog>
      <ImportDialog
        v-if="importServiceData"
        :open-dialog.sync="importAllDialog"
        :model="importServiceData"
        :user-task="userTask"
        :servicesLoading.sync="servicesLoading"
        submitBtnLabel="Импортировать"
        title="Доступные межведы"
      />
    <q-dialog v-model="isExportModalOpen">
      <ExportCard @close="() => isExportModalOpen = false" />
    </q-dialog>
  </div>
</template>

<script lang="ts">
import { Component, Vue, Watch } from 'vue-property-decorator';
import isEmpty from 'lodash/isEmpty';
import { Interagency, InteragencyApi } from '@openapi/registry-service';
import { generateParentInteragencySearchQuery } from './utils';
import CreateInteragencyCard from './components/parent-interagency/create-interagency-card.vue';
import { pushRoute } from '@utils/routes';
import QColumn from '@/types/QColumn';
import { notifyError, notifySuccess } from '@/utils/notify';
import axios from 'axios';
import ExportCard from './components/export-card.vue';
import { WorkflowServiceApi } from '@openapi/wf';
import get from 'lodash/get';
import cloneDeep from 'lodash/cloneDeep';
import { serviceImportModel } from '../services';
import ImportDialog from '@components/services/components/import-services-dialog.vue';

const interagencyApi = new InteragencyApi();
const sortByDefault = 'modified';
const wfApi = new WorkflowServiceApi();

@Component({
  components: {
    CreateInteragencyCard,
    ExportCard,
    ImportDialog,
  },
})
export default class InteragencyRequestsPage extends Vue {
  columns: QColumn[] = [
    {
      name: 'id',
      label: this.$t('base.table.id'),
      field: (val: any) => val,
      formatField: 'id',
      align: 'left',
      handler: (id: string, opts?: any) => {
        pushRoute(
          this.$router,
          {
            name: 'parent-interagency-page',
            params: {
              id,
            },
          },
          opts?.targetBlank
        );
      },
      handlerField: 'id',
    },
    {
      name: 'clazz',
      label: this.$t('base.table.class'),
      field: 'clazz',
      align: 'left',
      sortable: true,
    },
    {
      name: 'requestName',
      label: this.$t('base.table.title'),
      field: 'requestName',
      align: 'left',
      sortable: true,
    },
    {
      name: 'description',
      label: this.$t('base.table.description'),
      field: 'description',
      align: 'left',
      sortable: true,
    },
  ];
  pagination = {
    descending:
      this.$route.query.descending === undefined
        ? true
        : this.$route.query.descending === 'true',
    rowsPerPage: this.$route.query.rowsPerPage
      ? Number(this.$route.query.rowsPerPage)
      : 10,
    sortBy: this.$route.query.sortBy ? this.$route.query.sortBy : sortByDefault,
    rowsNumber: 0,
    page: this.$route.query.page ? Number(this.$route.query.page) : 1,
    search: this.$route.query.search ? this.$route.query.search : '',
  };
  loading: boolean = false;
  records: Interagency[] = [];
  isCreateModalOpen: boolean = false;
  isImportModalOpen = false;
  isExportModalOpen = false;
  isCreating: boolean = false;

  importServiceData: serviceImportModel | null = null;
  servicesLoading: { [service: string]: boolean } = {};
  importAllDialog = false;
  userTask = '';
  importInteragenciesLoading = false;

  created() {
    this.getInteragencies();
  }

  @Watch('pagination.search')
  onSearch() {
    this.getInteragencies();
  }

  async getInteragencies(val: any = null) {
    if (val?.pagination) {
      this.pagination = val.pagination;
    } else if (!isEmpty(val)) {
      this.pagination = val;
    }
    this.loading = true;
    const response = await interagencyApi
      .pagingInteragency(
        this.pagination.page,
        this.pagination.rowsPerPage,
        generateParentInteragencySearchQuery(
          this.columns.map(c => c.name!),
          '' + this.pagination.search
        ),
        '',
        `${this.pagination.descending ? '-' : '+'}${this.pagination.sortBy}`,
        ''
      )
      .catch((e) => {
        if (e instanceof Error) {
          notifyError(e.message);
        } else if (axios.isAxiosError(e)) {
          notifyError(e.response?.data?.message);
        }
      })
      .finally(() => (this.loading = false));
    if (!response || !response.data) {
      return;
    }
    this.records = response.data.records!;
    this.pagination.rowsNumber = response.data.totalRows!;
  }

  public async onSubmitNewInteragencyClick(newInteragency: any) {
    this.isCreating = true;
    try {
      const { data } = await interagencyApi.createInteragency([
        { ...newInteragency, class: null },
      ]);
      if (data.success) {
        notifySuccess(this.$tc('interagencies.message.success.creation'));
        this.isCreateModalOpen = false;
        this.getInteragencies();
      }
    } catch (e) {
      if (e instanceof Error) {
        notifyError(e.message);
      }
    } finally {
      this.isCreating = false;
    }
  }

  async importInteragencies() {
    this.importInteragenciesLoading = true;

    const currentUser = this.$store.getters['oidcClient/currentUser'];
    const userId = currentUser?.sub;

    await wfApi
      .start({
        processKey: 'BaseBatchImportMZFromNexus',
        data: { userId },
      })
      .then((response: any) => {
        const handler = (e: any) => {
          const data = JSON.parse(get(e, 'data', '{}'));
          if (data.traceId === response?.data?.traceId) {
            const outData: serviceImportModel = get(
              data,
              'body.userTask.outData',
              null
            );
            if (outData?.info && this.importServiceData) {
              const newImportService = cloneDeep(this.importServiceData);
              if (!newImportService.info) newImportService.info = {};

              Object.keys(outData.info).forEach((newInfo) => {
                if (newImportService.info?.[newInfo]) {
                  newImportService.info[newInfo] = {
                    ...newImportService.info?.[newInfo],
                    ...outData.info?.[newInfo],
                  };
                } else {
                  newImportService.info[newInfo] = outData.info[newInfo];
                }

                this.importServiceData = newImportService;
                const logsLoading = cloneDeep(this.servicesLoading);
                delete logsLoading[newInfo];
                this.servicesLoading = logsLoading;
              });
              this.userTask = get(data, 'body.userTask.taskId', '');
            } else if (outData && outData.available) {
              this.importAllDialog = true;
              this.importServiceData = outData;
              this.userTask = get(data, 'body.userTask.taskId', '');
              this.importInteragenciesLoading = false;
              this.servicesLoading = {};
            }
            const succesedImport: serviceImportModel = get(
              data,
              'body.userTask.outData.succesedImport'
            );
            const failedImport: serviceImportModel = get(
              data,
              'body.userTask.outData.failedImport'
            );
            if (
              succesedImport ||
              failedImport ||
              get(data, 'body.success') === false
            ) {
              this.$websockets.removeListener(handler);
            }
          }
        };

        this.$websockets.addListener(handler);
      });
  }
}
</script>
