<template>
  <div class="reason-not-attendance">
    <block-loader type="QBtn" :loading="loading">
      <r-btn
        dense
        :label="label"
        icon="pgs-roll"
        :disable="disable"
        @click="buttonOptions.hideDialog ? action() : open()"
        no-wrap
      />
    </block-loader>
    <operation-dialog
      persistent
      ref="dialog"
      :title="title"
      :sub="sub"
      v-model="opened"
    >
      <div class="row q-col-gutter-md">
        <div class="col-12">
          <r-input label="Номер решения" v-model="decisionNumber" />
        </div>
        <div class="col-12 SummonDateInput">
          <r-date-solo-input
            hide-bottom-space
            label="Дата решения"
            :date.sync="decisionDate"
          />
        </div>
        <div class="col-12">
          <r-select
            label="Тип решения"
            dense
            options-dense
            v-model="decisionType"
            :options="decisionOptions"
            :display-value="decisionTypeName"
          >
          </r-select>
        </div>
        <div class="col-12">
          <r-select
            label="Причина неявки"
            dense
            options-dense
            v-model="decisionReason"
            :options="decisionReasonOptions"
            :display-value="decisionReasonName"
          >
          </r-select>
        </div>
        <div class="col-12">
          <r-input label="Комментарий" v-model="decisionComment" />
        </div>
      </div>
      <template #process>
        <result-block type="info" icon="pgs-document" :header="processMessage">
        </result-block>
      </template>
      <template #result>
        <result-block icon="pgs-document" :header="resultMessage">
        </result-block>
      </template>
      <template #right-actions>
        <r-btn
          action
          label="Сохранить"
          :disable="canFormSubmit"
          @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": {
      "RNA": {
        "selected": "не выбрано | один рекрут | {n} рекрута | {n} рекрутов",
        "process": " | Документ формируется | Документы формируются | Документы формируются",
        "result": " | Документ сформирован | Документы сформированы | Документы сформированы"
      }
    }
  }
</i18n>

<style lang="scss" scoped></style>

<script lang="ts">
import { Component, Mixins, Prop, Ref } from 'vue-property-decorator';
import { Option } from '@/recruits/models';
import TaskButton from '@/mixins/TaskButton';
import { RecruitV4 } from '@/recruits/openapi/person-registry';
import OperationDialog from '@/components/common/operation-dialog/index.vue';
import { get, isArray, isString, map, toPairsIn } from 'lodash';
import ProcessStarter from '@/mixins/ProcessStarter';
import Dialog from '@/mixins/Dialog';
import RDateTimeInput from '@/recruits/components/common/r-date-time-input.vue';
import RSelect from '@/recruits/components/common/r-select.vue';
import RInput from '@/recruits/components/common/r-input.vue';
import moment from 'moment';
import { getDictionaryFormatedToOptions } from '@/recruits/utils';
import RDateSoloInput from '@/recruits/components/common/r-date-solo-input.vue';

const DESCISION_TYPE = 'decisionType';

interface ButtonOptions {
  fields?: {
    decisionNumber?: string; // из повестки reason
    decisionDate?: string; // из повестки visitDate (2023-09-13T17:00:00.000Z)
    decisionType?: string; // из повестки decisionType
    decisionReason?: string; // из повестки decisionReason
  };
  editableFields?: string[]; // поля которые можно редактировать
  hideFields?: string[]; // поля, которые нужно скрывать
  hideDialog?: boolean; // если надо скрыть модальное окно
}

@Component({
  components: {
    RDateTimeInput,
    RDateSoloInput,
    RSelect,
    RInput,
  },
})
export default class ReasonNotAttendance extends Mixins(
  TaskButton,
  Dialog,
  ProcessStarter
) {
  @Prop({ default: () => false })
  readonly sign: boolean;

  @Prop({
    default: () => 'Фиксация решения о признании причины неявки уважительной',
  })
  readonly title: string;

  @Prop({ default: () => 'YYYY-MM-DDTHH:mm:ss.SSSZ' })
  readonly emitFormat: string;

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

  @Ref('dialog') operationDialog: OperationDialog;

  decisionNumber: string | null = null;
  decisionDate: string | null = null;
  decisionType: Option | null = null;
  decisionReason: Option | null = null;
  decisionComment = '';

  get canFormSubmit(): boolean {
    return (
      this.disable ||
      !this.decisionNumber ||
      !this.decisionType?.value ||
      !this.decisionDate ||
      !this.decisionReason?.value
    );
  }

  get decisionOptions(): Option[] {
    const dict = this.$store.getters[
      'ervuDictionaries/decisionTypeForGoodReason'
      ];
    return getDictionaryFormatedToOptions(dict);
  }

  get decisionReasonOptions(): Option[] {
    const dict = this.$store.getters['ervuDictionaries/decisionReason'];
    return getDictionaryFormatedToOptions(dict);
  }

  get decisionReasonName(): string {
    return this.decisionReason?.label || '';
  }

  get decisionTypeName(): string {
    return this.decisionType?.label || '';
  }

  get sub(): string {
    if (isArray(this.model))
      return `${this.$tc('RNA.selected', this.model.length)}`;
    return this.model.mainInfo.fullName || '';
  }

  get processMessage(): string {
    return this.$tc('RNA.process', this.personIds.length);
  }

  get resultMessage(): string {
    return this.$tc('RNA.result', this.personIds.length);
  }

  get buttonOptions(): ButtonOptions {
    return get(
      this.userTask,
      ['outData', 'options', this.buttonSettings.id],
      {}
    );
  }

  getDefaultOption(options: Option[], defaultValue?: string): Option {
    const value = options.find(({ value }) => value === defaultValue);
    return (
      value || {
        value: '',
        label: 'Не выбрано',
      }
    );
  }

  getDefaultDate(defaultDate?: string): string | null {
    if (!defaultDate) return null;
    return moment(defaultDate).format(this.emitFormat);
  }

  isFieldDisabled(fieldName: string): boolean {
    return !this.buttonOptions.editableFields?.includes(fieldName);
  }

  isFieldHidden(fieldName: string): boolean {
    return !this.buttonOptions.hideFields?.includes(fieldName);
  }

  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 formModel() {
    return {
      id: this.buttonSettings.id,
      personIds: this.personIds,
      decisionNumber: this.decisionNumber,
      decisionType: this.decisionType,
      decisionReason: this.decisionReason,
      decisionComment: this.decisionComment,
      decisionDate: this.decisionDate,
    };
  }

  async action(): Promise<void> {
    this.operationDialog.toProcess();
    try {
      const taskId = this.userTask.taskId;
      const traceId = this.taskProcess.traceId;
      await this.$store.dispatch('wfActions/processes/submitForm', {
        formModel: this.formModel,
        taskId,
        traceId,
      });

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

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

  async initDescisionTypeDictionary(): Promise<void> {
    await this.$store.dispatch(
      'registryService/referenceBooks/initReferenceBooks',
      [
        {
          id: DESCISION_TYPE,
        },
      ]
    );
  }

  mounted(): void {
    this.initDescisionTypeDictionary();
  }

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

    this.decisionNumber = this.buttonOptions?.fields?.decisionNumber || null;
    this.decisionType = this.getDefaultOption(
      this.decisionOptions,
      this.buttonOptions?.fields?.decisionType
    );
    this.decisionReason = this.getDefaultOption(
      this.decisionReasonOptions,
      this.buttonOptions?.fields?.decisionReason
    );
    this.decisionDate = this.getDefaultDate(
      this.buttonOptions.fields?.decisionDate
    );
  }

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