<template>
  <div class="q-pa-md">
    <data-table
      :loading="loading"
      :data="reports"
      :columns="columnsFields"
      :pagination.sync="pagination"
      @request="onRequest"
      :rows-per-page-options="[10, 25, 50, 100]"
    />
  </div>
</template>

<style lang="scss" scoped></style>

<script lang="ts">
import { Component, Mixins, Prop, Watch} from 'vue-property-decorator';
import { keyBy } from 'lodash';
import { SearchFilter, UrlQueryParams} from '@/recruits/models';
import UrlIntegratedSearch from '@/recruits/mixins/url-integrated-search';
import NotificationsListener from '@/recruits/mixins/notifications-listener';
import DataTable from './data-table.vue';
import { reports as reportsApi} from '@/recruits/api/ervu-reports';

const finishedOrderStatuses = ['FINISHED', 'FINISHED_WITHOUT_DATA', 'FAILED'];

function prepareParams({
  sortby,
  descending,
  page,
  perpage,
  ...rest
}: any) {
  return {
    pagination: {
      sortBy: sortby,
      descending: descending,
      page: Number(page),
      rowsPerPage: Number(perpage),
    },
    search: {
      search: rest.search,
    },
  };
}

@Component({
  components: {
    DataTable,
  },
})
export default class Reports extends Mixins(UrlIntegratedSearch, NotificationsListener) {

  @Prop({ default: {} })
  public data: any;

  public filter = new SearchFilter();
  public reports: Array<any> | undefined = [];
  public reportsLookup: any = {};
  watchToReportLoading: any[] = [];

  get columnsFields() {
    return this.data.columns?.fields || [];
  }

  public async fetchData(query: UrlQueryParams): Promise<{ totalRows: number | undefined }> {

    const reportData = await reportsApi.search(
      this.getOrganizationId(),
      this.$route.params.id,
      prepareParams(query)
    );
    if (reportData?.content && Array.isArray(reportData.content)) {
      this.reports = reportData.content;
      this.reportsLookup = keyBy(reportData.content, 'id');
      if (reportData.content?.[0].status && !finishedOrderStatuses.includes(reportData.content[0].status)) {
        this.watchToReportLoading.push(reportData.content?.[0].id);
        this.reloadLap();
      } else {
        this.watchToReportLoading.length &&
        this.watchToReportLoading.splice(0, 1);
      }
    } else {
      this.reports = [];
      this.reportsLookup = {};
    }
    return { totalRows: reportData.totalSize };
  }

  private getOrganizationId(): string {
    const currentUser = this.$store.getters['oidcClient/currentUser'];
    return currentUser.domain_id;
  }

  @Watch('data')
  updateData(data: any) {
    if (!this.loading) {
      this.refresh();
    }
  }

  created(): void {
    this.pagination.sortBy = 'createdAt';
    this.pagination.descending = true;
  }

  reloadLap = this.debounce(()=> {
    if (!this.loading && this.watchToReportLoading.length) {
      this.refresh();
    }
  },5000)

  debounce(callback: () => void, delay: number) {
    let id: ReturnType<typeof setTimeout> | null = null;
    return (...args: any[]) => {
      if (id) {
        clearTimeout(id);
      }
      id = setTimeout(() => {
        callback();
        id = null;
      }, delay);
    };
  }

  handleNotification(messageData: any): void {
    if (messageData.body?.msg === 'Отчет успешно сформирован') {
      const targetReport = this.reportsLookup[messageData.body.statementId];
      if (targetReport) {
        reportsApi.get(messageData.body.statementId).then((result: any) => {
          Object.assign(targetReport, result);
        });
      }
    }
  }
}

</script>
