<template>
  <div class="q-pa-md q-gutter-y-md">
    <div
      class="flex justify-between items-center bg-white q-pa-md rounded-borders"
    >
      <div class="column justify-center text-h5" style="min-height: 36px">
        {{ $t('scopes.scopes') }}
      </div>
      <q-btn color="primary" icon="create" :label="$t('scopes.create')" />
    </div>
    <div class="bg-white rounded-borders">
      <BaseTable
        :only-my.sync="filter.onlyMy"
        v-model="inputSearch"
        :show-toggle-my="true"
        :use-search="true"
        :columns="columns"
        :data="scopesRecords"
        :loading="scopesLoading"
        :pagination.sync="filter.pagination"
        :title="$t('scopes.title')"
        :visible-columns="filter.visibleColumns"
        :attributes.sync="attributes"
        @requestTable="init"
        @update="init"
        @query="setQuery"
        saveQuery
      />
    </div>
  </div>
</template>

<script lang="ts">
import { Vue, Component, Prop, Watch } from 'vue-property-decorator';
import { ConditionType } from '@components/common/base-search-bar/index.ts';
import { i18n } from '@plugins/i18n';
import get from 'lodash/get';

@Component({})
export default class Scopes extends Vue {
  @Prop() searchQuery: ScopeSearchQuery;

  @Watch('scopesRowsNumber', {
    immediate: true,
  })
  private scopesRowsNumberHandler(val: number): void {
    this.filter.pagination.rowsNumber = val;
  }

  @Watch('filter.onlyMy')
  private onlyMyHandler(): void {
    this.filter.pagination.page = 1;
    this.filter.pagination.rowsNumber = 0;
    this.init();
  }

  @Watch('inputSearch')
  private inputSearchHandler(): void {
    this.init();
  }

  private sortByDefault = 'modified';

  filter = {
    pagination: {
      descending:
        this.$route.query.descending === undefined
          ? true
          : this.$route.query.descending === 'true',
      rowsPerPage: this.$route.query.rowsPerPage
        ? Number(this.$route.query.rowsPerPage)
        : 10,
      sortBy: this.$route.query.sortBy
        ? this.$route.query.sortBy
        : this.sortByDefault,
      rowsNumber: 0,
      page: this.$route.query.page ? Number(this.$route.query.page) : 1,
    },
    visibleColumns: ['name'],
    // @ts-ignore
    onlyMy: this.searchQuery?.onlyMy,
    query: '',
  };

  // @ts-ignore
  inputSearch = this.searchQuery.search ?? '';

  attributes = [
    {
      attribute: 'description',
      attributeName: i18n.t('scopes.description'),
      conditionType: ConditionType.string,
      value: '',
    },
  ];

  private get columns() {
    return [
      {
        align: 'left',
        field: (val: any) => val,
        formatField: 'name',
        handler: (id: any) => {
          this.$router.push({
            name: 'cards',
            params: {
              id,
              path: 'scopes',
            },
            query: {
              active: 'basic',
              components: this.$store.getters[
                'cardComponents/scopes/components'
              ],
            },
          });
        },
        handlerField: 'id',
        label: this.$t('scopes.name'),
        name: 'name',
        required: true,
        sortable: true,
      },
      {
        align: 'left',
        field: 'description',
        label: this.$t('scopes.description'),
        name: 'description',
        required: true,
        sortable: true,
      },
    ];
  }

  private get sort(): string {
    return `${this.filter.pagination.descending ? '-' : '+'}${
      this.filter.pagination.sortBy
    }`;
  }

  created() {
    if (!this.$route.query.filter) {
      this.init();
    }
  }

  private setQuery(q?: string) {
    this.filter.query = q || '';
    this.init();
  }

  private async init(val?: any): Promise<void> {
    if (val?.pagination) {
      this.filter.pagination.descending = val.pagination.descending;
      this.filter.pagination.page = val.pagination.page;
      this.filter.pagination.rowsPerPage = val.pagination.rowsPerPage;
      this.filter.pagination.sortBy =
        val.pagination.sortBy === null
          ? this.sortByDefault
          : val.pagination.sortBy;
    }

    const pagination = {
      page: this.filter.pagination.page,
      rowsPerPage: this.filter.pagination.rowsPerPage,
      sort: '',
    };

    if (this.sort) {
      pagination.sort = this.sort;
    }

    const arrFulltext = [
      this.inputSearch ? `name=searchprefix='${this.inputSearch}'` : null,
    ];

    const fulltext = arrFulltext
      .filter((filter: string | null) => !!filter)
      .join(' and ');

    const arrQuery = [
      this.filter.query,
      get({ model: this.filter }, 'model.onlyMy') ? 'own_type==my' : null,
    ];

    const currentQuery = arrQuery
      .filter((filter: string | null) => !!filter)
      .join(' and ');

    const scopes = await this.$store.dispatch('idm/scopes/dispatchScopes', {
      page: pagination.page,
      perPage: pagination.rowsPerPage,
      query: currentQuery,
      fulltext: fulltext,
      sort: pagination.sort,
      expand: 'roles',
    });

    this.filter.pagination.rowsNumber = scopes.totalRows;
  }

  private get scopesRecords() {
    return this.$store.getters['idm/scopes/scopesRecords'];
  }

  private get scopesLoading() {
    return this.$store.getters['idm/scopes/scopesLoading'];
  }

  private get scopesRowsNumber() {
    return this.$store.getters['idm/scopes/scopesRowsNumber'];
  }
}

export interface ScopeSearchQuery {
  onlyMy: boolean;
  search: string;
}
</script>
