<template>
  <select-base
    :options="employeeFilterOptions"
    :loading="loading"
    :disable="disable || disabled"
    v-bind="$attrs"
    use-input="10"
    option-value="id"
    option-label="fullname"
    v-on="$listeners"
  />
</template>

<script lang="ts">
import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
import { oidcClientComputed } from '@state/modules/oidc-client';
import map from 'lodash/map';
import { getNameStrings } from '../utils';
import { ReportAccount } from '../reports';
import SelectBase from './select-base.vue';
import sortBy from 'lodash/sortBy';
import { AccountApi, GraphApi } from '@openapi/idm';
import { notifyError } from '@utils/notify';

const accountApi = new AccountApi();
const graphApi = new GraphApi();

type ReportAccountOption = ReportAccount | { separator: true };

@Component({
  inheritAttrs: false,
  components: {
    SelectBase,
  },
})
export default class SelectAccounts extends Vue.extend({
  computed: {
    ...oidcClientComputed,
  },
}) {
  @Prop() protected organizations: string[];
  @Prop({ type: Boolean }) disable: boolean;

  protected get userid(): string {
    return this.currentUser.sub;
  }

  protected options: any[] = [];
  protected loading = false;
  protected disabled = true;

  protected get employeeFilterOptions(): ReportAccountOption[] {
    const employees: ReportAccountOption[] = [];

    this.options.forEach((employee) => {
      const { surname, firstname, middlename } = employee.person || {};

      employee = {
        ...employee,
        ...getNameStrings(firstname, middlename, surname),
      };

      if (employee.id !== this.userid) {
        employees.push(employee);
      } else {
        employees.unshift(employee, {
          separator: true,
        });
      }
    });

    return employees;
  }

  protected last = 0;

  @Watch('organizations', { immediate: true, deep: true })
  protected async organizationsUpdtae(
    organizations: any[] | 'all'
  ): Promise<void> {
    this.$emit('input', []); // todo сделть сложную обраюотку изменения доступных регионов

    if (organizations !== 'all') {
      if (!organizations || !organizations.length) {
        this.options = [];
        this.disabled = true;

        return;
      }
      if (typeof organizations[0] !== 'string') {
        organizations = map(organizations, 'id');
      }
    }

    this.disabled = false;
    this.loading = true;
    const last = ++this.last;

    let options = await (organizations === 'all'
      ? accountApi
          .searchAccounts(undefined, undefined, undefined, undefined, 'person')
          .then(({ data }) => data)
          .catch(() => {
            throw new Error(
              '[components][reports][components][select-accounts][searchAccounts]'
            );
          })
      : graphApi
          .flatten(
            'Organization',
            'incoming',
            organizations,
            1,
            ['Account'],
            undefined,
            ['Account:person']
          )
          .then(({ data }) => data)
    )
      // @ts-ignore
      .catch((e) => {
      notifyError(e.message.toString());

      return [];
    });
    
    options = sortBy(options, (el: any) => {
      const { surname, firstname, middlename } = el.person || {};
      const fio = getNameStrings(firstname, middlename, surname);
      return fio.fullname.toLowerCase().trim();
    });

    if (this.last === last) {
      this.options = options;
      if (!options.length) {
        this.disabled = true;
      }
    }
    this.loading = false;
  }
}
</script>
