<template>
  <centered-1280-box class="PersonalFileRequest">
    <p class="PersonalFileRequest-Header">Личное дело</p>
    <div class="PersonalFileRequest-Table">
      <div
        class="PersonalFileRequest-Table__Row PersonalFileRequest-Table__Header"
      >
        <p class="PersonalFileRequest-TableCol">Дата запроса</p>
        <p
          class="PersonalFileRequest-TableCol PersonalFileRequest-TableCol__Center"
        >
          Статус запроса
        </p>
        <p class="PersonalFileRequest-TableCol">Отправитель личного дела</p>
        <p class="PersonalFileRequest-TableCol">Получатель личного дела</p>
        <p
          class="PersonalFileRequest-TableCol PersonalFileRequest-TableCol__Right"
        >
          Действия
        </p>
      </div>
      <div
        class="PersonalFileRequest-Table__Row PersonalFileRequest-Table__Row__Bg"
        v-for="file in personalFileRequests"
        :key="file.id"
      >
        <div
          class="PersonalFileRequest-TableCol PersonalFileRequest-Table__Date PersonalFileRequest-TableCol__Border"
        >
          <q-icon
            class="PersonalFileRequest-TableCol__Icon"
            name="pgs-request-date"
          />
          {{ formatDate(file.requestDate) }}
        </div>
        <div
          class="PersonalFileRequest-TableCol PersonalFileRequest-Table__Status PersonalFileRequest-TableCol__Border"
        >
          <status-box :status="file.status" type="privateFile" borderless />
        </div>
        <div
          class="PersonalFileRequest-TableCol PersonalFileRequest-TableCol__Border"
        >
          <div>{{ file.sendedRecruitment.name || '—' }}</div>
        </div>
        <div
          class="PersonalFileRequest-TableCol PersonalFileRequest-TableCol__Border"
        >
          <div>{{ file.receivedRecruitment.name || '—' }}</div>
        </div>
        <div
          class="PersonalFileRequest-TableCol PersonalFileRequest-Table__Buttons PersonalFileRequest-TableCol__Right"
        >
          <attach-personal-file
            v-if="displayButton(file, 'confirmEnable')"
            :disable="!file.confirmEnable"
            :model="data"
            :private-file="file"
            @done="$emit('refresh')"
          >
            <template #button="btn">
              <q-icon
                :class="{
                  'PersonalFileRequest-Button__Disable': !file.confirmEnable,
                }"
                class="PersonalFileRequest-Button PersonalFileRequest-Button__Attach"
                name="pgs-import"
                @click="btn.open"
              >
                <q-tooltip>Направить код загрузки личного дела</q-tooltip>
              </q-icon>
            </template>
          </attach-personal-file>
          <reject-personal-file
            v-if="displayButton(file, 'rejectEnable')"
            :disable="!file.rejectEnable"
            :model="file.infoForReject"
          >
            <template #button="btn">
              <q-icon
                :class="{
                  'PersonalFileRequest-Button__Disable': !file.rejectEnable,
                }"
                class="PersonalFileRequest-Button PersonalFileRequest-Button__Undo"
                name="pgs-undo"
                @click="btn.open"
              >
                <q-tooltip>Отклонить</q-tooltip>
              </q-icon>
            </template>
          </reject-personal-file>
          <q-icon
            v-if="displayButton(file, 'requestDownloadEnable')"
            :class="{
              'PersonalFileRequest-Button__Disable': !file.requestDownloadEnable,
            }"
            class="PersonalFileRequest-Button"
            name="pgs-import-from-epgu"
            @click="downloadPrivateFile(file)"
          >
            <q-tooltip> Скачать файл запроса личного дела </q-tooltip>
          </q-icon>
          <q-icon
            v-if="displayButton(file, 'cancelEnable')"
            :class="{
              'PersonalFileRequest-Button__Disable': !file.cancelEnable,
            }"
            class="PersonalFileRequest-Button PersonalFileRequest-Button__Decline"
            :id="'decline' + file.id"
            name="pgs-close"
            @click="decline(file)"
          >
            <q-tooltip :target="'#decline' + file.id">
              Отменить запрос личного дела
            </q-tooltip>
          </q-icon>
          <q-icon
            v-if="displayButton(file, 'accessCodeDownloadEnable')"
            :class="{
              'PersonalFileRequest-Button__Disable': !file.accessCodeDownloadEnable,
            }"
            class="PersonalFileRequest-Button PersonalFileRequest-Button__Export"
            name="pgs-export"
            @click="downloadFile(file.accessCode)"
          >
            <q-tooltip> Скачать код загрузки личного дела </q-tooltip>
          </q-icon>
          <q-icon
            v-if="displayButton(file, 'quittanceDownloadEnable')"
            :class="{
              'PersonalFileRequest-Button__Disable': !file.quittanceDownloadEnable,
            }"
            class="PersonalFileRequest-Button"
            name="pgs-roll"
            @click="downloadFile(file.quittance)"
          >
            <q-tooltip> Скачать квитанцию загрузки личного дела </q-tooltip>
          </q-icon>
        </div>
      </div>
    </div>
  </centered-1280-box>
</template>

<script lang="ts">
import { Component, Prop, Mixins } from 'vue-property-decorator';
import { get } from 'lodash';
import dataBlock from '@components/cards/statements/components/dataBlock.vue';
import StatusBox from '@/recruits/components/common/status-box/index.vue';
import { formatDate } from '@/recruits/utils';
import S3UrlSignerFilesService from '@services/s3urlsigner/files';
import Centered1280Box from '@/recruits/components/common/centered-1280-box.vue';
import { saveBlob } from '@/utils/files';
import {
  RecruitV3,
  PrivateFileV1,
  PersonRegistryApi,
  S3File,
} from '@/recruits/openapi/person-registry';
import AttachPersonalFile from './dialogs/AttachPersonalFile.vue';
import RejectPersonalFile, { ModelProps } from '@/recruits/components/dialogs/RejectPersonalFile.vue';
import { fetchDocumentAttachment } from '@/utils/fetch-document-attachment';
import ProcessStarter from '@/mixins/ProcessStarter';
import { GetKeysByValueType } from '@/recruits/utils/types';

const RecruitApi = new PersonRegistryApi();

type PrivateFileV1Sign = GetKeysByValueType<PrivateFileV1, boolean | undefined>;

interface PrivateFileWithInfoForReject extends PrivateFileV1 {
  infoForReject: ModelProps;
}
@Component({
  components: {
    dataBlock,
    StatusBox,
    Centered1280Box,
    AttachPersonalFile,
    RejectPersonalFile,
  },
  methods: {
    get,
  },
})
export default class PersonalFileTab extends Mixins(ProcessStarter) {
  @Prop()
  readonly data: RecruitV3;

  @Prop({ default: 'milBaseUserActionDistribute' }) declare processKey: string;

  get personalFileRequests(): PrivateFileWithInfoForReject[] {
    return (
      this.data?.privateFile?.map((file) => {
        return {
          ...file,
          infoForReject: {
            id: file.id,
            fullName: this.data.mainInfo.fullName,
            birthDate: this.data.mainInfo.birthDate,
            processTraceId: this.data.currentPrivateFile?.processTraceId || '',
          },
        };
      }) || []
    );
  }

  formatDate(date?: string): string {
    if (!date) return '';
    return formatDate(date);
  }

  displayButton(file: PrivateFileV1, key: PrivateFileV1Sign): boolean {
    return (
      this.$AC.haveOneOfScope([
        this.$AC.scopes.MILITARY_RECRUIT_SPECIALIST,
        this.$AC.scopes.SYSTEM_ADMINISTRATOR,
      ]) && file[key] !== null
    );
  }

  async downloadFile(file: S3File | undefined): Promise<void> {
    if (!file) {
      this.$q.notify({
        message: 'Файл не найден',
      });
      return;
    }

    const { s3Name: fileName, s3url } = file;
    try {
      const { file: blob } = await S3UrlSignerFilesService.fetchFileFromS3ByUrl(
        {
          url: s3url,
        }
      );
      saveBlob({
        blob,
        fileName,
      });
    } catch (e) {
      if (e) {
        this.$q.notify({
          color: 'negative',
          icon: 'error',
          message: (e as Error)?.message ?? e,
        });
      }
    }
  }

  async downloadPrivateFile(file: PrivateFileV1): Promise<void> {
    try {
      if (!file.requestDownloadEnable) {
        this.$q.notify({
          message: 'Файл недоступен для загрузки',
        });
        return;
      }

      const { data } = await RecruitApi.generateListRequestsV1({
        privateFileId: file.id,
      });

      await fetchDocumentAttachment(
        {
          s3Name: file.id + '.json',
          s3url: data,
        },
        'download',
        's3Name',
        's3url'
      );
    } catch (e) {
      if (e) {
        this.$q.notify({
          color: 'negative',
          icon: 'error',
          message: (e as Error)?.message ?? e,
        });
      }
    }
  }

  async decline(file: PrivateFileV1): Promise<void> {
    if (!file.cancelEnable) return;

    if (!this.data.currentPrivateFile) {
      this.$q.notify({
        message: 'Невозможно отменить запрос: отсутствует личное дело',
      });
      return;
    }

    const traceId = await this.startProcess({
      processTraceIds: [this.data.currentPrivateFile.processTraceId],
      actionType: 'privateFileCancel',
    });

    this.registerListener((message, removeListener) => {
      if (traceId !== message.traceId) return;
      if (message.body.type === 'finish') {
        removeListener();
        this.$q.notify({
          message: 'Запрос личного дела успешно отменён',
          color: 'positive',
        });
        this.$emit('refresh');
        return;
      }

      if (message.body.type === 'error') {
        this.$q.notify({
          color: 'negative',
          icon: 'error',
          message: 'Не удалось отменить запрос личного дела',
        });
      }
    });
  }

  mounted(): void {
    this.$store.dispatch('ervuDictionaries/loadPrivateFileStatusDictionary');
  }
}
</script>

<style lang="scss" scoped>
.PersonalFileRequest {
  * {
    margin: 0;
    padding: 0;
  }
  &-Header {
    font-family: 'Golos Text', sans-serif;
    border-bottom: 1px solid rgba(1, 72, 116, 0.11);
    font-style: normal;
    font-weight: 500;
    font-size: 20px;
    line-height: 24px;
    letter-spacing: -0.015em;
    padding-bottom: 12px;
  }
  &-Table {
    &__Row {
      display: grid;
      grid-template-columns: 1fr 1fr 1.5fr 1.5fr 1.5fr;
      &__Bg {
        background: #ffffff;
        border: 1px solid rgba(1, 72, 116, 0.11);
        border-radius: 8px;
      }
    }
    &__Header {
      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;
      color: rgba(2, 12, 18, 0.58);
      padding: 25px 0 10px 0;
    }
    &__Type {
      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);
    }
    &__Name {
      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);
      justify-content: center;
      .doc-name {
        margin: -4px;
      }
    }
    &__Sender {
      font-family: 'Golos UI', sans-serif;
      font-style: normal;
      font-size: 14px;
      line-height: 16px;
      color: rgba(2, 12, 18, 0.9);
      align-items: center;
    }
    &__Date {
      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);
      align-items: center;
    }
    &__Status {
      padding: 0 !important;
      margin: 0 !important;
    }
    &__Buttons {
      ::v-deep.warning-colors {
        background: #fdf3ed;
        color: #cf5f14;
        border-color: #cf5f14;
      }
      align-items: center;
      gap: 12px;
    }
  }
  &-TableCol {
    overflow: hidden;
    display: flex;
    padding: 6px 6px;
    &__Border {
      border-right: 1px solid rgba(1, 72, 116, 0.11);
    }
    &__Center {
      justify-content: center;
    }
    &__Right {
      justify-content: flex-end;
      padding-right: 20px;
    }
    &__Icon {
      font-size: 26px;
      margin-right: 7px;
    }
    &__WithText {
      flex-direction: column;
    }
    &__Sender {
      flex-direction: column;
      align-items: flex-start;
      gap: 4px;
    }
  }
  &-WarningContent {
    font-family: 'Golos UI', sans-serif;
    font-style: normal;
    font-weight: 400;
    font-size: 14px;
    line-height: 14px;
    padding-top: 8px;
    color: #cf5f14;
    display: inline-block;
    &__Bold {
      font-weight: bold;
    }
  }
  &-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;
    }
    &__Noty {
      background: #fdf3ed;
      border-left: 2px solid #cf5f14;
      padding: 8px;

      font-family: 'Golos UI', sans-serif;
      font-style: normal;
      font-weight: 400;
      font-size: 14px;
      line-height: 16px;
      text-align: center;
      color: #cf5f14;
    }
  }
  &-AttentionButtons {
    display: flex;
    justify-content: space-between;
    padding: 12px 20px;
  }
  &-AttentionButton {
    padding: 0 10px;
  }

  &-Button {
    font-size: 26px;
    cursor: pointer;
    // margin-right: 12px;
    &__Attach {
      color: #1491cf;
    }

    &__Undo {
      color: #cf5f14;
    }

    &__Decline {
      color: var(--q-color-negative);
    }

    &__Disable {
      color: rgba(2, 12, 18, 0.58);
      cursor: not-allowed;
    }
  }
}
</style>
