<template>
  <div :class="{ invisible: hidden }">
    <slot name="button" v-bind="{ open, label }">
      <r-btn
        dense
        negative
        :disable="disable"
        label="Отклонить"
        @click="open"
        no-wrap
      >
        <q-tooltip v-if="rejectReasonMessage">
          {{ rejectReasonMessage }}
        </q-tooltip>
      </r-btn>
    </slot>
    <operation-dialog
      persistent
      ref="dialog"
      :title="title"
      :sub="model.reason"
      :process-key="processKey"
      v-model="opened"
      @hide="close"
    >
      <div class="RevertApplication">
        <r-textarea label="Комментарий" v-model="returnText" />
      </div>
      <template #process>
        <result-block type="info" header="Решение отклоняется">
          {{ fileName }}
        </result-block>
      </template>
      <template #result>
        <result-block :type="resultType" :header="resultMessage">
          {{ fileName }}
        </result-block>
      </template>
      <template #right-actions>
        <r-btn
          negative
          label="Отклонить"
          icon="pgs-close"
          :disable="disable"
          @click="startProcess"
        />
      </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 OperationDialog from '@/components/common/operation-dialog/index.vue';
import { notifyError } from '@/utils/notify';
import CryptoProSignForm from '@/components/common/cryptopro-sign-form/index.vue';
import { Application } from '@/recruits/openapi/person-registry';
import RSelect from '@/recruits/components/common/r-select.vue';
import RInput from '@/recruits/components/common/r-input.vue';
import moment from 'moment/moment';
import ProcessStarter from '@mixins/ProcessStarter';
import RTextarea from '@/recruits/components/common/r-textarea.vue';

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

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

interface ModelData extends FormModel {
  comment: string;
  file: File | null;
}

@Component({
  components: {
    RSelect,
    RInput,
    RTextarea,
    DataBlock,
    OperationDialog,
    CryptoProSignForm,
  },
  methods: {
    moment,
  },
})
export default class CancelApplication extends Mixins(ProcessStarter) {
  @Prop({ default: false })
  hidden: boolean;

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

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

  @Prop(String) readonly label: string;

  @Prop(String) readonly personId: string;

  @Ref('dialog') operationDialog: OperationDialog;

  opened = false;
  files: FileInfo[] = [];

  formModel: ModelData | null = null;
  loading = false;
  isErrorSign = false;
  returnText = '';

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

  get resultMessage(): string {
    return this.isErrorSign
      ? 'Произошла ошибка'
      : 'Решение об отклонении отменено';
  }

  get resultType(): string {
    return this.isErrorSign ? 'negative' : 'positive';
  }

  get title(): string {
    return `Отклонение решения по заявлению № ${this.model.number}`;
  }

  get rejectReasonMessage(): string {
    if (this.model.reasonCode === 'deregister')
      return 'При отмене решения отказать в снятии с учета будет невозможно';

    if (
      this.model.reasonCode === 'changeVK' ||
      this.model.reasonCode === 'militaryReg'
    )
      return 'При отмене решения отказать в постановке на учет будет невозможно';

    return '';
  }

  // @ts-ignore
  async startProcess(): Promise<void> {
    if (!this.returnText) {
      notifyError('Не введен комментарий');
      return;
    }
    this.operationDialog.toProcess();
    try {
      this.loading = true;
      const { traceId } = await this.$store.dispatch(
        'wfActions/processes/dispatchProcess',
        {
          processKey: 'milBaseRouteProcess',
          data: {
            personIds: [this.personId],
            applicationsId: [this.model.id],
            actionType: 'cancelReject',
            reasonCode: this.model.reasonCode,
            returnText: this.returnText,
          },
        }
      );

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

  showResult(isError = false): void {
    this.isErrorSign = isError;
    this.operationDialog.toResult();
  }

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

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

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

<style lang="scss">
.RejectApplication {
  &-Form {
    display: flex;
    flex-direction: column;
  }
  &-FormLine {
    &:not(:last-child) {
      margin-bottom: 4px;
    }
  }
}
</style>
