<template>
  <Centered1280Box class="AccountRoles">
    <WhiteCard class="AccountRoles__WhiteCard">
      <div class="AccountRoles__Header">
        <div class="AccountRoles__HeaderText">Назначенные роли</div>
        <r-btn
          v-if="visibleButton"
          action
          label="Редактировать"
          @click="editingAccount = data"
        />
      </div>
      <q-skeleton v-if="loading || loadingRoles" style="width: 50%" />
      <q-tree v-else-if="tree" :nodes="tree" node-key="id" default-expand-all />
      <div v-else>Роли не найдены</div>
    </WhiteCard>
    <EditModal
      :account="editingAccount"
      @close="editingAccount = null"
      @refresh="updateAccountData"
    />
  </Centered1280Box>
</template>

<script lang="ts">
import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
import { LinksApi, Role, Organization, DepartmentApi } from '@openapi/idm';
import { Account } from '@interfaces/entities/Account';
import { notifyError } from '@utils/notify';
import { getTreeConfig, RoleTreeCode } from '@constants/RoleTreeTypes';
import Centered1280Box from '@/recruits/components/common/centered-1280-box.vue';
import WhiteCard from '@/recruits/components/common/white-card.vue';
import { DepartmentWithParent } from '@models/DepartmentWithParent';
import EditModal from './EditModal.vue';

const linksApi = new LinksApi();
const departmentApi = new DepartmentApi();

const DEPARTMENT = 'Department';

interface ExtendedRole extends Role {
  label?: string;
}

interface Solution {
  id: string;
  modified: number;
  schema: string;
  name: string;
  displayName: string;
  shortname: string;
  description: string;
  roles: ExtendedRole[];
}

@Component({
  components: {
    Centered1280Box,
    WhiteCard,
    EditModal,
  },
  props: ['data', 'loading'],
})
export default class AccountRolesCard extends Vue {
  @Prop({}) private data: Account;
  @Prop({}) private loading: boolean;
  private loadingRoles = true;
  private roles: Array<Role> = [];
  private solutions: Array<Solution> = [];
  private tree: any = null;

  private parent: Organization | null = null;

  private get visibleButton(): boolean {
    return this.$AC.haveScope(this.$AC.scopes.SECURITY_ADMINISTRATOR);
  }

  private async getDepartmentParent(id: string): Promise<void> {
    const response = await departmentApi.getDepartment(id, 'parent');
    const data = response?.data as DepartmentWithParent;
    this.parent = data.parent ?? null;
  }

  private get organizationId(): string {
    return this.parent?.id || this.data?.userDomain?.id || '';
  }

  @Watch('data', {
    immediate: true,
  })
  async dataWatcher(val: Account): Promise<void> {
    this.loadingRoles = true;
    if (val?.roles) {
      this.roles = val.roles;
    }
    if (val?.userDomain?.id) {
      if (val?.userDomain.schema === DEPARTMENT) {
        await this.getDepartmentParent(val.userDomain.id);
      }
      await this.getSolutions(this.organizationId);
      this.mappingTree(this.solutions);
    }
    this.loadingRoles = false;
  }

  private async getSolutions(id: string): Promise<void> {
    try {
      const { data: response } = await linksApi.searchLinks(
        'Organization',
        id,
        'Solution',
        undefined,
        undefined,
        'roles'
      );

      this.solutions = (response ?? []) as Solution[];
    } catch (e: any) {
      notifyError(e);
    }
  }

  private filterTree(tree: any) {
    if (!tree.children.some((item: any) => item.children.length)) {
      return '';
    } else {
      tree.children = tree.children.filter((item: any) => item.children.length);
      return tree;
    }
  }

  private mappingTree(data: Array<Solution>): void {
    this.tree = data.map((item) => {
      // keep 'name' for Solutions
      const tree = getTreeConfig(item.id, item.displayName || item.name);

      for (const role of item.roles || []) {
        if (role.ervuRole && this.roles.some((el) => el.id === role.id)) {
          role.label = role.displayName;

          tree.children
            .find((child: any) => child.code === RoleTreeCode.EMPLOYEES)
            .children.push(role);
        }
      }
      return this.filterTree(tree);
    });
  }

  editingAccount: null | Account = null;

  updateAccountData(): void {
    this.editingAccount = null;
    this.$emit('refresh');
  }
}
</script>

<style lang="scss" scoped>
.AccountRoles {
  &__WhiteCard {
    padding: 12px 16px;
    margin-bottom: 16px;
  }
  &__Header {
    padding-bottom: 12px;
    margin-bottom: 20px;
    border-bottom: 1px solid rgba(1, 72, 116, 0.11);
    display: flex;
    justify-content: space-between;
    align-items: center;
  }

  &__HeaderText {
    font-family: 'Golos UI', 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);
  }
}
</style>
