<template>
  <div class="attach-personal-file" :class="{ invisible: hidden }">
    <slot name="button" v-bind="{ open, label }">
      <r-btn
        :disable="disable"
        :label="label"
        icon="pgs-paperclip"
        @click="open"
      />
    </slot>
    <operation-dialog
      persistent
      sign
      ref="dialog"
      :title="title"
      :sub="sub"
      v-model="opened"
      @hide="close"
    >
      <div class="row q-col-gutter-md">
        <div class="col-12">
          <r-file-loader
            ref="fileLoader"
            supported-file=".json"
            @change="addFile"
          />
        </div>
        <!-- <div class="divider"><div>ИЛИ</div></div>
        <div class="col-12">
          <div class="RTextarea">
            <label class="RTextarea__label">Код загрузки личного дела</label>
            <r-input
              v-if="formModel"
              v-model="formModel.accessCode"
              placeholder="Введите код загрузки личного дела"
            />
            <div class="warning-msg" v-if="!isModelReady">
              Обязательно для заполнения в случае отсутствия файла с кодом
              загрузки
            </div>
          </div>
        </div> -->
      </div>
      <template #process>
        <result-block type="info" header="Файл загружается">
          {{ fileName }}
        </result-block>
      </template>
      <template #result>
        <result-block
          :type="hasError ? 'negative' : 'positive'"
          :header="hasError ? 'Файл не загружен' : 'Файл загружен'"
          :icon="hasError ? 'pgs-stop' : 'pgs-ok'"
        >
          {{ fileName }}
        </result-block>
      </template>
      <template #right-actions>
        <r-btn
          action
          label="Отправить на подписание"
          icon="pgs-sign"
          :disable="disable || !isModelReady"
          @click="action"
        />
      </template>
      <template #right-actions-result>
        <r-btn
          action
          label="Продолжить"
          icon-right="pgs-shevron-right-off"
          @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 { notifyError } from '@/utils/notify';
import { DateFormat, convertDateFormat } from '@/utils/format-date';
import S3UrlSignerFilesService from '@/recruits/services/s3UrlService/files';
import {
  LoadLdResponseV1,
  PersonRegistryApi,
} from '@/recruits/openapi/person-registry';
import ProcessStarter from '@/mixins/ProcessStarter';
import RInput from '@/recruits/components/common/r-input.vue';
import RFileLoader from '@/components/common/r-file-loader';

interface FileInfo {
  fileName: string;
  fileSize: number;
  file: File;
  fileExt: string;
}

type FormModel = Record<string | symbol, unknown>;

interface DocumentInfo {
  s3Url: string;
  name: string;
  sigUrl?: string;
  sigName?: string;
}

interface ModelData extends FormModel {
  accessCode: string;
  file: File | null;
  docInfo?: {
    s3Url: string;
    name: string;
  } | null;
}

const RegistryApi = new PersonRegistryApi();

@Component({
  components: {
    DataBlock,
    OperationDialog,
    RInput,
  },
})
export default class AttachPersonalFile extends Mixins(
  TaskButton,
  ProcessStarter
) {
  @Prop({ default: false })
  hidden: boolean;

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

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

  @Prop({ default: () => 'Загрузка файла:' })
  readonly title: string;

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

  opened = false;
  certificateIsActive = false;
  hasError = false;

  files: FileInfo[] = [];

  formModel: ModelData | null = null;

  get sub(): string {
    return `${this.model?.fullName}, ${this.birthDate}`;
  }

  get birthDate(): string {
    return convertDateFormat(
      this.model?.birthDate,
      DateFormat.invertedDate,
      DateFormat.date
    );
  }

  get fileName(): string {
    return this.formModel?.file?.name || '';
  }

  get isModelReady(): boolean {
    return !!(this.formModel?.file || this.formModel?.accessCode);
  }

  isCertReady(): boolean {
    return this.certificateIsActive;
  }

  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();
    }
  }

  async saveDocument(file: FileInfo): Promise<DocumentInfo | void> {
    try {
      const s3Url = await S3UrlSignerFilesService.uploadFileToS3ByPath({
        bucket: 'ervu-attachment',
        file: file.file,
        path: `PersonalFiles/${this.model.recruitId}/file/${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.checkAccessCodeValidityV2({
        s3Url,
        id: 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.formModel) return;

    this.operationDialog.toProcess();
    try {
      const payload: FormModel = {
        processTraceIds: [this.model.processTraceId],
        actionType: 'privateFileAttachCode',
        docInfo: this.formModel.file ? this.formModel.docInfo : null,
      };

      // if (this.formModel.file) payload.docInfo = await this.saveDocument();

      if (this.formModel.accessCode)
        payload.accessCode = this.formModel.accessCode;

      const traceId = await this.startProcess(payload);

      this.registerListener((message, removeListener) => {
        if (traceId !== message.traceId) return;
        if (message?.body?.type === 'finish') {
          this.operationDialog.toResult();
          removeListener();
        }
      });
    } catch (error) {
      this.hasError = true;
      this.operationDialog.toResult();
      if (error instanceof Error) notifyError(error.message);
    }
  }

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

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

  open(): void {
    if (this.disable) return;
    this.files = [];
    this.formModel = {
      accessCode: this.model.privateFileAccessCode ?? '',
      file: null,
    };
    this.opened = true;
  }

  close(): void {
    this.$emit('close');
    this.formModel = null;
    this.opened = false;
    this.hasError = false;
  }
}
</script>

<style lang="scss" scoped>
.RTextarea {
  display: flex;
  flex-flow: column nowrap;
  justify-content: stretch;
}
.RTextarea__control {
  background: rgba(242, 248, 253, 0.75);
  background-blend-mode: multiply;
  border: none;
  border-bottom: 1px solid rgba(1, 72, 116, 0.18);
  padding: 8px;
  border-start-start-radius: 8px;
}
.RTextarea__label {
  font-family: 'Golos Text', sans-serif;
  font-style: normal;
  font-weight: 600;
  font-size: 12px;
  line-height: 16px;
  margin-bottom: 4px;

  color: rgba(2, 12, 18, 0.58);
}
.attached-file__icon {
  font-size: 48px;
}
.attached-file {
  display: flex;
  flex-flow: row;
  align-items: center;
}
.attached-file__content {
  flex: 1 1 auto;
}
.attached-file__delete {
  flex: none;
}

.attached-file__capure {
  color: #cfcfcf;
  font-size: 10px;
  line-height: 15px;
}
.attached-file__name {
  font-weight: bold;
  line-height: 20px;
}

.divider {
  display: flex;
  align-items: center;
  font-weight: 600;
  color: grey;
  width: 100%;
  gap: 8px;
  &:before,
  &:after {
    content: '';
    display: block;
    height: 2px;
    width: 100%;
    background: lightgrey;
  }
}

.warning-msg {
  margin-top: 12px;
  font-weight: 500;
  background: rgba(red, 0.15);
  border-radius: 4px;
  padding: 12px 16px;
  font-family: 'Golos UI';
  font-size: 14px;
  font-weight: 400;
  line-height: 16px;
  letter-spacing: 0em;
  text-align: left;
  border: 1px solid rgba(red, 0.4);
}
</style>
