<template>
  <Centered1280Box class="OrganizationAccounts">
    <WhiteCard class="OrganizationAccounts__WhiteCard">
      <div class="OrganizationAccounts__Header">Сотрудники</div>
      <div>
        <search-bar
          v-model="filter"
          :loading="loading"
          @search="executeSearch"
        />
        <sort-bar
          v-model="sortButtons"
          :pagination="pagination"
          :loading="loading"
          @click="handleSortClick"
        />
        <re-table
          :data="accounts"
          :columns="columns"
          :loading="loading"
          :pagination.sync="pagination"
          :rows-per-page-options="[5, 10, 25, 50, 100]"
          @request="onRequest"
        >
          <template v-slot:body-item-roles="props">
            <r-btn label="Показать" @click="showModalRoles(props.row)" />
          </template>
        </re-table>
        <RolesModal :openedAccount="openedAccount" @close="closeRoles()" />
      </div>
    </WhiteCard>
  </Centered1280Box>
</template>

<script lang="ts">
import { Component, Mixins } from 'vue-property-decorator';
import { AccountApi, AccountPersonSingleTO } from '@openapi/idm';
import { notifyError } from '@utils/notify';
import { RTableColumn } from '@/interfaces';
import SearchBar from './Accounts/SearchBar.vue';
import { SSOServiceApi, AccountsSessionCountBodyV1 } from '@openapi/sso';
import ReTable from '@/recruits/components/common/r-table/index.vue';
import SortBar from '@/recruits/components/common/sort-bar.vue';
import Centered1280Box from '@/recruits/components/common/centered-1280-box.vue';
import WhiteCard from '@/recruits/components/common/white-card.vue';
import RolesModal from './Accounts/RolesModal.vue';
import UrlIntegratedSearch from '@/recruits/mixins/url-integrated-search';
import { SearchFilter, UrlQueryParams } from '@/recruits/models';
import { prepareApiParams } from '@/recruits/utils/prepare-api-params';

const accountApi = new AccountApi();
const ssoServiceApi = new SSOServiceApi();

interface AccountSearchRecord extends AccountPersonSingleTO {
  sessionsCount?: number;
}

@Component({
  components: {
    SearchBar,
    SortBar,
    ReTable,
    Centered1280Box,
    WhiteCard,
    RolesModal,
  },
})
export default class OrganizationCardAccounts extends Mixins(
  UrlIntegratedSearch
) {
  private accounts: AccountSearchRecord[] = [];

  sortButtons: Array<{ label: string; value: string }> = [
    { label: 'По ФИО', value: 'surname' },
  ];

  public filter = new SearchFilter();

  private sortByDefault = 'modified';

  get columns(): RTableColumn<Array<AccountSearchRecord>>[] {
    return [
      {
        label: 'ФИО',
        name: 'surname',
        field: 'person',
        format: (person: any) => person.fio,
        width: '2fr',
        componentPath: 'link',
        componentOptions: {
          route: 'account',
          routeParams: (person: any) => ({ id: person.id }),
        },
      },
      {
        field: 'domainFullName',
        label: 'Организация',
        name: 'domainFullName',
        width: '2fr',
      },
      {
        field: 'enabled',
        componentPath: 'icon',
        componentOptions: {
          icon: 'block',
          align: 'center',
          iconColor: 'black',
        },
        format: (val) => (val ? '' : 'icon'),
        label: 'Активность',
        name: 'enabled',
      },
      {
        field: 'blocked',
        componentPath: 'icon',
        componentOptions: {
          icon: 'lock',
          align: 'center',
          iconColor: 'black',
        },
        format: (val) => (val ? 'icon' : ''),
        label: 'Блокировка',
        name: 'blocked',
      },
      {
        field: 'sessionsCount',
        format: (val) => {
          return val.toString();
        },
        label: 'Кол-во сессий',
        name: 'sessionsCount',
      },
      {
        field: 'roles',
        label: 'Роли',
        name: 'roles',
      },
    ];
  }

  async fetchData(
    query: UrlQueryParams
  ): Promise<{ totalRows: number | undefined }> {
    // Т.К. fetchData вызывается при каждом обновлении url, то
    // делаем проверку что в данный момент открыт данный таб
    if (this.$route.name !== 'organization-accounts') {
      return { totalRows: undefined };
    }
    const params = prepareApiParams(query);

    // подготавливаем строку для поиска в формате RSQL
    const searchStr = params.search.search?.length
      ? `surname=like=*${
          params.search.search[0].toUpperCase() + params.search.search.slice(1)
        }*`
      : '';

    try {
      const {
        data: response,
      } = await accountApi.findAccountsByOrganizationIdWithPerson(
        this.$route.params.id,
        params.pagination.page,
        params.pagination.rowsPerPage,
        `${params.pagination.descending === 'false' ? '+' : '-'}${
          params.pagination.sortBy || this.sortByDefault
        }`,
        searchStr
      );
      const accounts: AccountSearchRecord[] = response.records || [];

      // получаем список id аккаунтов
      const accountIds: string[] = accounts.map((account) => account.id || '');

      // объект хранящий соотношения id аккаунта к кол-ву сессий
      const sessions: Record<string, number> = {};

      if (accountIds.length) {
        // получаем список соотношения id аккаунта к кол-ву сессий
        const sessionsResponse: AccountsSessionCountBodyV1 = await new Promise(
          (resolve) => {
            ssoServiceApi
              .getAccountsSessionCountV1({ accountIdList: accountIds })
              .then((sessionsResponse) => {
                resolve(sessionsResponse.data);
              })
              .catch(() => {
                resolve({ accountIdList: [] });
              });
          }
        );

        // преобразуем список соотношения id аккаунта к кол-ву сессий в объект
        sessionsResponse.accountIdList?.forEach((accountWithSession) => {
          if (accountWithSession?.accountId) {
            sessions[accountWithSession.accountId] =
              accountWithSession?.count || 0;
          }
        });
      }

      // добавляем кол-во сессий к общей информации аккаунта
      this.accounts = accounts.map((account) => {
        const sessionsCount = account?.id ? sessions[account.id] || 0 : 0;
        return { ...account, sessionsCount };
      });

      return { totalRows: response.totalRows };
    } catch (e: any) {
      notifyError(e.toString());
      return { totalRows: 0 };
    }
  }

  // блок для работы модального окна
  private openedAccount: AccountPersonSingleTO | null = null;

  showModalRoles(row: AccountPersonSingleTO): void {
    this.openedAccount = row;
  }

  closeRoles(): void {
    this.openedAccount = null;
  }
}
</script>

<style lang="scss" scoped>
.OrganizationAccounts {
  &__WhiteCard {
    padding: 12px 16px;
    margin-bottom: 16px;
  }
  &__Header {
    padding-bottom: 12px;
    margin-bottom: 20px;
    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>
