<template>
  <div class="MultiSubpoenaSign">
    <r-btn
      dense
      positive
      :disable="disable"
      :label="label"
      icon="pgs-sign"
      no-wrap
      @click="open"
    >
      <q-tooltip v-if="!!summons.length" anchor="bottom middle">
        <div
          class="MultiSubpoenaSign__Tooltip"
          v-for="sub in summons"
          :key="`recruit-${sub.recruitId}`"
        >
          <div class="MultiSubpoenaSign__Name">
            {{ sub.recruitFullName }}
          </div>
        </div>
      </q-tooltip>
    </r-btn>
    <operation-dialog
      sign
      persistent
      ref="dialog"
      :title="title"
      :sub="subCount"
      v-model="opened"
      @hide="close"
    >
      <div v-if="!!summons.length" class="MultiSubpoenaSign__Recruits">
        <div
          v-for="sub in summons"
          :key="`recruit-${sub.recruitId}`"
          class="MultiSubpoenaSign__Recruit"
        >
          <div class="MultiSubpoenaSign__RecruitName">
            {{ sub.recruitFullName }}
          </div>
          <div class="MultiSubpoenaSign__RecruitDocument">
<!--            <q-icon-->
<!--              class="MultiSubpoenaSign__RecruitDocumentIcon"-->
<!--              name="pgs-document"-->
<!--              size="18px"-->
<!--            />-->
<!--            <span class="MultiSubpoenaSign__RecruitDocumentName">-->
<!--              {{ getFileName(sub) }}-->
<!--            </span>-->
            <base-preview
              v-if="sub.file"
              :s3Url="checkUrlForPreview(sub.file)"
              :extension="getDocumentType(sub.file)"
            >
              <q-icon class="SummonsTable__Icon" name="pgs-view">
                <q-tooltip>Предпросмотр</q-tooltip>
              </q-icon>
            </base-preview>
          </div>
        </div>
      </div>
      <template #process>
        <result-block type="info" icon="pgs-sign" :header="processMessage">
          <TransitionGroup name="results" tag="div">
            <div v-for="res in resultList" :key="res.id">
              <q-icon name="pgs-sign-2" color="info" size="sm" />
              <span>{{ res.fullName }}</span>
            </div>
          </TransitionGroup>
        </result-block>
      </template>
      <template #result>
        <result-block
          :type="hasError ? 'negative' : 'positive'"
          :header="resultMessage"
        >
          <div class="results">
            <div v-for="res in resultList" :key="res.id">
              <q-icon name="pgs-check" color="positive" size="sm" />
              <span>{{ res.fullName }}</span>
            </div>
          </div>
        </result-block>
      </template>
      <template #right-actions>
        <r-btn
          action
          label="Подписать"
          icon="pgs-sign"
          :disable="disable || !certificateIsActive"
          @click="action"
        />
      </template>
      <template
        v-if="operationDialog && operationDialog.formState === 'start'"
        #left-actions-panel
      >
        <r-btn
          outline
          label="Отмена"
          icon="pgs-close"
          color="primary"
          @click="closeModal"
        />
      </template>
      <template #right-actions-result>
        <r-btn
          action
          label="Продолжить"
          icon-right="pgs-shevron-right-off"
          @click="finish"
        />
      </template>
      <template #sign-form>
        <crypto-pro-sign-form
          ref="signForm"
          :process-key="processKey"
          :user-task="userTask"
          :task-process="taskProcess"
          @update:certificateIsActive="certificateIsActive = $event"
          @signed="onSigned"
          @error="onError"
          @finish="onFinish"
        />
      </template>
    </operation-dialog>
  </div>
</template>

<i18n>
{
  "ru": {
    "MultiSign": {
      "selected": "не выбрано | {n} документ | {n} документа | {n} документов",
      "signing": " | Документ подписывается | Документы подписываются | Документы подписываются",
      "signed": " | Документ подписан | Документы подписаны | Документы подписаны",
      "error": " | Документ не подписан | Документы не подписаны | Документы не подписаны"
    }
  }
}
</i18n>

<style lang="scss" scoped>
.SummonsTable__Icon {
  overflow: hidden;
  color: #1491cf;
  font-size: 26px;
  padding: 6px 3px;
  cursor: pointer;
}

.MultiSubpoenaSign {
  &__Recruits {
    display: flex;
    flex-flow: column;
  }
  &__Recruit {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
    background: #ffffff;
    border-bottom: 1px solid rgba(1, 72, 116, 0.11);
    box-shadow: none;
    padding: 8px 0;
  }
  &__RecruitName {
    font-weight: bold;
  }

  &__RecruitDocument {
    display: flex;
    flex-flow: row;
    align-items: center;
  }

  &__RecruitDocumentName,
  &__RecruitDocumentIcon {
    color: #6c7276;
  }

  &__Tooltip {
    margin-bottom: 8px;
    &:last-child {
      margin-bottom: 0;
    }
  }
  &__Name {
    margin-bottom: 2px;
    font-weight: 500;
  }
}
</style>

<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 ProcessStarter from '@/mixins/ProcessStarter';
import CryptoProSignForm from '@/components/common/cryptopro-sign-form/index.vue';
import { SubpoenaListResponseV1 } from '@/recruits/openapi/subpoena-service';
import get from 'lodash/get';
import { FormModel, SignData } from '@/mixins/CriptoProPlugin';
import isArray from 'lodash/isArray';
import isEmpty from 'lodash/isEmpty';
import RInput from '@/recruits/components/common/r-input.vue';
import { notifyError } from '@utils/notify';
import { convertDateFromBackendFormat, DateFormat } from '@utils/format-date';

type PersonInfo = {
  id: string;
  fullName: string;
};

interface IFile {
  s3Name: string;
  s3Url: string;
}

interface ISubpoenaView {
  recruitFullName: string;
  recruitIdERN: string;
  recruitId: string;
  file: Partial<IFile>;
}

@Component({
  components: {
    dataBlock,
    CryptoProSignForm,
    RInput,
  },
  methods: {
    get,
  },
})
export default class MultiSubpoenaSign extends Mixins(
  TaskButton,
  ProcessStarter
) {
  get: typeof get;

  @Prop({ default: () => [] })
  declare readonly model: SubpoenaListResponseV1[];

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

  @Prop({ default: () => null })
  // @ts-ignore
  processKey: string | null;

  @Ref('dialog') operationDialog: OperationDialog;

  @Ref('signForm') signForm: CryptoProSignForm;

  opened = false;

  certificateIsActive = false;

  hasError = false;

  resultList: PersonInfo[] = [];

  checkUrlForPreview(doc: SubpoenaListResponseV1) {
    return doc.s3Url || '';
  }

  getFileName(doc: SubpoenaListResponseV1): string {
    return doc.s3Name || '';
  }

  get processMessage(): string {
    return this.$tc('MultiSign.signing', this.personsCount);
  }

  get resultMessage(): string {
    if (this.hasError) {
      return this.$tc('MultiSign.error', this.personsCount);
    }
    return this.$tc('MultiSign.signed', this.personsCount);
  }

  get personsCount(): number {
    return this.personIds?.length;
  }

  get subCount(): string {
    if (isArray(this.model)) {
      return `${this.$tc('MultiSign.selected', this.model.length)}`;
    }
    return '';
  }

  get personIds(): string[] {
    return (
      this.model?.map((recruitOrId): string => {
        return recruitOrId.recruitId;
      }) || []
    );
  }

  get summons(): ISubpoenaView[] {
    return this.model.flatMap(
      ({ idERN, recruitId, s3Name, s3Url, fullName }) => {
        return {
          recruitId: recruitId,
          recruitFullName: fullName,
          recruitIdERN: idERN,
          file: { s3Name, s3Url },
        };
      }
    );
  }

  get formModel(): FormModel {
    const signDate = convertDateFromBackendFormat(
      Date.now(),
      DateFormat.backend
    );
    return {
      id: null,
      personIds: this.personIds,
      listId: null,
      signDate,
    };
  }

  getDocumentType(file: { s3Url: string }) {
    const array = file?.s3Url?.split('.');
    return array[array.length - 1];
  }

  async action(): Promise<boolean | void> {
    this.operationDialog.toProcess();
    try {
      await this.signForm.sendDataForSign(this.formModel);
    } catch (error) {
      this.operationDialog.reset();
      notifyError(error.message);
      console.error(error);
    }
  }

  onSigned(data: SignData): void {
    const personInfo: PersonInfo = {
      id: data.operationInfo?.recruitId,
      fullName: data.operationInfo?.recruitFullName,
    };
    if (!isEmpty(personInfo)) this.resultList.push(personInfo);
  }

  onError(): void {
    this.hasError = true;
    this.operationDialog.toResult();
  }

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

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

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

  closeModal(): void {
    this.close();
  }

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