import {
  Component,
  Watch,
  Mixins,
  ProvideReactive,
} from 'vue-property-decorator';
import { oidc } from './utils/mixins';
import { Person, Account, PersonApi, AccountApi } from '@openapi/idm';

import ProfileHeader from './components/header.vue';
import ProfileInfo from './components/info.vue';
import ProfileAccounts from './components/accounts.vue';
import { personInjectionKey, accountsInjectionKey } from './utils/keys';
import { ComputedAccount } from './utils/types';
import get from 'lodash/get';

const personApi = new PersonApi();
const accountApi = new AccountApi();

@Component({
  components: {
    ProfileHeader,
    ProfileInfo,
    ProfileAccounts,
  },
})
export default class Profile extends Mixins(oidc) {
  /* Данные компонента */
  error: string | null = null;
  isLoading = false;

  /* Запрос данных о персоне */
  @ProvideReactive(personInjectionKey)
  person: Person | null = null;

  /* Запрос данных об аккаунтах */
  @ProvideReactive(accountsInjectionKey)
  accounts: ComputedAccount[] = [];

  requestPerson(): Promise<Person | void> {
    return personApi
      .getPerson(this.currentUser.person_id)
      .then(({ data }) => {
        this.person = data;
        return data;
      })
      .catch(() => {
        this.error = 'Неудалось получить данные Персоны';

        throw new Error('[components][profile][index][personApi]');
      });
  }

  /* Выбор активного аккаунта */
  // @ProvideReactive(activeAccountInjectionKey)
  // activeAccount: ComputedAccount | null = null;

  /**
   * Запрос списка аккаунтов
   */
  requestAccounts(): Promise<void> {
    return personApi
      .getPersonAccountsByPersonId(this.currentUser.person_id)
      .then(({ data }) => {
        // @ts-ignore IDM
        this.accounts = data.map((account: Account) => ({
          id: account.id,
          account,
          organization: null,
          department: null,
          group: null,
          roles: [],
        }));
      })
      .catch(() => {
        throw new Error('[components][profile][index][personApi]');
      });
  }

  /**
   * Запрос подробных данных об аккаунте
   */
  requestAccountDetail(userId: string): Promise<void> | void {
    const account = this.accounts.find((item) => item.id === userId);

    if (!account) {
      console.warn('Аккаунт с данным ID не найден');
      return;
    }

    return accountApi
      .getAccount(userId, 'user-domain,roles')
      .then(({ data }) => {
        account.roles = get(data, 'roles', []);
        const domain = get(data, 'user-domain', null);
        if (domain.schema === 'Organization') {
          account.organization = domain;
        }
        if (domain.schema === 'Department') {
          account.department = domain;
        }
      })
      .catch(() => {
        this.error = 'Неудалось получить данные сотрудников';

        throw new Error('[components][profile][index][accountApi]');
      });
  }

  /* Действие при смене пользователя */
  @Watch('currentUser', {
    immediate: true,
  })
  async onCurrentUserChange(): Promise<void> {
    this.isLoading = true;
    await this.requestUserData();
    this.isLoading = false;

    // this.setActiveAccount(this.accounts[0]);
  }

  /* Методы */

  /**
   * Загрузка данных пользователя
   */
  async requestUserData(): Promise<void> {
    await this.requestPerson();
    await this.requestAccounts();

    const detailsRequests = this.accounts.map((account) =>
      this.requestAccountDetail(account.id)
    );

    await Promise.allSettled(detailsRequests);
  }

  /**
   * Установить активный аккаунт
   */
  // setActiveAccount(account: ComputedAccount): void {
  //   this.activeAccount = account;
  // }

  /* Геттеры */

  /**
   * Получить название выбранной организации
   */
  // get activeOrganizationName(): string {
  //   return this.activeAccount?.organization?.name || '';
  // }

  // get activeRegionName(): string {
  //   return this.activeAccount?.region?.name || '';
  // }

  /**
   * Получить нзвание депортамента
   */
  // get activeDepartmentName(): string {
  //   return this.activeAccount?.department?.name || '';
  // }

  /**
   * Объеденить роли в строку
   */
  // get activeAccountRolesInString(): string {
  //   const roles = this.activeAccount?.roles
  //     ?.filter((role) => role.ervuRole)
  //     ?.map((role) => role.displayName);
  //   const uniqRoles = new Set(roles || '');
  //   return [...uniqRoles].join(', ');
  // }

  get inputMask(): string {
    return this.$store.getters['i18N/localeMask'].input;
  }
}
