<i18n>
{
  "en": {
    "EmployeesCreateAccountForm": {
      "organization": "Organization",
      "region": "Region",
      "searchOrganization": "Search organization",
      "searchRegion": "Search region",
      "send": "Send",
      "notChoose": "Not chosen",
      "department": "Department",
      "startDateTime": "Account Activation Date and Time",
      "endDateTime": "Account disabled date and time",
      "disabledLabel": "Account is blocked",
      "position": "Position",
      "or": "OR"
    }
  },
  "ru": {
    "EmployeesCreateAccountForm": {
      "organization": "Организация",
      "region": "Регион",
      "searchOrganization": "Поиск организации",
      "searchRegion": "Поиск региона",
      "send": "Далее",
      "notChoose": "Не выбрано",
      "department": "Подразделение",
      "startDateTime": "Дата и время активации доступа сотрудника",
      "endDateTime": "Дата и время отключения доступа сотрудника",
      "disabledLabel": "Доступ сотруднику заблокирован",
      "position": "Должность",
      "or": "ИЛИ"
    }
  }
}
</i18n>

<template>
  <q-form class="q-gutter-y-md" @submit="submit">
    <div v-if="readonly" class="q-gutter-y-sm">
      <div v-if="organizationName" class="row">
        <div class="col text-grey-5">
          {{ $t('EmployeesCreateAccountForm.organization') }}
        </div>
        <div class="col text-grey-7">{{ organizationName }}</div>
      </div>
      <div v-if="regionName" class="row">
        <div class="col text-grey-5">
          {{ $t('EmployeesCreateAccountForm.region') }}
        </div>
        <div class="col text-grey-7">{{ regionName }}</div>
      </div>
      <div class="row">
        <div class="col text-grey-5">
          {{ $t('EmployeesCreateAccountForm.department') }}
        </div>
        <div class="col text-grey-7">{{ labelView }}</div>
      </div>
      <div class="row">
        <div class="col text-grey-5">
          {{ $t('EmployeesCreateAccountForm.position') }}
        </div>
        <div class="col text-grey-7">{{ position }}</div>
      </div>
      <div v-if="!!inputData.isEditProcess" class="row">
        <div class="col text-grey-5">
          {{ $t('EmployeesCreateAccountForm.startDateTime') }}*
        </div>
        <div class="col text-grey-7">{{ startDateTime }}</div>
      </div>
      <div v-if="!!inputData.isEditProcess" class="row">
        <div class="col text-grey-5">
          {{ $t('EmployeesCreateAccountForm.endDateTime') }}
        </div>
        <div class="col text-grey-7">{{ endDateTime || '-' }}</div>
      </div>
    </div>
    <div v-else class="q-gutter-y-md">
      <div v-if="haveScopeToChangeOrg" class="row">
        <div class="col-xs-12 col-md q-mr-md-md">
          <BaseAutocompleteSelect
            :model.sync="regions"
            :async-getter="getRegions"
            :field-label="$t('EmployeesCreateAccountForm.searchRegion')"
            label-value="fullname"
            :disable="Boolean(organizations.selected)"
            @value="setRegion"
          />
        </div>
      </div>
      <div v-if="haveScopeToChangeOrg" class="row">
        {{ $t('EmployeesCreateAccountForm.or') }}
      </div>
      <div v-if="haveScopeToChangeOrg" class="row">
        <div class="col-xs-12 col-md q-mr-md-md">
          <BaseAutocompleteSelect
            :model.sync="organizations"
            :async-getter="getOrganizations"
            :field-label="$t('EmployeesCreateAccountForm.searchOrganization')"
            label-value="fullname"
            :disable="Boolean(regions.selected)"
            @value="setOrganization"
          />
        </div>
      </div>
      <div class="row">
        <div v-if="!haveScopeToChangeOrg" class="col-xs-12 col-md q-mr-md-md">
          <q-input
            v-model="organizationName"
            filled
            :label="$t('EmployeesCreateAccountForm.organization') + '*'"
            type="text"
            readonly
          />
        </div>
        <div class="col-xs-12 col-md q-mr-md-md q-mt-xs-md q-mt-md-none">
          <q-select
            :disable="!departments.length"
            filled
            v-model="selectDepartment"
            clearable
            :options="departments"
            option-value="id"
            option-label="fullname"
            :label="$t('statements.RoutingDialog.department')"
          >
          </q-select>
        </div>
        <div class="col-xs-12 col-md q-mr-md-none q-mt-xs-md q-mt-md-none">
          <q-input
            v-model="position"
            filled
            :label="$t('EmployeesCreateAccountForm.position')"
            type="text"
          />
        </div>
      </div>
      <div v-if="!!inputData.isEditProcess" class="row">
        <div class="col-xs-12 col-sm q-mr-sm-md">
          <q-input
            v-model="startDateTime"
            filled
            :mask="inputMask"
            :label="$t('EmployeesCreateAccountForm.startDateTime')"
          >
            <template #prepend>
              <q-icon name="event" class="cursor-pointer">
                <q-popup-proxy transition-show="scale" transition-hide="scale">
                  <q-date v-model="startDateTime" :mask="dateMask" />
                </q-popup-proxy>
              </q-icon>
            </template>

            <template #append>
              <q-icon name="access_time" class="cursor-pointer">
                <q-popup-proxy transition-show="scale" transition-hide="scale">
                  <q-time v-model="startDateTime" :mask="dateMask" format24h />
                </q-popup-proxy>
              </q-icon>
            </template>
          </q-input>
        </div>
        <div class="col-xs-12 col-sm q-mt-xs-md q-mt-sm-none">
          <q-input
            v-model="endDateTime"
            filled
            :mask="inputMask"
            :label="$t('EmployeesCreateAccountForm.endDateTime')"
          >
            <template #prepend>
              <q-icon name="event" class="cursor-pointer">
                <q-popup-proxy transition-show="scale" transition-hide="scale">
                  <q-date v-model="endDateTime" :mask="dateMask" />
                </q-popup-proxy>
              </q-icon>
            </template>

            <template #append>
              <q-icon name="access_time" class="cursor-pointer">
                <q-popup-proxy transition-show="scale" transition-hide="scale">
                  <q-time v-model="endDateTime" :mask="dateMask" format24h />
                </q-popup-proxy>
              </q-icon>
            </template>
          </q-input>
        </div>
      </div>
      <div
        v-if="
          !!inputData.isEditProcess &&
          accountId !== $store.getters['oidcClient/currentUser'].sub
        "
      >
        <q-toggle
          v-model="disabled"
          :label="$t('EmployeesCreateAccountForm.disabledLabel')"
        />
      </div>

      <q-btn
        color="primary"
        :label="$t('EmployeesCreateAccountForm.send')"
        type="submit"
      />
    </div>
  </q-form>
</template>

<script lang="ts">
// @ts-nocheck

import BaseAutocompleteSelect from '@components/common/base-autocomplete-select/index.vue';
import { USER_SCOPES } from '@constants/entities/Scope';
import { v4 } from 'uuid';
import {
  convertDateFormat,
  convertDateFromBackendFormat,
  convertDateToBackendFormat,
} from '@utils/format-date';
import { DateFormat } from '@constants/utils/format-date';
import { LinksApi, DepartmentApi, RegionApi } from '@openapi/idm';
import { notifyError } from '@utils/notify';
import get from 'lodash/get';

const linksApiIdm = new LinksApi();
const departmentApi = new DepartmentApi();
const regionApi = new RegionApi();

const DEPARTMENT = 'Department';
const ORGANIZATION = 'Organization';
const REGION = 'Region';

export default {
  components: {
    BaseAutocompleteSelect,
  },
  props: ['input-data', 'readonly'],
  data() {
    return {
      USER_SCOPES: USER_SCOPES,
      accountId: '',
      organizationName: '',
      organizationId: '',
      regionName: '',
      departments: [],
      selectDepartment: null,
      position: '',
      selected: '',
      label: '',
      startDateTime: '',
      endDateTime: '',
      disabled: false,
      modified: null,
      departmentParent: null,
      organizations: {
        pageSize: 20,
        lastPage: 0,
        nextPage: 1,
        search: '',
        records: [],
        selected: null,
        loading: false,
        coolDown: false,
      },
      regions: {
        pageSize: 20,
        lastPage: 0,
        nextPage: 1,
        search: '',
        records: [],
        selected: null,
        loading: false,
        coolDown: false,
      },
    };
  },
  computed: {
    /**
     * Свойство для проверки наличия scope CLOUD_ADMIN или SECURITY_ADMINISTRATOR
     * @return {boolean}
     */
    haveScopeToChangeOrg(): boolean {
      return this.$AC.haveOneOfScope([
        this.$AC.scopes.CLOUD_ADMIN,
        this.$AC.scopes.SECURITY_ADMINISTRATOR,
      ]);
    },
    userDomain() {
      if (this.selectDepartment) {
        return this.selectDepartment.id;
      } else if (get(this, 'organizations.selected')) {
        return get(this, 'organizations.selected.id', '');
      } else if (get(this, 'regions.selected')) {
        return get(this, 'regions.selected.id', '');
      }
      return this.inputData.userDomainId;
    },
    outputData() {
      const accountData = {
        account: {
          id: this.accountId,
          start: new Date().toISOString(),
          enabled: !this.disabled,
          schema: 'Account',
          'user-domain': this.userDomain,
          person: this.inputData.person,
          position: this.position,
        },
        accountDataForStepper: {
          label: this.labelView,
        },
      };
      if (this.organizationName) {
        accountData.accountDataForStepper.organizationName = this.organizationName;
      } else if (this.regionName) {
        accountData.accountDataForStepper.regionName = this.regionName;
      }
      if (this.inputData.isEditProcess) {
        if (this.startDateTime) {
          accountData.account.start =
            convertDateToBackendFormat(this.startDateTime, this.dateMask) ||
            new Date().toISOString();
        }
        if (this.endDateTime) {
          accountData.account.finish =
            convertDateToBackendFormat(this.endDateTime, this.dateMask) || null;
        }
        accountData.isEditProcess = true;
        accountData.account.modified = this.modified || null;
      }

      return accountData;
    },
    labelView() {
      return this.label || this.$t('EmployeesCreateAccountForm.notChoose');
    },
    dateMask() {
      return DateFormat.datetime;
    },
    inputMask() {
      return this.$store.getters['i18N/localeMask'].input + ' ##:##';
    },
  },
  watch: {
    inputData: {
      handler: function (val, oldVal) {
        if (
          val &&
          oldVal &&
          typeof val === 'object' &&
          typeof oldVal === 'object' &&
          JSON.stringify(val) === JSON.stringify(oldVal)
        ) {
          return;
        }
        if (val) {
          this.accountId = v4();
          if (typeof val === 'object' && val.structure) {
            if (val.structure?.value && !this.haveScopeToChangeOrg) {
              this.organizationName = val.structure.value.fullname;
              this.organizationId = val.structure.value.id;
            }

            if (this.readonly && val.accountDataForStepper) {
              this.label = val.accountDataForStepper.label;
              this.organizationName =
                val.accountDataForStepper.organizationName;
              this.regionName = val.accountDataForStepper.regionName;
              this.position = val.accountDataForStepper.position;
            }

            if (val.isEditProcess) {
              if (val.account) {
                this.accountId = val.account.id;
                this.modified = val.account.modified;
                this.disabled = !val.account.enabled;
                this.startDateTime = convertDateFromBackendFormat(
                  val.account.start,
                  this.dateMask
                );
                this.endDateTime = convertDateFromBackendFormat(
                  val.account.finish,
                  this.dateMask
                );
                this.position = val.account.position;
                if (val.account['user-domain']) {
                  this.selected = val.account['user-domain'].id || '';
                }
              }
              if (val.structure.value && this.haveScopeToChangeOrg) {
                const schema = val.structure.value.schema;
                switch (schema) {
                  case ORGANIZATION:
                    this.organizations.selected = {
                      id: val.structure.value.id,
                      fullname: val.structure.value.fullname,
                    };
                    break;
                  case DEPARTMENT:
                    this.setDepartments(val.structure.value.id);
                    break;
                  case REGION:
                    this.regions.selected = {
                      id: val.structure.value.id,
                      fullname: val.structure.value.fullname,
                    };
                    break;
                }
              }
            }
          }
        }
      },
      immediate: true,
    },
    selected: {
      handler: function (val) {
        if (val) {
          this.initLabel();
          this.getDepartments(val);
        } else {
          this.selectDepartment = null;
          this.departments = [];
        }
      },
      immediate: true,
    },
    dateMask: {
      handler: function (currentValue, oldValue) {
        if (this.startDateTime) {
          this.startDateTime = convertDateFormat(
            this.startDateTime,
            oldValue,
            currentValue
          );
        }
        if (this.endDateTime) {
          this.endDateTime = convertDateFormat(
            this.endDateTime,
            oldValue,
            currentValue
          );
        }
      },
    },
  },
  methods: {
    async setDepartments(id: string): void {
      const parent = await this.getDepartmentParent(id);
      this.selected = parent.id;
      this.organizations.selected = {
        id: parent.id,
        fullname: parent.fullname,
      };
      this.selectDepartment = this.inputData?.structure?.value;
    },

    async getDepartmentParent(id: string) {
      const response = await departmentApi
        .getDepartment(id, 'parent')
        .catch((e) => {
          notifyError(e.toString());
        });
      return response.data.parent;
    },

    async getDepartments(parentId: string): void {
      if (parentId) {
        const response = await linksApiIdm
          .searchLinks(ORGANIZATION, parentId, DEPARTMENT)
          .catch((e) => {
            notifyError(e.toString());
          });
        this.departments = response.data;
      }
    },
    submit(e) {
      this.$emit('submit', e, this.outputData);
    },
    getNodeByKeyRecursive(val, nodes) {
      let targetNode = null;

      if (val && nodes.length) {
        for (const node of nodes) {
          if (node.id === val) {
            targetNode = node;
          } else if (node.children && node.children.length) {
            targetNode = this.getNodeByKeyRecursive(val, node.children);
          }

          if (targetNode) break;
        }
      }
      return targetNode;
    },
    initLabel() {
      const node = this.getNodeByKeyRecursive(this.selected, this.departments);

      this.label = node ? node.label : '';
    },
    getOrganizations() {
      return new Promise((resolve) => {
        this.organizations.loading = true;
        const arrQuery = [
          this.organizations.search
            ? `(fullname=searchphrase='${this.organizations.search}' or inn=searchphrase='${this.organizations.search}' or ogrn=searchphrase='${this.organizations.search}')`
            : null,
        ];
        const currentQuery = arrQuery
          .filter((filter) => !!filter)
          .join(' and ');

        this.$store
          .dispatch('idm/organizations/dispatchOrganizations', {
            page: this.organizations.nextPage,
            perPage: this.organizations.pageSize,
            fulltext: currentQuery,
          })
          .then((data) => {
            resolve(data);
          });
      });
    },
    getRegions() {
      return new Promise((resolve) => {
        this.regions.loading = true;
        const arrQuery = [
          this.regions.search
            ? `(fullname=searchphrase='${this.regions.search}' or name=searchphrase='${this.regions.search}')`
            : null,
        ];
        const currentQuery = arrQuery
          .filter((filter) => !!filter)
          .join(' and ');

        regionApi
          .pagingRegions(
            undefined,
            this.regions.nextPage,
            this.regions.pageSize,
            undefined,
            currentQuery
          )
          .then(({ data }) => resolve(data.records))
          .catch(() => {
            throw new Error('[components][forms][EmployeesCreateAccountForm]');
          })
          .finally(() => {
            this.regions.loading = false;
          });
      });
    },
    setOrganization(val) {
      if (val) {
        this.organizationName = val.fullname || '';
        this.regions.selected = null;
        this.organizationId = val.id || '';
        this.selected = val.id || '';
      } else {
        this.organizationName = '';
        this.selected = '';
      }
    },
    setRegion(val) {
      if (val) {
        this.regionName = val.fullname || '';
        this.organizations.selected = null;
        this.selected = '';
        this.label = '';
      } else {
        this.regionName = '';
      }
    },
  },
};
</script>
