<template>
  <div class="register-new-recruit">
    <r-btn
      dense
      negative
      :disable="disable"
      :label="label"
      @click="open"
      no-wrap
    />
    <operation-dialog
      sign
      persistent
      ref="dialog"
      title="Отклонение включения в реестр"
      :sub="sub"
      v-model="opened"
      @hide="cancel()"
    >
      <r-select
        class="MultiConfirm-Description"
        label="Причина"
        :options="causes"
        v-model="cause"
      />
      <r-input
        type="text"
        class="MultiConfirm-Description"
        label="Комментарий"
        v-model="description"
      />
      <div class="MultiConfirm-Attention__Header q-mt-md">
        Вы отклоняете включение в реестр:
      </div>
      <div class="MultiConfirm-Attention">
        <div
          v-for="recruit in citizens"
          :key="recruit.id"
          class="MultiConfirm-Attention__Item"
        >
          {{ recruit.fullName }}
        </div>
      </div>
      <template #process>
        <div class="process-loader">
          <upload-status
            status="pending"
            label="В процессе отклонения..."
            file-name="Отклонение включения в реестр"
            :reverse-labels-order="true"
            :label-size="16"
          />
        </div>
      </template>
      <template #result>
        <div class="process-loader">
          <upload-status
            :status="hasError ? 'error' : 'success'"
            :label="resultMessage"
            file-name="Отклонение включения в реестр"
            :label-size="16"
            success-label-color="black"
            :reverse-labels-order="true"
            success-icon="pgs-reply"
          />
          <div v-for="res in citizens" :key="res.id" class="citizens-list">
            <span>{{ get(res, 'fullName') }}</span>
            <div class="success">
              <q-icon name="pgs-ok" color="#04967d" size="sm" />
              <span>Сформировано</span>
            </div>
          </div>
        </div>
      </template>
      <template #right-actions>
        <r-btn
          action
          label="Сформировать"
          :disable="disable"
          @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": {
    "MultiSign": {
      "selected": "не выбрано | {n} решение | {n} решения | {n} решений",
      "signing": " | Документ подписывается | Документы подписываются | Документы подписываются",
      "signed": " | Сформировано решение об отклонении включения сведений в реестр | Сформировано {n} решения об отклонении включения сведений в реестр | Сформировано {n} решений об отклонении включения сведений в реестр",
      "error": " | Документ не подписан | Документы не подписаны | Документы не подписаны"
    }
  }
}
</i18n>

<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 {
  RecruitV4,
  SearchRecruitResponse,
} from '@/recruits/openapi/person-registry';
import get from 'lodash/get';
import { SignData } from '@/mixins/CriptoProPlugin';
import isString from 'lodash/isString';
import isArray from 'lodash/isArray';
import isEmpty from 'lodash/isEmpty';

import { getDictionaryFormatedToOptions } from '@/recruits/utils';
import rSelect from '@/recruits/components/common/r-select.vue';
import rInput from '@/recruits/components/common/r-input.vue';
import { notifyError } from '@utils/notify';
import UploadStatus from '@/components/common/upload-status/index.vue';
import ProcessStarter from '@/mixins/ProcessStarter';

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

@Component({
  components: {
    dataBlock,
    rSelect,
    rInput,
    UploadStatus,
  },
  methods: {
    get,
  },
})
export default class MultiNotConfirm extends Mixins(
  TaskButton,
  ProcessStarter
) {
  get: typeof get;

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

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

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

  @Prop()
  actionType: 'notConfirmRecruit';

  @Prop()
  activityRecorderOptions: any;

  @Ref('dialog') operationDialog: OperationDialog;

  opened = false;

  certificateIsActive = false;

  hasError = false;

  resultList: PersonInfo[] = [];

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

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

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

  get citizens(): Array<SearchRecruitResponse | RecruitV4> {
    if ((this.model as SearchRecruitResponse[])?.length !== undefined)
      return this.model as SearchRecruitResponse[];
    const recruit = this.model as RecruitV4;
    return [
      {
        ...recruit.mainInfo,
        ...recruit,
      } as RecruitV4,
    ];
  }

  cause = {
    value: '',
    label: '',
  };

  get causes() {
    const dict = this.$store.getters[
      'ervuDictionaries/causeNotConfirmDictionary'
    ];
    return getDictionaryFormatedToOptions(dict).sort((a, b) => {
      return a.label[0] < b.label[0] ? -1 : a.label[0] > b.label[0] ? 1 : 0;
    });
  }

  description = '';

  get sub(): string {
    if (this.citizens.length > 1)
      return `${this.$tc('MultiSign.selected', this.citizens.length)}`;
    return (this.citizens[0] as SearchRecruitResponse).fullName || '';
  }

  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];
  }

  get extraInfo() {
    const list = isArray(this.model)
      ? this.model.map((e: any) => ({
          id: e.id,
          idERN: e.idern,
          fio: e.fullName,
        }))
      : [
          {
            id: this.model.id,
            idERN: this.model?.systemInfo?.idERN,
            fio: this.model?.mainInfo?.fullName,
          },
        ];

    return {
      list,
    };
  }

  get formModel() {
    return {
      personIds: this.personIds,
      actionType: this.actionType,
      cause: this.cause.value,
      description: this.description,
    };
  }

  async action(): Promise<void> {
    if (!this.cause.value) {
      notifyError('Не выбрана причина');
      return;
    }
    this.operationDialog.toProcess();
    this.$recordActivity({
      buttonCode: 'commissariat_not_confirm_sign',
      extraInfo: {
        detailedInfo: [
          {
            label: 'причина',
            value: this.cause.label,
          },
          {
            label: 'комментарий',
            value: this.description,
          },
        ],
        ...this.extraInfo,
      },
    });
    try {
      const traceId = await this.startProcess(this.formModel);

      this.registerListener((message, removeListener) => {
        if (traceId !== message.traceId) return;
        if (message.body.type === 'finish') {
          this.operationDialog.toResult();
          removeListener();
        }
      });
    } catch (error) {
      console.error(error);
      this.operationDialog.toResult();
    }
  }

  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');
    this.$recordActivity({
      buttonCode: 'commissariat_not_confirm',
      extraInfo: this.extraInfo,
    });
  }

  close(): void {
    this.opened = false;
    this.resultList = [];
    this.cause = {
      value: '',
      label: '',
    };
    this.operationDialog.reset();
    this.$emit('close');
  }

  cancel(): void {
    this.close();
    this.$recordActivity({
      buttonCode: 'commissariat_not_confirm_cancel',
      extraInfo: this.extraInfo,
    });
  }
}
</script>

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

.MultiConfirm {
  &-Attention {
    overflow: auto;
    max-height: 65vh;
    border-top: 1px solid #e3ebf0;
    padding-top: 24px;

    &__Header {
      font-family: 'Golos UI', sans-serif;
      font-size: 16px;
      font-weight: bold;
      margin-bottom: 10px;
    }

    &__Item {
      font-family: 'Golos UI';
      font-size: 14px;
      font-weight: 500;
      line-height: 16px;
      letter-spacing: 0em;
      height: 25px;
    }
  }
  &-ErrorMessage {
    &__Header {
      font-family: 'Golos UI', sans-serif;
      font-size: 20px;
      color: rgba(193, 5, 37, 1);
    }
    &__Icon {
      font-size: 30px;
    }
    &__Date {
      font-family: 'Golos Text', sans-serif;
      font-size: 12px;
      color: rgba(157, 157, 161, 1);
      margin-bottom: 5px;
    }
    &__DateText {
      margin-right: 5px;
    }
    &__Description {
      font-family: 'Golos Text', sans-serif;
      font-size: 14px;
      color: rgba(157, 157, 161, 1);
      &Des {
        background-color: rgba(248, 248, 250, 1);
        border-left: 1px solid rgba(206, 206, 210, 1);
        padding: 5px;
      }
    }
  }

  &-Description {
    margin-bottom: 5px;
  }
}

.process-loader {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  ::v-deep .upload-status {
    margin-bottom: 16px;
  }
}

.citizens-list {
  display: flex;
  width: 400px;
  max-width: 90vw;
  font-weight: 500;
  justify-content: space-between;
  .success {
    display: flex;
    align-items: center;
    color: #04967d;
  }
}
</style>
