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

<script lang="ts">
import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
import SelectBase from './select-base.vue';
import { CollapsedProfileApi } from '@openapi/idm';
import {
  Organization,
  ServiceApi,
  OrganizationApi,
  OrganizationForStats,
  ServiceForStats,
} from '@openapi/registry-service';
import sortBy from 'lodash/sortBy';
import { notifyError } from '@utils/notify';

const serviceApi = new ServiceApi();
const organizationApi = new OrganizationApi();
const collapsedProfileApi = new CollapsedProfileApi();

@Component({
  inheritAttrs: false,
  components: { SelectBase },
})
export default class SelectServices extends Vue {
  @Prop({ required: true }) organizations: Organization[];
  @Prop({ required: true }) role: reportAccessScope;

  protected options: ServiceForStats[] | [] = [];
  protected loading = false;
  protected allServices: ServiceForStats[] | [] = [];
  protected accountServiceIdList: string[] | [] = [];
  protected accountServiceList: ServiceForStats[] | [] = [];

  async mounted(): Promise<void> {
    if (
      this.role === reportAccessScope.observerRF ||
      this.role === reportAccessScope.observerRegion
    ) {
      const currentUser = this.$store.getters['oidcClient/currentUser'].sub;
      const { data } = await collapsedProfileApi.getCollapsedProfileByAccountId(
        currentUser || ''
      );
      this.accountServiceIdList = data.sectionFilters?.services || [];
      await this.fetchAllServices();
      this.accountServiceList = this.allServices.filter((e: ServiceForStats) =>
        this.accountServiceIdList.includes(e.id as never)
      );
    }
  }

  @Watch('organizations', { immediate: true, deep: true })
  protected async organizationsUpdate(
    organizations: Organization[],
    oldValue: Organization[] | []
  ): Promise<void> {
    if (oldValue?.length && !organizations.length) {
      this.$emit('input', []);
      this.options = [];
    }
    this.loading = true;
    if (!organizations?.length 
      && this.role !== reportAccessScope.observerRF
      && this.role !== reportAccessScope.observerRegion
    ) {
      this.options = [];
      return;
    }  else if (!organizations?.length && (this.role === reportAccessScope.observerRF || this.role === reportAccessScope.observerRegion)
    ) {
      await this.fetchAllServices();
      this.accountServiceList = this.allServices.filter((e: ServiceForStats) => this.accountServiceIdList.includes(e.id as never));
      const fetchOptions = await this.fetchAllServices() as ServiceForStats[];
      this.options = this.filterService(this.accountServiceList.length ? this.accountServiceList : fetchOptions);
      this.loading = false
      return;
    }
    const query = organizations.map(org => org.id);
    const orgs = await organizationApi
      .searchOrganizationForStats(query)
      .then(({ data }) => {
        return (data as OrganizationForStats[]) || [];
      })
      .catch((e) => {
        notifyError(e.message.toString());
        return [];
      });
    const services: ServiceForStats[] = [];
    orgs.forEach((org: OrganizationForStats) => {
      org.services && services.push(...org.services)
    });
    if (this.accountServiceList.length) {
      const mappedWithAllServices = services.filter((e: ServiceForStats) =>
        this.accountServiceIdList.includes(e.id as never)
      );
      this.options = this.filterService(mappedWithAllServices);
    } else {
      this.options = this.filterService(services);
    }
    this.loading = false;
  }

  protected async fetchAllServices() {
    if (this.allServices.length) {
      return this.allServices;
    } else {
      const fetchOptions = await serviceApi
        .searchServiceForStats()
        .then(({ data }) => {
          return data || [];
        })
        .catch((e) => {
          notifyError(e.message.toString());
          return [];
        });
      this.allServices = fetchOptions;
      return this.allServices;
    }
  }

  protected filterService(services: ServiceForStats[]): ServiceForStats[] {
    const filterServices = services.reduce(
      (acc: ServiceForStats[], service: ServiceForStats) => {
        if (acc.find((el) => el.targetId === service.targetId)) return acc;
        if (service.targetId && service.shortNameStat) {
          return [...acc, service];
        }
        return acc;
      },
      []
    );
    return sortBy(filterServices, (el) =>
      el.shortNameStat?.toLowerCase().trim()
    );
  }
}

enum reportAccessScope {
  observerRF = 'observerRF',
  observerRegion = 'observerRegion',
  observerOrganization = 'observerOrganization',
  // observerDepartment = 'observerDepartment',
}
</script>
