<template>
  <operation-dialog
    persistent
    sign
    ref="dialogDepartmentEdit"
    :title="departmentName"
    sub="Редактирование подразделения"
    v-model="opened"
    @hide="close"
    class="EditModalForm"
  >
    <div class="EditModalForm__Content">
      <r-input
        class="EditModalForm__Field"
        label="Полное наименование подразделения*"
        v-model="editDepartment.fullname"
        validate-on-blur
        :rules="[(val) => !isEmptyVal(val) || 'Обязательное поле']"
      />
      <r-input
        class="EditModalForm__Field"
        label="Сокращённое наименование подразделения*"
        v-model="editDepartment.shortname"
        validate-on-blur
        :rules="[(val) => !isEmptyVal(val) || 'Обязательное поле']"
      />
      <r-input
        class="EditModalForm__Field"
        label="Код военного комиссариата"
        v-model="editDepartment.militaryCode"
        :rules="[
          (val) =>
            !val || val.match(/^[0-9]{8}$/) || 'Должен состоять из 8 цифр',
        ]"
      />
      <r-input
        class="EditModalForm__Field"
        label="Часовой пояс"
        v-model="editDepartment.timezone"
        :rules="[
          (val) => !val || rulesTimezone(val) || 'Должен быть в формате +01:30',
        ]"
      />
      <div class="EditModalForm__Field">
        <span class="EditModalForm__FieldLabel">Адрес подразделения</span>
        <BasicMAddressComponent
          :id.sync="editDepartment.addressId"
          :value.sync="editDepartment.address"
          filled
          dense
          options-dense
          dropdown-icon="pgs-shevron-down-off"
          :showManualEnter="false"
        />
      </div>
      <div class="EditModalForm__Field">
        <span class="EditModalForm__FieldLabel">
          Почтовый адрес подразделения
        </span>
        <BasicMAddressComponent
          :id.sync="editDepartment.postalAddressId"
          :value.sync="editDepartment.postalAddress"
          filled
          dense
          options-dense
          dropdown-icon="pgs-shevron-down-off"
          :showManualEnter="false"
        />
      </div>
      <r-input
        class="EditModalForm__Field"
        label="Адрес электронной почты"
        v-model="editDepartment.email"
        type="email"
      >
        <template v-slot:icon>
          <q-icon name="email" />
        </template>
      </r-input>
      <div class="EditModalForm__Field">
        <span class="EditModalForm__FieldLabel">Телефон</span>
        <q-input
          fill-mask
          filled
          dense
          mask="+7 (###) ###-##-##"
          unmasked-value
          v-model="editDepartment.phone"
        >
          <template v-slot:prepend>
            <q-icon name="phone" />
          </template>
        </q-input>
      </div>
      <div class="EditModalForm__TogglesBlock">
        <q-toggle
          v-model="editDepartment.reportsEnabled"
          :label="
            editDepartment.reportsEnabled
              ? 'Включать в отчеты'
              : 'Исключать из отчетов'
          "
        />
      </div>
    </div>
    <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 } from 'vue-property-decorator';
import RInput from '@/recruits/components/common/r-input/index.vue';
import RSelect from '@/recruits/components/common/r-select.vue';
import BasicMAddressComponent from '@components/m-address/index.vue';
import { Department } from '@openapi/idm';
import get from 'lodash/get';
import ProcessStarter from '@/mixins/ProcessStarter';
import OperationDialog from '@/components/common/operation-dialog/index.vue';
import { DepartmentWithParent } from '@/models/DepartmentWithParent';
import isString from 'lodash/isString';

@Component({
  components: {
    RInput,
    RSelect,
    BasicMAddressComponent,
  },
})
export default class EditDepartmentModal extends Mixins(ProcessStarter) {
  @Prop({ default: null }) department: DepartmentWithParent | null;
  @Prop({ default: 'EditDepartmentIDMProcess' })
  declare processKey: string;

  @Ref('dialogDepartmentEdit') operationDialog: OperationDialog;

  loading = false;
  opened = false;
  isFinishStep = false;

  editDepartment: DepartmentWithParent = {
    id: '',
    name: '',
    shortname: '',
    fullname: '',
    dns: '',
    parent: {
      id: '',
      name: '',
      shortname: '',
      fullname: '',
      dns: '',
      inn: '',
      ogrn: '',
    },
  };

  get departmentName(): string {
    return (
      this.department?.fullname ||
      this.department?.shortname ||
      this.department?.name ||
      'Подразделение'
    );
  }

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

  @Watch('department')
  private async departmentHandler(): Promise<void> {
    // departmentHandler приходит null - значит надо закрыть окно
    this.opened = false;
    this.resultType = '';
    this.isFinishStep = false;
    this.operationDialog.reset();
    if (!this.department?.id) return;
    this.editDepartment = JSON.parse(JSON.stringify(this.department));
    this.opened = true;
  }

  rulesTimezone(timezone: string): string | boolean {
    const regex = /^[+|-]((0[0-9]|1[0-1]):([0-5][0-9])|12:00)$/;
    const regexMinusZero = /^-00:00$/;
    return regex.test(timezone) && !regexMinusZero.test(timezone);
  }

  isEmptyVal(val: string | null): boolean {
    return isString(val) ? !val.trim().length : true;
  }

  get validateForm(): boolean {
    return (
      !this.isEmptyVal(this.editDepartment.fullname) &&
      !this.isEmptyVal(this.editDepartment.shortname) &&
      (!this.editDepartment.militaryCode?.length ||
        !!this.editDepartment.militaryCode.match(/^[0-9]{8}$/)) &&
      (!this.editDepartment.timezone?.length ||
        !!this.rulesTimezone(this.editDepartment.timezone))
    );
  }

  removeSpaces(val: string): string {
    return val.trim().replace(/ {1,}/g, ' ');
  }

  async submit(): Promise<void> {
    if (!this.validateForm) {
      return;
    }
    this.operationDialog.toProcess();
    const dataObject: {
      department: Department;
      organizationId: string;
    } = {
      department: {
        id: this.editDepartment.id,
        shortname: this.removeSpaces(this.editDepartment.shortname),
        fullname: this.removeSpaces(this.editDepartment.fullname),
        timezone: this.editDepartment.timezone,
        addressId: this.editDepartment.addressId,
        address: this.editDepartment.address,
        postalAddress: this.editDepartment.postalAddress,
        postalAddressId: this.editDepartment.postalAddressId,
        email: this.editDepartment.email,
        phone: this.editDepartment.phone,
        dns: '',
        name: this.editDepartment.fullname,
        reportsEnabled: this.editDepartment.reportsEnabled,
        militaryCode: this.editDepartment.militaryCode || 'emptyValue',
      },
      organizationId: this.editDepartment.parent.id,
    };

    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>

<style lang="scss" scoped>
.EditModalForm {
  &__FieldLabel {
    font-family: 'Golos Text', sans-serif;
    font-style: normal;
    display: inline-block;
    cursor: pointer;
    font-size: 12px;
    line-height: 16px;
    margin-bottom: 4px;
    font-weight: 600;
    color: rgba(2, 12, 18, 0.58);
    transition: 0.3s;
  }

  &__Field {
    margin-bottom: 15px;
    &::v-deep {
      .q-field--with-bottom {
        padding-bottom: 0;
      }

      .q-field--auto-height .q-field__control {
        background: #e5edf5;
        border-bottom: 1px solid rgba(1, 72, 116, 0.18);
        padding: 0 8px;
      }

      .q-field--filled.q-field--highlighted .q-field__control:before {
        opacity: 0;
      }

      .q-field--filled .q-field__control:after {
        height: 0;
      }

      .q-field--focused {
        &.q-field--filled .q-field__control {
          background: white;
          border: 1px solid #0148742e;
        }
      }

      .q-field--filled .q-field__control {
        background: #e5edf5;
        // border-bottom: 1px solid rgba(1, 72, 116, 0.18);
      }
    }
  }

  &__FieldIcon {
    cursor: pointer;
  }

  &__TogglesBlock {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 20px;
  }
}
</style>
