<template>
  <div class="full-width" style="position: relative">
    <div class="full-width headers ListsDataTable-Row">
      <div class="q-pl-xs text-center">Номер</div>
      <div class="q-pl-xs text-center">Причина вызова</div>
      <div class="text-center">Дата и время вызова</div>
      <div class="text-center">Граждан</div>
      <div class="text-center">Дата формирования</div>
      <div class="text-center"></div>
      <div class="text-center">Статус</div>
      <div class="text-center">Действия</div>
    </div>
    <q-table
      grid
      v-bind="{ ...$props, ...$attrs }"
      @request="requestHandler"
      @update:pagination="paginationHandler"
      row-key="id"
      selection="multiple"
    >
      <template v-slot:item="props">
        <div
          :class="[
            'full-width',
            'body',
            'ListsDataTable-Row',
            get(props, 'row.extend', false) ? 'ListsDataTable-Extend' : '',
          ]"
          @click="goToSummonList(props.row.id)"
          @dblclick="/*dblClickHandler(props.row.id)*/"
        >
          <div class="flex items-center number_field">
            <div class="number cursor-pointer">
              {{ props.row.number || '-' }}
            </div>
          </div>
          <div class="flex items-center no-wrap goal cursor-pointer">
            <span class="name text-no-wrap ellipsis">
              {{ options[props.row.summonObjective] || '-' }}
              <q-tooltip
                contentStyle="width: 300px;"
                v-if="options[props.row.summonObjective]"
                >{{ options[props.row.summonObjective] }}</q-tooltip
              >
            </span>
          </div>
          <div class="flex col no-wrap items-center">
            <template v-if="props.row.turnoutDate">
              <q-icon name="pgs-time" size="20px" />
              <span class="text-no-wrap ellipsis">
                <span>
                  {{ formatDate(props.row.turnoutDate, 'DD.MM.YYYY') }}
                </span>
                <span class="time">
                  {{ formatDate(props.row.turnoutDate, 'HH:mm') }}
                </span>
              </span>
            </template>
            <template v-else>-</template>
          </div>
          <div class="no-wrap flex items-center justify-end">
            <span>
              {{ 50 - props.row.freeCount || '-' }}
            </span>
          </div>
          <div class="flex col no-wrap items-center">
            <template v-if="props.row.createDate">
              <q-icon name="pgs-calendar" size="20px" />
              <span class="text-no-wrap ellipsis">
                {{ formatDate(props.row.createDate) }}
              </span>
            </template>
            <template v-else>-</template>
          </div>
          <div class="extend">
            <q-icon
              :disabled="!get(props, 'row.sendInfo[0].addressType', false)"
              :name="
                get(props, 'row.extend', false)
                  ? 'pgs-close'
                  : 'pgs-message-constructor'
              "
              size="25px"
              color="primary"
              class="cursor-pointer"
              @click.stop="
                get(props, 'row.sendInfo[0].addressType', false) &&
                  extendList(props.row.id)
              "
            />
          </div>
          <div class="status">
            <status-box
              type="callLists"
              :status="props.row.status"
              borderless
            />
          </div>
          <div class="full-width ListsDataTable-Col__Buttons">
            <div
              class="ListsDataTable-Content__Icon__SaveSize"
              v-if="props.row.loading"
            >
              <q-inner-loading color="primary" :showing="props.row.loading" />
            </div>
            <q-icon
              v-if="
                $AC.haveOneOfScope([$AC.scopes.MILITARY_RECRUIT_SPECIALIST]) &&
                !props.row.loading &&
                props.row.merge
              "
              class="ListsDataTable-Content__Icon"
              name="pgs-export"
              @click.stop="
                fetchDocumentAttachment(props.row.id, props.row.merge)
              "
            >
              <q-tooltip>Загрузить</q-tooltip>
            </q-icon>
            <base-preview
              v-if="
                $AC.haveOneOfScope([$AC.scopes.MILITARY_RECRUIT_SPECIALIST]) &&
                !props.row.loading &&
                props.row.merge
              "
              extension="pdf"
              :s3-url="props.row.merge"
            >
              <q-icon class="ListsDataTable-Content__Icon" name="pgs-print">
                <q-tooltip>Печать</q-tooltip>
              </q-icon>
            </base-preview>

            <q-icon
              v-if="
                !props.row.merge &&
                !props.row.loading &&
                $AC.haveOneOfScope([$AC.scopes.MILITARY_RECRUIT_SPECIALIST])
              "
              @click.stop="getPreview(props.row)"
              :disabled="checkStatusListForShapeMerge(props.row)"
              class="ListsDataTable-Content__Icon"
              name="pgs-interagency"
            >
              <q-tooltip>Сформировать</q-tooltip>
            </q-icon>
            <q-icon
              v-if="!props.row.loading && !props.row.opis"
              :disabled="checkStatusListForShapeOpis(props.row.status)"
              class="ListsDataTable-Content__Icon"
              name="pgs-tasks-lists"
              @click.stop="
                !checkStatusListForShapeOpis(props.row.status) &&
                  getFileOpis(props.row.id)
              "
            >
              <q-tooltip>Скачать опись</q-tooltip>
            </q-icon>
            <base-preview
              v-if="
                $AC.haveOneOfScope([$AC.scopes.MILITARY_RECRUIT_SPECIALIST]) &&
                !props.row.loading &&
                props.row.opis
              "
              extension="pdf"
              :s3-url="props.row.opis"
            >
              <q-icon class="ListsDataTable-Content__Icon" name="pgs-print">
                <q-tooltip>Печать описи</q-tooltip>
              </q-icon>
            </base-preview>
            <q-icon
              v-if="
                $AC.haveOneOfScope([$AC.scopes.MILITARY_RECRUIT_SPECIALIST]) &&
                !props.row.loading
              "
              :class="{
                'ListsDataTable-Content__Icon__Not': isStatusProcessed(
                  props.row.status
                ),
              }"
              class="ListsDataTable-Content__Icon"
              color="negative"
              name="pgs-delete"
              :disabled="isStatusProcessed(props.row.status)"
              @click.stop="openDeleteListDialog(props.row)"
            >
              <q-tooltip>Удалить</q-tooltip>
            </q-icon>
          </div>
        </div>
        <div
          v-if="
            get(props, 'row.extend', false) &&
            get(props, 'row.sendInfo[0].addressType', false)
          "
          class="full-width ListsDataTable-Extend__Form"
        >
          <div class="ListsDataTable-Extend__Form__Title">
            Способы направления
          </div>
          <div class="ListsDataTable-Extend__Form__SendInfo">
            <div
              class="ListsDataTable-Extend__Form__SendInfo__Info"
              v-for="info in props.row.sendInfo"
            >
              <div class="ListsDataTable-Extend__Form__SendInfo__Info__Type">
                <span>{{ convertAddressType(info.addressType) }}</span>
              </div>
              <div
                class="ListsDataTable-Extend__Form__SendInfo__Info__Delivery"
              >
                <span v-show="convertMethodType(info.sendCode, '14')">{{
                  convertMethodType(info.sendCode, '14')
                }}</span>
                <span v-show="convertMethodType(info.sendCode, '15')">{{
                  convertMethodType(info.sendCode, '15')
                }}</span>
              </div>
            </div>
          </div>
        </div>
      </template>
    </q-table>
    <q-dialog v-model="deleteListDialog" no-backdrop-dismiss>
      <q-card>
        <q-card-section class="DeleteListDialog-AttentionContent">
          <q-icon
            class="DeleteListDialog-AttentionContent__Icon"
            name="pgs-delete"
          />
          <p class="DeleteListDialog-AttentionContent__Header">
            Вы действительно хотите безвозвратно удалить этот список?
          </p>
        </q-card-section>
        <q-card-actions class="DeleteListDialog-AttentionButtons">
          <r-btn
            class="DeleteListDialog-AttentionButton"
            label="Закрыть"
            v-close-popup
          />
          <r-btn
            class="DeleteListDialog-AttentionButton"
            label="Удалить"
            :action="true"
            @click="deleteList"
          />
        </q-card-actions>
      </q-card>
    </q-dialog>
    <q-dialog v-model="apiErrorShow" no-backdrop-dismiss>
      <process-api-error :errorObject="errorObject" />
    </q-dialog>
  </div>
</template>

<style lang="scss" scoped>
.PreviewDialog {
  display: flex;
  flex-flow: column;
  &-Section {
    display: flex;
    flex-flow: row;
  }
  &-Header {
    flex: none;
  }
  &-Contant {
    flex: 1 1 auto;
    position: relative;
  }
  &-Ref {
    width: 100%;
    height: 100%;
  }
  &-Container {
    position: absolute;
    overflow-y: scroll;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    padding: 16px;
  }
  &-Iframe {
    display: block;
    height: 100%;
    width: 100%;
    border: none;
  }
  &-Pre {
    margin: 0;
  }
  &-Img {
    display: inline-block;
    width: 100%;
    height: 100%;
  }
}

.previewModal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: 100%;
  background: white;
  z-index: 100000;
  iframe {
    width: 90%;
    height: 90%;
    margin: auto;
  }
  & i {
    position: absolute;
    cursor: pointer;
    right: 0;
    top: 0;
    font-size: 50px;
  }
}
.white-tooltip {
  background: white;
  color: black;
  width: 300px;
}
.headers {
  padding: 16px 0 6px 0;
  > div {
    color: rgba(2, 12, 18, 0.58);
    overflow: hidden;
    font-family: 'Golos Text', sans-serif;
    font-style: normal;
    font-weight: 600;
    font-size: 10px;
    line-height: 12px;

    letter-spacing: 0.05em;
    text-transform: uppercase;
  }
}

.body {
  max-height: 5em;
  padding: 4px 0 4px 0;
  margin: 2px 0 2px 0;
  background: #ffffff;
  border: 1px solid rgba(1, 72, 116, 0.11);
  border-radius: 8px;
  box-shadow: none;

  .crap-stick {
    > div > span {
      line-height: 20px;
    }

    ::v-deep i.pgs-calendar {
      top: -1px;
    }
  }

  > div {
    position: relative;
    padding: 0 4px 0 4px;
    overflow: hidden;
    color: rgba(2, 12, 18, 0.9);
    font-family: 'Golos UI', sans-serif;
    font-style: normal;
    font-weight: 400;
    font-size: 14px;
    line-height: 14px;
    justify-content: center;
    .number {
      font-size: 14px;
      line-height: 16px;
      //color: rgba(2, 12, 18, 0.58);
      overflow: hidden;
      text-overflow: ellipsis;
      display: -webkit-box;
      -webkit-line-clamp: 2;
      -webkit-box-orient: vertical;
      padding: 0 4px;
      a {
        text-decoration: none;
        &:link {
          color: #015e98;
        }
        &:visited {
        }
      }
    }
    &.goal {
      justify-content: flex-start;
    }

    &.extend {
      align-items: center;
    }

    &.status {
      margin-top: -4px;
      margin-bottom: -4px;
      padding: 0;
    }
  }
  &:hover {
    border: 1px solid #1491cf;
    box-shadow: 0 0.6px 1.8px rgba(7, 46, 71, 0.12),
      0 3.2px 8px rgba(7, 46, 71, 0.15);
  }
  > div:not(:nth-last-of-type(-n + 2))::after {
    // Кроме последних двух
    position: absolute;
    content: '';
    width: 1px;
    height: 100%;
    top: 0;
    right: 0;
    background-color: rgba(1, 72, 116, 0.11);
  }
}

::v-deep .q-table__bottom {
  font-family: 'Golos UI', sans-serif;
  font-style: normal;
  font-weight: 400;
  font-size: 14px;
  line-height: 16px;
  color: rgba(2, 12, 18, 0.58);
}

.ListsDataTable {
  &-Row {
    display: grid;
    grid-template-columns: 0.5fr 2fr 1fr 0.5fr 1fr 35px 0.7fr 0.7fr;
    .number_field {
      justify-content: flex-start;
    }
  }
  &-Extend {
    margin-bottom: -3px;
    border-radius: 8px 8px 0 0;
    border: 1px solid rgba(1, 72, 116, 0.11);
    border-bottom: 1px solid rgba(1, 72, 116, 0.11);
    background: rgba(4, 15, 125, 0.1);
    &:hover {
      border-bottom: 1px solid rgba(1, 72, 116, 0.11);
    }
    &__Form {
      font-family: 'Golos UI', sans-serif;
      font-style: normal;
      font-weight: 500;
      font-size: 14px;
      line-height: 14px;
      align-self: center;
      color: rgba(2, 12, 18, 0.58);
      display: grid;
      grid-template-columns: 0.2fr 0.8fr;
      max-height: 12em;
      padding: 4px 8px;
      background: #ffffff;
      border: 1px solid rgba(1, 72, 116, 0.11);
      border-radius: 0 0 8px 8px;
      box-shadow: 0 0.6px 1.8px rgba(7, 46, 71, 0.12),
        0 3.2px 8px rgba(7, 46, 71, 0.15);
      &__Title {
        color: rgba(2, 12, 18, 0.58);
      }
      &__SendInfo {
        display: flex;
        flex-direction: column;
        flex-wrap: nowrap;
        gap: 5px;
        font-weight: 400;
        color: rgba(2, 12, 18, 0.9);
        &__Info {
          display: grid;
          grid-template-columns: 300px auto;
          border-radius: 4px;
          width: fit-content;
          line-height: 18px;
          &__Type {
          }
          &__Delivery {
            display: grid;
            grid-template-columns: auto auto;
            gap: 5px;
            span:nth-child(1) {
              text-align: center;
              background: rgba(4, 150, 125, 0.2);
              color: #04967d;
              border-radius: 4px;
              text-transform: uppercase;
            }

            span:nth-child(2) {
              text-align: center;
              background: rgba(1, 94, 152, 0.2);
              color: #015e98;
              border-radius: 4px;
              text-transform: uppercase;
            }
          }
        }
      }
    }
    &:hover + &__Form {
      border: 1px solid #1491cf;
      border-top: 1px solid rgba(1, 72, 116, 0.11);
    }
  }
  &-Col {
    &__Buttons {
      display: flex;
      align-items: center;
      justify-content: center;
    }
  }
  &-Content {
    &__Icon {
      font-size: 26px;
      cursor: pointer;
      color: #1491cf;
      &__Not {
        cursor: not-allowed;
      }
      &__SaveSize {
        color: inherit;
        width: 26px;
        height: 26px;
      }
    }
  }
}
.DeleteListDialog {
  &-AttentionContent {
    * {
      margin: 0;
      padding: 0;
    }
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    padding: 30px 40px;
    &__Icon {
      color: #1491cf;
      font-size: 40px;
      margin-bottom: 10px;
    }
    &__Header {
      font-family: 'Golos Text', sans-serif;
      font-style: normal;
      font-weight: 500;
      font-size: 20px;
      line-height: 24px;
      text-align: center;
      letter-spacing: -0.015em;
      color: #015e98;
      margin-bottom: 24px;
    }
  }
  &-AttentionButtons {
    display: flex;
    justify-content: space-between;
    padding: 12px 20px;
  }
  &-AttentionButton {
    padding: 0 10px;
  }
}
</style>

<script lang="ts">
import { Component, Emit, Mixins, Vue } from 'vue-property-decorator';
import {
  DocumentsMergeServiceApi,
  MergeDocumentWithCountV1,
} from '@/recruits/openapi/doc-merge-service';
import {
  ListElementV2,
  ListRecordV2,
  SummonListRegistryApi,
} from '@/recruits/openapi/summon-list-service';
import { SubpoenaRegistryApi } from '@/recruits/openapi/subpoena-service';
import { formatDate, mask } from '@/recruits/utils';
import StatusBox from '@/recruits/components/common/status-box/index.vue';
import { isArray, get } from 'lodash';
import S3UrlSignerFilesService from '@services/s3urlsigner/files';
import { saveAs } from 'file-saver';
import ProcessStarter from '@mixins/ProcessStarter';
import { AxiosResponse } from 'axios';
import ProcessApiError from '@/recruits/components/dialogs/ProcessApiError.vue';

interface IMergeStartResult {
  jobId?: string;
  listId?: string;
  status?: boolean;
}
type ListRecordV2ForCheck = Required<ListRecordV2 & { disabled: boolean }>;

const applyShapeOpis = ['4'];
const excludeApplyShapeMerge = ['1', '5'];

@Component({
  components: {
    StatusBox,
    ProcessApiError,
  },
  methods: { mask, formatDate, get, isArray },
})
export default class DataTable extends Mixins(Vue, ProcessStarter) {
  private SummonListRegistryApi = new SummonListRegistryApi();
  SubpoenaRegistryApi = new SubpoenaRegistryApi();
  DocumentsMergeServiceApi = new DocumentsMergeServiceApi();

  get options(): string {
    return (
      this.$store.getters[
        'ervuDictionaries/militaryRegistrationUpdatingGoalsDictionary'
      ] || []
    );
  }

  private deleteListDialog = false;
  private delitingList: ListRecordV2 | null = null;
  apiErrorShow = false;
  errorObject = {};
  dialog = false;

  @Emit('update:pagination')
  // eslint-disable-next-line @typescript-eslint/no-empty-function
  paginationHandler(): void {}

  @Emit('request')
  // eslint-disable-next-line @typescript-eslint/no-empty-function
  requestHandler(): void {}

  // @Emit('row:dblclick')
  dblClickHandler(recruitId: string): void {
    this.$router.push({ name: 'call-list', params: { id: recruitId } });
  }

  get getAddressTypesDictionary(): Record<string, string> {
    return this.$store.getters['ervuDictionaries/addressTypeDictionary'] || {};
  }

  get deliveryOptions(): Record<string, string> {
    return this.$store.getters['ervuDictionaries/getDeliveryDirections'] || {};
  }

  isStatusProcessed(status: string): boolean {
    return ['2', '4'].includes(status);
  }

  goToSummonList(id: string): void {
    this.$router.push({ name: 'call-list', params: { id } });
  }

  extendList(id: string) {
    this.$emit('extend-list', id);
  }

  checkStatusListForShapeOpis(status: string) {
    return !applyShapeOpis.includes(status);
  }

  checkStatusListForShapeMerge(row: ListRecordV2ForCheck) {
    if (row?.disabled) return true;
    return excludeApplyShapeMerge.includes(row?.status);
  }

  convertAddressType(type: string) {
    return this.getAddressTypesDictionary[type];
  }

  convertMethodType(sendCode: string[], type: string) {
    return sendCode?.includes(type) ? this.deliveryOptions[type] : '';
  }

  recordListDeletion(recruitList: Array<ListElementV2>): void {
    if (this.delitingList) {
      this.$recordActivity({
        buttonCode: 'summons_list_delete',
        extraInfo: {
          id: this.delitingList.id,
          type: 'list',
          previewInfo: [
            {
              label: 'номер',
              value: this.delitingList.number,
            },
          ],
          detailedInfo: [
            {
              label: 'цель вызова',
              value: this.options[Number(this.delitingList.summonObjective)],
            },
            {
              label: 'дата и время вызова',
              value: this.delitingList.turnoutDate,
              type: 'date',
            },
          ],
          list: recruitList.map((recruit: ListElementV2) => ({
            idERN: recruit.idERN,
            fio: recruit.fullName,
          })),
        },
      });
    }
  }

  public openDeleteListDialog(list: ListRecordV2): void {
    if (list.status && !this.isStatusProcessed(list.status)) {
      this.deleteListDialog = true;
      this.delitingList = list;
    }
  }

  async getFileOpis(listId: string) {
    this.$emit('loadingList', { listId, loading: true });
    const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
    try {
      const { data } = await this.SummonListRegistryApi.getS3UrlOpisV1({
        listId,
        timeZone,
        format: 'PDF',
      });
      if (data.s3url) {
        this.$emit('addOpis', { listId, s3Url: data?.s3url });
      }
    } catch (error) {
      this.$q.notify({
        message: error.message,
      });
    } finally {
      this.$emit('loadingList', { listId, loading: false });
    }
  }

  public async getPreview(row: ListRecordV2ForCheck) {
    if (!this.checkStatusListForShapeMerge(row)) {
      this.$emit('loadingList', { listId: row.id, loading: true });
      try {
        const { data } = await this.SummonListRegistryApi.getRecruitsFromListV2(
          row.id,
          {
            pagination: { page: 1, rowsPerPage: 50 },
            search: {},
          }
        );
        if (isArray(data.data)) {
          const mergeWithCount = data.data?.reduce((recruitsAcc, recruit) => {
            if (recruit?.file?.s3url) {
              const count = recruit?.sendInfo?.reduce((acc, info) => {
                acc += info?.sendCode?.length || 0;
                return acc;
              }, 0 as number);
              recruitsAcc.push({ s3Url: recruit.file.s3url, count });
              return recruitsAcc;
            } else {
              return [];
            }
          }, [] as MergeDocumentWithCountV1[]);
          if (mergeWithCount?.length) {
            const mergeStartResult = (await this.DocumentsMergeServiceApi.mergeDocumentsV2(
              {
                listId: row.id,
                data: mergeWithCount,
              }
            )) as AxiosResponse<IMergeStartResult>;
            this.registerListener((message, removeListener) => {
              if (mergeStartResult?.data?.jobId !== message.body?.jobId) return;
              if (message?.body?.status === 'FINISHED') {
                this.$emit('addLink', {
                  listId: row.id,
                  s3Url: message?.body?.s3url,
                });
              }
              removeListener();
              this.$emit('loadingList', { listId: row.id, loading: false });
            });
          } else {
            this.$emit('loadingList', { listId: row.id, loading: false });
            this.$emit('disabledList', { listId: row.id, disabled: true });
          }
        }
      } catch (e) {
        console.warn(e);
      }
    }
  }

  public async deleteList(): Promise<void> {
    if (this.delitingList?.id) {
      this.$q.loading.show({
        message: `Удаление списка номер ${this.delitingList?.number}`,
      });
      const {
        data: { data },
      } = await this.SummonListRegistryApi.getRecruitsFromListV2(
        this.delitingList.id,
        {
          pagination: {
            page: 1,
            rowsPerPage: 0, // 0 - должен возвращать всех рекрутов
          },
          search: {},
        }
      );
      try {
        await this.SummonListRegistryApi.deleteListV1(this.delitingList?.id);
        this.recordListDeletion(data || []);
      } catch (error) {
        if (error.message !== 'Network Error') {
          if (error.response.status !== 400) {
            this.errorObject = {
              data: {
                message:
                  'Сервис временно недоступен, попробуйте повторить позже',
                description:
                  'Возникла ошибка сетевого соединения. Удаленный сервер недоступен. ' +
                  ' Проверьте сетевое соединение или обратитесь к системному администратору',
              },
            };
          } else {
            this.errorObject = error.response;
          }
        } else {
          this.errorObject = {
            data: {
              message: 'Сервис временно недоступен, попробуйте повторить позже',
              description:
                'Возникла ошибка сетевого соединения. Удаленный сервер недоступен. ' +
                ' Проверьте сетевое соединение или обратитесь к системному администратору',
            },
          };
        }
        this.apiErrorShow = true;
      } finally {
        this.$q.loading.hide();
        this.deleteListDialog = false;
        this.$emit('refresh');
      }
    }
  }

  async fetchDocumentAttachment(listId: string, s3url: string) {
    try {
      if (s3url) {
        const {
          file,
          presignedUrl,
        } = await S3UrlSignerFilesService.fetchFileFromS3ByUrl({
          url: s3url,
        });

        saveAs(file, 'fileName');
      }
    } catch (e) {
      console.warn(e);
    }
  }
}
</script>
