<template>
  <div class="EditModalForm">
    <q-inner-loading :showing="loading">
      <q-spinner-gears color="primary" size="50px" />
    </q-inner-loading>
    <template v-if="!loading">
      <q-tree
        v-if="solutions.length"
        :nodes="solutions"
        node-key="id"
        tick-strategy="leaf"
        :ticked.sync="rolesList"
        default-expand-all
      />
      <div v-else>Нет ролей</div>
      <div class="EditModalForm__Separate"></div>
      <div class="EditModalForm__Field">
        <div class="EditModalForm__FieldLabel EditModalForm__FieldLabel_Big">
          Назначенные роли
        </div>
        <div v-for="(tick, i) in ticked" :key="`ticked-${tick}-${i}`">
          {{ tick }}
        </div>
      </div>
    </template>
  </div>
</template>

<script lang="ts">
import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
import { AccountRolesData } from '@/recruits/components/accounts/utils/types';
import { Role, SolutionApi, Solution } from '@openapi/idm';
import { notifyError } from '@utils/notify';

const solutionApi = new SolutionApi();

interface SolutionWithChildrenRole extends Solution {
  children?: RoleWithLabel[];
  roles?: Role[];
  ervuSolution?: boolean;
}

interface RoleWithLabel extends Role {
  label: string;
}

@Component({})
export default class AccountRolesForm extends Vue {
  @Prop({ default: () => [] }) userRolesIds: string[];
  @Prop({}) submitFunction: (accountRolesData: AccountRolesData) => void;
  @Prop({ default: 0 }) triggerSubmit: number;

  solutions: SolutionWithChildrenRole[] = [];
  rolesList: string[] = [];
  loading = false;

  mounted(): void {
    if (this.userRolesIds) {
      this.rolesList = [...this.userRolesIds];
    }
    this.getRoles();
  }

  async getRoles(): Promise<void> {
    this.loading = true;
    try {
      // Тут ts-ignore т.к. запрос по openApi возвращает Solution[], но т.к. при запросе мы указываем
      // expand roles, поэтому возврашается расширенный объект
      // @ts-ignore
      const {
        data,
      }: {
        data: SolutionWithChildrenRole[];
      } = await solutionApi.getAllSolutions(
        'ervuSolution==true',
        undefined,
        undefined,
        'roles'
      );

      const solutionsErvu =
        data.filter((solution) => solution.ervuSolution && solution.roles) ||
        [];

      this.solutions = solutionsErvu.map((solution) => {
        return {
          ...solution,
          label: solution.shortname || '',
          children: solution.roles?.map((role) => {
            return {
              ...role,
              label: role.displayName || role.shortname || '',
            };
          }),
        };
      });
    } catch (e: any) {
      notifyError(e);
    } finally {
      this.loading = false;
    }
  }

  /**
   * Свойство для получения названий активных ролей
   * @return {string[]}
   */
  get ticked(): string[] {
    const rolesInSolutions = this.solutions.flatMap(
      (solution) => solution.children || []
    );

    return this.rolesList.map((roleId) => {
      const role = rolesInSolutions.find((role) => role.id === roleId);
      return role?.displayName || role?.shortname || '';
    });
  }

  @Watch('triggerSubmit')
  private triggerSubmitHandler(): void {
    this.submitFunction({
      rolesList: this.rolesList.filter(
        (roleId) => !this.userRolesIds?.includes(roleId)
      ),
      removeRoles:
        this.userRolesIds?.filter(
          (roleId) => !this.rolesList.includes(roleId)
        ) || [],
    });
  }
}
</script>

<style lang="scss" scoped>
.EditModalForm {
  display: grid;
  grid-template-columns: calc(50% - 16px) 1px calc(50% - 16px);
  gap: 16px;
  &__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;

    &_Big {
      font-size: 16px;
      line-height: 24px;
    }
  }

  &__Separate {
    height: 100%;
    width: 1px;
    background-color: rgba(0, 0, 0, 0.12);
  }

  &__Field {
    margin-bottom: 15px;
  }
}
</style>
