<template>
  <div class="AdminAction">
    <search-bar v-model="filter" :loading="loading" @search="executeSearch" />
    <sort-bar
      v-model="sortButtons"
      :pagination="pagination"
      :loading="loading"
      @click="handleSortClick"
    />
    <re-table
      :data="data"
      :columns="columns"
      :loading="loading"
      :pagination.sync="pagination"
      :rows-per-page-options="[10, 25, 50, 100]"
      @request="onRequest"
    >
      <template #expand="props">
        <q-list class="AdminAction-TableExpand" bordered separator>
          <q-expansion-item label="JSON">
            <q-card>
              <q-card-section>
                <pre>{{ JSON.stringify(props.row, null, 2).slice(2, -1) }}</pre>
              </q-card-section>
            </q-card>
          </q-expansion-item>
        </q-list>
      </template>
      <template v-slot:body-item-extraInfo="props">
        <div v-if="props.row.extraInfo">
          <div v-for="info in getDescriptionErrorRow(props.row.extraInfo)">
            {{ info.label }} - {{ info.value }}
          </div>
        </div>
      </template>
    </re-table>
    <q-dialog v-model="apiErrorShow" no-backdrop-dismiss>
      <api-errors :errorObject="errorInResponse" />
    </q-dialog>
  </div>
</template>

<script lang="ts">
import { Component, Mixins } from 'vue-property-decorator';
import SortBar from '@/recruits/components/common/sort-bar.vue';
import { SortingOption, UrlQueryParams } from '@/recruits/models';
import SearchBar from './search-bar.vue';
import ApiErrors from '@/recruits/components/dialogs/ApiErrors.vue';
import {
  JournalServiceApi,
  AdminActionV1,
} from '@/recruits/openapi/journal-service';
import UrlIntegratedSearch from '@/recruits/mixins/url-integrated-search';
import RefreshKeyInterceptor from '@/recruits/mixins/refresh-key-interceptor.ts';
import { RTableColumn } from '@/interfaces';
import ReTable from '@/recruits/components/common/r-table/index.vue';
import { AdminActionsFilter } from '@/recruits/components/log/admin-actions/search-filter';
import { formatDate } from '@/recruits/utils';
const JOURNAL_API = new JournalServiceApi();

@Component({
  components: {
    SearchBar,
    SortBar,
    ApiErrors,
    ReTable,
  },
})
export default class AdminActions extends Mixins(
  UrlIntegratedSearch,
  RefreshKeyInterceptor
) {
  sortButtons: Array<SortingOption<AdminActionV1>> = [
    { label: 'По дате', value: 'eventTime' },
    { label: 'По типу операции', value: 'event' },
    { label: 'По ФИО', value: 'userName' },
  ];

  filter = new AdminActionsFilter();
  data: Array<AdminActionV1> = [];
  apiErrorShow = false;
  errorInResponse = {};

  async fetchData(
    query: UrlQueryParams
  ): Promise<{ totalRows: number | undefined }> {
    try {
      const { data } = await JOURNAL_API.getAdminActionsV1({
        pagination: {
          sortBy: query.sortby,
          descending: query.descending === 'true',
          page: Number(query.page),
          rowsPerPage: Number(query.perpage),
        },
        search: this.filter.prepareRequestParams(),
      });
      this.data = data.data || [];
      return {
        totalRows: data.totalRows,
      };
    } catch (error) {
      this.errorInResponse = error;
      this.apiErrorShow = true;
      return {
        totalRows: 0,
      };
    }
  }

  getDescriptionErrorRow(val: AdminActionV1['extraInfo']) {
    return val?.errorInfo?.length ? val?.errorInfo : [];
  }

  get columns(): RTableColumn<AdminActionV1>[] {
    return [
      {
        label: 'Дата и время события',
        name: 'eventTime',
        field: 'eventTime',
        format: (val) =>
          typeof val === 'string' ? formatDate(val, 'DD-MM-YYYY HH:mm:ss') : '',
        width: '0.6fr',
        borderless: true,
      },
      {
        label: 'ФИО',
        name: 'userName',
        field: 'userName',
        width: '0.8fr',
        align: 'center',
        borderless: true,
      },
      {
        label: 'Организация',
        name: 'vkName',
        field: 'vkName',
        width: '1.5fr',
        align: 'center',
        borderless: true,
      },
      {
        label: 'Операция',
        name: 'event',
        field: 'event',
        format: (val) =>
          typeof val === 'string'
            ? this.filter.eventOptions.find((option) => option.value === val)
                ?.label || ''
            : '',
        width: '0.4fr',
        align: 'center',
        borderless: true,
      },
      {
        label: 'Статус',
        name: 'status',
        field: 'status',
        format: (val) =>
          typeof val === 'string'
            ? this.filter.statusOptions.find((option) => option.value === val)
                ?.label || ''
            : '',
        width: '0.4fr',
        align: 'center',
        componentPath: 'status-box',
        borderless: true,
      },
      {
        label: 'Описание',
        name: 'description',
        field: 'description',
        width: '0.8fr',
        align: 'center',
        borderless: true,
      },
      {
        label: 'Описание ошибки',
        name: 'extraInfo',
        field: 'extraInfo',
        width: '1.5fr',
        align: 'center',
      },
    ];
  }
}
</script>

<style lang="scss">
.AdminAction {
  &-TableExpand {
    width: 100%;
    font-size: 12px;
  }
}
</style>
