<template>
  <operation-dialog
    persistent
    sign
    ref="dialogEditMainInfoAccount"
    :title="accountFIO"
    sub="Редактирование основных данных"
    v-model="opened"
    @hide="close"
  >
    <AccountBaseForm
      v-if="personData"
      :person-data="personData"
      :submit-function="submitFunction"
      :trigger-submit="triggerSubmit"
      @validateForm="updateStateValidateForm"
    />
    <template #process>
      <result-block
        header="Обновление информации о сотруднике"
        icon="pgs-document"
        type="info"
      />
    </template>
    <template #result>
      <result-block :header="resultMessage" :type="resultType" />
    </template>
    <template #left-actions-panel>
      <r-btn
        outline
        :label="isFinishStep ? 'Закрыть' : 'Отмена'"
        icon="pgs-close"
        color="primary"
        @click="close"
      />
    </template>
    <template #right-actions-panel>
      <r-btn
        v-if="!isFinishStep"
        outline
        label="Сохранить"
        icon="pgs-save"
        positive
        :disable="!validateForm"
        @click="submit"
      />
    </template>
  </operation-dialog>
</template>

<script lang="ts">
import {
  Component,
  Prop,
  Mixins,
  Watch,
  Ref,
  InjectReactive,
} from 'vue-property-decorator';
import get from 'lodash/get';
import ProcessStarter from '@/mixins/ProcessStarter';
import OperationDialog from '@/components/common/operation-dialog/index.vue';
import { ComputedAccount } from '../../utils/types';
import { accountsInjectionKey } from '../../utils/keys';
import { Person } from '@/openapi/idm';
import AccountBaseForm from '@/recruits/components/accounts/components/forms/AccountBaseForm.vue';
import { PersonData } from '@/recruits/components/accounts/utils/types';

@Component({
  components: {
    AccountBaseForm,
  },
})
export default class EditPersonModal extends Mixins(ProcessStarter) {
  @Prop({ default: null }) person: Person | null;
  @Prop({ default: false }) showModal: boolean;
  @Prop({ default: false }) isLocalCredential: boolean;
  @Prop({ default: 'milBaseEditAccountPersonIDMProcess' })
  declare processKey: string;

  @Ref('dialogEditMainInfoAccount') operationDialog: OperationDialog;

  @InjectReactive(accountsInjectionKey) accounts: ComputedAccount[] | null;

  opened = false;
  isFinishStep = false;

  validateForm = false;
  personData: PersonData | null = null;
  triggerSubmit = 0;

  get accountFIO(): string {
    return this.person?.fio || 'Сотрудник';
  }

  private updateStateValidateForm(validateStatus: boolean): void {
    this.validateForm = validateStatus;
  }

  resultType: 'positive' | 'negative' | '' = '';
  resultMessage = '';

  @Watch('showModal')
  private async showModalHandler(): Promise<void> {
    this.opened = false;
    this.resultType = '';
    this.personData = null;
    this.isFinishStep = false;
    this.operationDialog.reset();
    if (!this.showModal || !this.person?.id) return;
    this.personData = this.person;
    this.opened = true;
  }

  async submit(): Promise<void> {
    if (!this.validateForm) {
      return;
    }
    this.triggerSubmit++;
  }

  async submitFunction(personData: PersonData): Promise<void> {
    if (!this.accounts?.length) {
      return;
    }
    this.operationDialog.toProcess();

    const accountId = this.accounts[0].id || null;
    const organizationId =
      this.accounts[0]?.department?.id ||
      this.accounts[0]?.organization?.id ||
      null;

    if (!accountId || !organizationId) {
      this.$q.notify({
        message: `Не удалось найти ${!accountId ? 'аккаунт' : ''} ${
          !organizationId ? 'организацию' : ''
        } сотрудника`,
        color: 'negative',
      });
      return;
    }
    const dataObject: {
      accountId: string;
      organizationId: string;
      personData: PersonData;
    } = {
      accountId,
      organizationId,
      personData,
    };

    try {
      const traceId = await this.startProcess(dataObject);

      this.isFinishStep = true;

      this.registerListener((message, removeListener) => {
        if (traceId !== message.traceId) return;
        if (message?.body?.type === 'finish') {
          this.resultType = 'positive';
          this.resultMessage = 'Информация о сотруднике обновлена';
          removeListener();
        }

        if (message?.body?.type === 'error') {
          this.resultType = 'negative';
          // get т.к. message может быть Task | PushMessage, а в Task нет поля msg
          this.resultMessage = get(
            message,
            'body.msg.message',
            'Произошла непредвиденная ошибка'
          );
          removeListener();
        }
      });
    } catch (error: any) {
      this.resultType = 'negative';
      this.$q.notify({
        message: error.message,
        color: 'negative',
      });
    } finally {
      this.operationDialog.toResult();
    }
  }

  close(): void {
    if (this.isFinishStep) {
      this.$emit('refresh');
    } else {
      this.$emit('close');
    }
  }
}
</script>
