<template>
  <div class="register-new-recruit">
    <r-btn
      :disable="disable"
      :label="label"
      dense
      icon="pgs-user-check"
      no-wrap
      positive
      @click="open"
    />
    <operation-dialog
      ref="dialog"
      v-model="opened"
      :sub="fio"
      :title="title"
      @finish="onFinish"
    >
      <div class="row q-col-gutter-md">
        <div class="col-12">
          <data-block
            :form-data="{
              label: 'Тип документа',
              value: 'Решение о постановке на воинский учёт по новому адресу',
              icon: 'pgs-document',
            }"
            bolder
          />
        </div>
        <div class="col-12 col-sm-4 col-md-3">
          <data-block
            :form-data="{
              label: 'Дата решения',
              value: resolutionDate,
              icon: 'pgs-calendar',
            }"
          />
        </div>
        <span class="col-12 ChangeVk-UserInfo__Header">
          ФИО / ДАТА РОЖДЕНИЯ / Военный идентификатор
        </span>
        <div class="col-12 ChangeVk-UserInfo">
          <span class="col-12 ChangeVk-UserInfo__FullName">
            {{ fio }}
          </span>
          <span class="col-12 ChangeVk-UserInfo__BirthDate">
            <q-icon class="ChangeVk-UserInfo__Calendar" name="pgs-calendar" />
            <span class="ChangeVk-UserInfo__Date">
              {{ formatDate(model.mainInfo.birthDate) }}
            </span>
          </span>
          <span class="col-12 ChangeVk-UserInfo__Id">
            {{ model.systemInfo.docId }}
          </span>
        </div>
        <div class="col-12">
          <h5 class="ChangeVk__SubTitle">
            Загрузка файла квитанции подтверждения
          </h5>
          <r-file-loader
            supported-file=".json"
            ref="fileLoader"
            @change="addFile"
          />
        </div>
      </div>

      <template #process>
        <result-block
          :header="processMessage"
          :icon="sign ? 'pgs-sign' : 'pgs-document'"
          type="info"
        />
      </template>
      <template #result>
        <result-block :header="resultMessage" :type="resultType" />
      </template>
      <template #right-actions>
        <r-btn
          action
          icon="pgs-double-check"
          label="Сформировать"
          :disable="!formModel.file"
          @click="action"
        />
      </template>
      <template #right-actions-result>
        <r-btn
          action
          icon-right="pgs-shevron-right-off"
          label="Продолжить"
          @click="finish"
        />
      </template>
    </operation-dialog>
  </div>
</template>

<script lang="ts">
import { Component, Mixins, Prop, Ref } from 'vue-property-decorator';
import dataBlock from '@components/cards/statements/components/dataBlock.vue';
import TaskButton from '@/mixins/TaskButton';
import OperationDialog from '@/components/common/operation-dialog/index.vue';
import { convertDateFormat, DateFormat } from '@/utils/format-date';
import now from 'lodash/now';
import { PersonRegistryApi } from '@/recruits/openapi/person-registry';
import ProcessStarter from '@/mixins/ProcessStarter';
import { formatDate } from '@/recruits/utils';
import RFileLoader, { FileInfo } from '@/components/common/r-file-loader';
import S3UrlSignerFilesService from '@/recruits/services/s3UrlService/files';
import { ModelData, DocumentInfo } from '@/types/documents';
import { DataForRecruit } from '@/recruits/components/recruit-card/masthead/interfaces';

const RegistryApi = new PersonRegistryApi();

@Component({
  components: {
    dataBlock,
  },
  methods: {
    formatDate,
  },
})
export default class ChangeVkDialog extends Mixins(TaskButton, ProcessStarter) {
  formatDate: typeof formatDate;

  @Prop({ default: () => ({}) })
  declare readonly model: DataForRecruit;

  @Prop({ default: () => false })
  readonly sign: boolean;

  @Prop({ default: () => '' })
  readonly title: string;

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

  @Ref('dialog') operationDialog: OperationDialog;
  @Ref('fileLoader') fileLoader: RFileLoader;

  opened = false;

  resultType: 'positive' | 'negative' | '' = '';

  formModel: ModelData = {
    file: null,
  };

  get fio(): string {
    return this.model?.mainInfo?.fullName || '';
  }

  get processMessage(): string {
    return 'Решение о постановке на учёт формируется';
  }

  get resultMessage(): string {
    if (!this.resultType) return '';

    return this.resultType === 'positive'
      ? 'Решение о постановке на учёт сформировано'
      : 'Произошла ошибка';
  }

  async addFile([file]: FileInfo[]): Promise<void> {
    if (!this.formModel || !file) return;

    const docInfo = await this.saveDocument(file);
    if (!docInfo) return;

    const fileIsValid = await this.validateFile(docInfo.s3Url);

    if (docInfo && fileIsValid) {
      this.formModel.file = file?.file || null;
      this.formModel.docInfo = docInfo;
    } else {
      this.fileLoader.clearResults();
    }
  }

  get resolutionDate(): string {
    return convertDateFormat(new Date(now()), undefined, DateFormat.date);
  }

  async saveDocument(file: FileInfo): Promise<DocumentInfo | void> {
    try {
      const s3Url = await S3UrlSignerFilesService.uploadFileToS3ByPath({
        bucket: 'ervu-attachment',
        file: file.file,
        path: `PersonalFiles/quitances/${file.file.name}`,
      });
      if (!s3Url) throw new Error('Не удалось загрузить файл');
      return {
        s3Url,
        name: file.file.name,
      };
    } catch (error: any) {
      this.$q.notify({
        message: error.message,
      });
    }
  }

  async validateFile(s3Url: string): Promise<boolean> {
    try {
      const response = await RegistryApi.checkQuittanceValidityV2({
        s3Url,
        recruitId: this.model.id,
      });
      if (response.status === 200) {
        this.$q.notify({
          message: 'Файл загружен',
          color: 'positive',
        });
        return true;
      }
    } catch (error: any) {
      this.$q.notify({
        message: 'Файл не валиден, проверьте загружаемые параметры',
        color: 'negative',
      });
      return false;
    }

    return false;
  }

  async action(): Promise<void> {
    if (!this.model.currentPrivateFile) {
      this.$q.notify({
        message: 'Нет личного дела для подписания',
        color: 'negative',
      });
      return;
    }

    this.operationDialog.toProcess();
    try {
      const traceId = await this.startProcess({
        processTraceIds: [this.model.currentPrivateFile.processTraceId],
        actionType: 'privateFileAccept',
        docInfo: this.formModel.file ? this.formModel.docInfo : null,
      });

      this.resultType = 'positive';

      this.registerListener((message, removeListener) => {
        if (traceId !== message.traceId) return;
        if (message?.body?.type === 'finish') {
          removeListener();
          this.$emit('refresh');
        }
      });
    } catch (error: any) {
      this.resultType = 'negative';
      this.$q.notify({
        message: error.message,
        color: 'negative',
      });
    } finally {
      this.operationDialog.toResult();
    }
  }

  onFinish(): void {
    this.operationDialog.toResult();
  }

  finish(): void {
    this.$emit('done');
  }

  open(): void {
    if (this.disable) return;
    this.resultType = '';
    this.opened = true;
    this.$emit('open');
  }

  close(): void {
    this.$emit('close');
    this.operationDialog.reset();
    this.opened = false;
    this.resultType = '';
  }
}
</script>

<style lang="scss" scoped>
.r-block {
  background: rgba(53, 126, 172, 0.05);
  border-radius: 4px;

  &__label {
    font-family: 'Golos', sans-serif;
    font-style: normal;
    font-weight: 600;
    font-size: 12px;
    line-height: 16px;

    color: rgba(2, 12, 18, 0.58);
  }
}
.r-field {
  background: rgba(53, 126, 172, 0.05);
  border-radius: 4px;

  &__label {
    font-family: 'Golos', sans-serif;
    font-style: normal;
    font-weight: 600;
    font-size: 12px;
    line-height: 16px;

    color: rgba(2, 12, 18, 0.58);
  }

  &__content {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    padding: 4px 4px 3px 8px;
    gap: 10px;

    background: rgba(242, 248, 253, 0.75);
    background-blend-mode: multiply;
    border-radius: 0;
  }
}
.ChangeVk {
  &-UserInfo {
    display: flex;
    flex-direction: column;
    padding: 0 6px 6px 6px;
    margin-left: 15px;
    background-color: rgba(53, 126, 172, 0.05);
    border-radius: 4px;
    font-family: 'Golos Text', sans-serif;
    &__FullName {
      color: rgba(2, 12, 18, 0.58);
      font-size: 14px;
      font-weight: 500;
    }
    &__BirthDate {
      color: rgba(2, 12, 18, 0.9);
      font-size: 12px;
      display: flex;
      align-items: center;
    }
    &__Calendar {
      font-size: 20px;
      margin-right: 5px;
    }
    &__Date {
      line-height: 1px;
    }
    &__Id {
      font-size: 14px;
      font-weight: 600;
    }
    &__Header {
      font-size: 12px;
      font-family: 'Golos Text', sans-serif;
      color: rgba(2, 12, 18, 0.58);
      font-weight: 600;
      text-transform: uppercase;
    }
    &:not(:last-child) {
      margin-bottom: 4px;
    }
  }

  &__SubTitle {
    font-family: 'Golos Text';
    font-style: normal;
    font-weight: 500;
    font-size: 20px;
    line-height: 24px;
    letter-spacing: -0.015em;
    color: rgba(2, 12, 18, 0.9);
    margin: 1em 0;
  }
}
</style>
