<template>
  <div>
    <select-base
      :options="options"
      :loading="loading"
      v-bind="$attrs"
      use-input="10"
      option-value="id"
      option-label="fullname"
      :multiple="false"
      :disable="disable || disabled || (allOrganisations && isSpecialReport)"
      v-on="$listeners"
      @input="onSelectedOrganisation"
    />

    <!-- Запрос к stat-query-rest падает по длинне, замена на post v2 в stat-chart-component 
    не работает так как nginx не пропускает post-ы к статике.
    нужно поменять запросы так чтобы не передавать id всех ведомств. 
    Завёл задачу PGSRUSH-4372

    <q-checkbox
      v-if="isRegionObserver && isSpecialReport && regions.length && options.length"
      class="all_orgs"
      v-model="allOrganisations"
      label="Все организации"
    /> -->
    <div
      v-show="departments.length"
      :class="departments.length && 'block text-left'"
    >
      <select-base
        class="q-pt-sm"
        :options="departments"
        v-model="department"
        label="Выберите подразделение"
        use-input="10"
        :multiple="false"
        option-value="id"
        option-label="fullname"
        :disable="excludeDepartments"
      />
      <q-checkbox
        class="q-mt-sm q-mb-sm"
        v-model="excludeDepartments"
        label="Исключить подразделения"
      />
    </div>
  </div>
</template>

<script lang="ts">
import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
import SelectBase from './select-base.vue';
import {
  DomainApi,
  GraphApi,
  DomainForStats,
  Organization,
} from '@openapi/idm';
import { USER_SCOPES } from '@/constants/entities/Scope';
import { notifyError } from '@utils/notify';
import { cloneDeep } from 'lodash';
import sortBy from 'lodash/sortBy';
import map from 'lodash/map';

const domainApi = new DomainApi();
const graphApi = new GraphApi();

type OrganizationStat = { id: string; shortname: string; fullname: string };

@Component({
  inheritAttrs: false,
  components: {
    SelectBase,
  },
})
export default class SelectOrganizations extends Vue {
  @Prop({ required: true }) regions: string[];
  @Prop({ type: Boolean }) disable: boolean;
  @Prop() isSpecialReport?: boolean;

  protected options: DomainForStats[] | [] = [];
  protected loading = false;
  protected disabled = true;
  protected allOrganisations = false;

  protected last = 0;

  protected value: any = [];
  protected selectedOrganisation: Record<string, unknown> = {};
  hasSubDepartment = true;
  protected department: Record<string, unknown>[] = [];
  protected departments: Record<string, unknown>[] = [];
  protected excludeDepartments = false;

  get isRegionObserver(): boolean {
    return this.$AC.haveOneOfScope([
      USER_SCOPES.REGION_OBSERVER,
      USER_SCOPES.REGION_ADMIN,
      USER_SCOPES.RF_OBSERVER_SCOPE,
      USER_SCOPES.REG_STAT_OBSERVER,
      USER_SCOPES.FED_STAT_OBSERVER,
    ]);
  }

  get departmentConditions() {
    return {
      excludeDepartments: this.excludeDepartments,
      departments: this.department,
    };
  }

  @Watch('regions', { immediate: true, deep: true })
  protected async regionsUpdate(regions: any[] | 'all'): Promise<void> {
    if (
      this.$AC.haveOneOfScope([
        USER_SCOPES.SIGNED_SPECIALIST,
        USER_SCOPES.ORG_STAT_OBSERVER,
      ]) &&
      !this.$AC.haveOneOfScope([
        USER_SCOPES.REGION_OBSERVER,
        USER_SCOPES.REGION_ADMIN,
        USER_SCOPES.RF_OBSERVER_SCOPE,
        USER_SCOPES.FED_STAT_OBSERVER,
        USER_SCOPES.REG_STAT_OBSERVER,
      ])
    ) {
      return;
    }

    this.$emit('input', []); // todo сделть сложную обраюотку изменения доступных регионов

    if (regions !== 'all') {
      if (!regions || !regions.length) {
        this.options = [];
        this.disabled = true;
        return;
      }
      if (typeof regions[0] !== 'string') {
        regions = map(regions, 'id');
      }
    }

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

    let organizations =
      regions !== 'all'
        ? await domainApi
            .pagingDomainsForStats(regions)
            .then((res) => {
              const organizations = (res.data as unknown) as DomainForStats[];
              return organizations
                .flatMap((org) => org.organizations)
                .filter((el) => el);
            })
            .catch((e) => {
              notifyError(e.message.toString());
              return [];
            })
        : [];
    organizations =
      organizations &&
      sortBy(organizations, (el: any) => el.fullname?.toLowerCase().trim());

    if (this.last === last) {
      organizations &&
        organizations.length &&
        (this.options = organizations as DomainForStats[]);
      if (organizations && !organizations.length) {
        notifyError('Организации не найдены');
        this.disabled = true;
      }
    }
    this.loading = false;
  }

  @Watch('allOrganisations')
  setAllOrganisations(value: boolean): void {
    if (value) {
      this.$emit('allOrganisations', value, this.options);
    } else {
      this.$emit('allOrganisations', value);
    }
  }

  @Watch('regions')
  setRegions(): void {
    this.allOrganisations = false;
    this.departments = [];
  }

  @Watch('isSpecialReport')
  resetAllOrganisations(value: boolean): void {
    if (!value) {
      this.allOrganisations = false;
    }
  }

  @Watch('departmentConditions', { immediate: true })
  protected setDepartment( conditions: Record<string, unknown> ): void {
    this.$emit('departmentConditions', conditions);
  }

  @Watch('excludeDepartments', { immediate: true })
  protected isDepartments(): void {
    this.department = [];
  }

  async onSelectedOrganisation(organizations: Organization[]) {
    this.department = [];
    this.departments = [];
    this.excludeDepartments = false;
    const organizationId = organizations[0].id;
    this.loading = true;

    const departments = (await graphApi
      .flatten('Organization', 'incoming', [organizationId], 6, ['Department'])
      .then(({ data }) => data)) as OrganizationStat[];

    this.loading = false;

    this.departments = cloneDeep(departments)
      .filter((org) => org.id !== organizationId)
      .map((org) => ({
        id: org.id,
        shortname: org.shortname,
        fullname: org.fullname,
      }));
  }
}
</script>
<style lang="sass">
.all_orgs.row.inline
  display: flex
</style>
