<template>
  <div class="register-new-recruit">
    <r-btn
      dense
      positive
      :disable="disable || CheckRejectApplicationInProgress"
      :label="label"
      @click="open"
      no-wrap
    >
      <q-tooltip v-if="CheckRejectApplicationInProgress">
        Не завершен процесс отказа по заявлению
      </q-tooltip>
    </r-btn>
    <operation-dialog
      persistent
      ref="dialog"
      :title="title"
      :sub="sub"
      :process-key="processKey"
      v-model="opened"
      @hide="close"
    >
      <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>
        <div class="col-12">
          <span class="MultiCancel-UserInfo__Header">
            ФИО / ДАТА РОЖДЕНИЯ / Военный идентификатор
          </span>
          <div
            class="col-12 MultiCancel-UserInfo"
            v-for="recruit in usersInfo"
            :key="recruit.id"
          >
            <span class="col-12 MultiCancel-UserInfo__FullName">
              {{ recruit.fullName }}
            </span>
            <span class="col-12 MultiCancel-UserInfo__BirthDate">
              <q-icon
                class="MultiCancel-UserInfo__Calendar"
                name="pgs-calendar"
              />
              <span class="MultiCancel-UserInfo__Date">
                {{ formatDate(recruit.birthDate) }}
              </span>
            </span>
            <span class="col-12 MultiCancel-UserInfo__Id">
              {{ vkId }}
            </span>
          </div>
        </div>
      </div>
      <template #process>
        <result-block
          type="info"
          :icon="sign ? 'pgs-sign' : 'pgs-document'"
          :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>{{ get(res, 'fullName') }}</span>
            </div>
          </TransitionGroup>
        </result-block>
      </template>
      <template #result>
        <result-block :header="resultMessage">
          <div class="results">
            <div v-for="res in resultList" :key="res.id">
              <q-icon name="pgs-check" color="positive" size="sm" />
              <span>{{ get(res, 'fullName') }}</span>
            </div>
          </div>
        </result-block>
      </template>
      <template #right-actions>
        <r-btn action label="Сформировать" @click="action" />
      </template>
      <template #right-actions-result>
        <r-btn
          action
          label="Продолжить"
          icon-right="pgs-shevron-right-off"
          @click="finish"
        />
      </template>
    </operation-dialog>
  </div>
</template>

<i18n>
  {
    "ru": {
      "MultiCancel": {
        "selected": "не выбрано | одного гражданина | {n} гражданина | {n} граждан",
        "signing": " | Решение формируется | Решения формируются | Решения формируются",
        "signed": " | Решение сформировано | Решения сформированы | Решения сформированы"
      }
    }
  }
</i18n>

<style lang="scss" scoped>
.results-enter-active,
.results-leave-active {
  transition: all 0.5s ease;
}
.results-enter-from,
.results-leave-to {
  opacity: 0;
  transform: translateY(-30px);
}
// TODO вынести
.title-text {
  font-family: 'Golos Text', sans-serif;
  font-style: normal;
  font-weight: 500;
  font-size: 20px;
  line-height: 24px;
  letter-spacing: -0.015em;

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

.MultiCancel {
  &-UserInfo {
    display: flex;
    flex-direction: column;
    padding: 6px;
    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;
    }
  }
}
</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 {
  SearchRecruitsResponseWithList,
  RecruitV3,
} from '@/recruits/openapi/person-registry';
import get from 'lodash/get';
import ProcessStarter from '@/mixins/ProcessStarter';
import { DateFormat, convertDateFormat } from '@/utils/format-date';
import { now, isArray, isString } from 'lodash';
import { formatDate } from '@/recruits/utils';

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

type UserInfo = {
  id: string;
  fullName: string;
  birthDate: string;
};

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

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

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

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

  @Prop({ default: () => 'cancelRegistration' })
  actionType: 'cancelRegistration';

  @Ref('dialog') operationDialog: OperationDialog;

  opened = false;

  resultList: PersonInfo[] = [];

  get CheckRejectApplicationInProgress(): boolean {
    return (
      !isArray(this.model) &&
      !!this.model?.stateRecruit?.rejectApplicationInProgress
    );
  }

  get vkId(): string {
    return (!Array.isArray(this.model) && this.model?.systemInfo?.docId) || '';
  }

  get usersInfo(): UserInfo[] {
    if (Array.isArray(this.model)) {
      return this.model?.map((recruit) => {
        return {
          fullName: recruit.fullName || '',
          birthDate: recruit.birthDate || '',
          id: recruit.id || '',
        };
      });
    }
    return [
      {
        fullName: this.model.mainInfo.fullName,
        birthDate: this.model.mainInfo.birthDate,
        id: this.model.id,
      },
    ];
  }

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

  get resultMessage(): string {
    return this.$tc('MultiCancel.signed', this.length);
  }

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

  get sub(): string {
    if (isArray(this.model) && this.model.length === 1) {
      return get(this.model, '[0].fullName', '');
    }
    if (isArray(this.model))
      return `${this.$tc('MultiCancel.selected', this.model.length)}`;
    return this.model?.mainInfo?.fullName || '';
  }

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

  get firstAndMiddleName(): string {
    if (
      isArray(this.model) ||
      (!this.model?.mainInfo?.firstName && !this.model?.mainInfo?.middleName)
    )
      return '';
    return this.model.mainInfo.firstName + ' ' + this.model.mainInfo.middleName;
  }

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

  get personIds(): string[] {
    if (Array.isArray(this.model)) {
      return (
        this.model?.map((recruitOrId): string => {
          if (isString(recruitOrId)) return recruitOrId;
          return recruitOrId.id;
        }) || []
      );
    }
    return [this.model.id];
  }

  async action(): Promise<void> {
    this.operationDialog.toProcess();
    try {
      const { traceId } = await this.$store.dispatch(
        'wfActions/processes/dispatchProcess',
        {
          processKey: 'milBaseRouteProcess',
          data: {
            actionType: this.actionType,
            personIds: this.personIds,
          },
        }
      );

      this.registerListener((message, removeListener) => {
        if (traceId !== message.traceId) return;
        if (message.body.type === 'task' && message.body.successId) {
          if (isArray(this.model)) {
            this.resultList.push(
              ...this.model.filter((e) => e.id === message.body.successId)
            );
          }
        }
        if (message.body.type === 'finish') {
          this.operationDialog.toResult();
          removeListener();
        }
      });
    } catch (error) {
      console.error(error);
      this.operationDialog.toResult();
    }
  }

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

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

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