import get from 'lodash/get';
import { Component, Watch } from 'vue-property-decorator';
import Vue from 'vue';
import { convertDateFromTimestamp } from '@utils/format-date';
import { USER_SCOPES } from '@constants/entities/Scope';
import { pushRoute } from '@utils/routes';
import { RegionApi, Region } from '@openapi/idm';
import { notifyError } from '@utils/notify';

const regionApi = new RegionApi();

@Component({})
export default class Regions extends Vue {
  @Watch('inputSearch')
  private inputSearchHandler(): void {
    this.init();
  }

  private sortByDefault = 'modified';
  USER_SCOPES = USER_SCOPES;

  model = {
    loading: false,
    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,
    },
    regions: [] as Region[],
    visibleColumns: ['name'],
    query: '',
  };

  inputSearch = this.$route.query.search ?? '';

  private get columns() {
    return [
      {
        align: 'left',
        field: (val: any) => val,
        formatField: 'name',
        handler: (row: any, options: any) => {
          pushRoute(
            this.$router,
            {
              name: 'cards',
              params: {
                id: row as string,
                path: 'regions',
              },
              query: {
                active: 'data',
                components: this.$store.getters[
                  'cardComponents/regions/components'
                ],
              },
            },
            options?.targetBlank
          );
        },
        handlerField: 'id',
        label: this.$t('regions.name'),
        name: 'name',
        required: true,
        sortable: true,
      },
      {
        align: 'left',
        field: 'enabled',
        format: (val: boolean) => {
          if (val) {
            return this.$t('regions.yes');
          }

          return this.$t('regions.no');
        },
        label: this.$t('regions.enabled'),
        name: 'enabled',
        required: true,
        sortable: true,
      },
      {
        align: 'left',
        field: 'code',
        label: this.$t('regions.code'),
        name: 'code',
        required: true,
        sortable: true,
      },
      {
        field: 'modified',
        format: (val: any) => (val ? convertDateFromTimestamp(val) : ''),
        label: this.$t('regions.modified'),
        name: 'modified',
        required: true,
        sortable: true,
      },
    ];
  }

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

  created() {
    this.init();
  }

  private create() {
    this.$router.push({
      name: 'regions-create',
    });
  }

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

  private init(val: any = null): void {
    if (
      get(
        {
          val,
        },
        'val.pagination'
      )
    ) {
      this.model.pagination.descending = val.pagination.descending;
      this.model.pagination.rowsPerPage = val.pagination.rowsPerPage;
      this.model.pagination.page = val.pagination.page;
      this.model.pagination.sortBy =
        val.pagination.sortBy === null
          ? this.sortByDefault
          : val.pagination.sortBy;
    }

    const pagination = {
      sort: '',
    };

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

  private pending = 0;

  private async fetch() {
    if (this.pending) {
      this.pending++;
      return;
    }
    this.pending = 1;

    this.model.loading = true;
    const currentUser = this.$store.getters['oidcClient/currentUser'] || {};

    const arrFulltext: (string | null)[] = [
      this.inputSearch
        ? [
            `fullname=searchprefix="${this.inputSearch}"`,
            `fullname=search="${this.inputSearch}"`,
          ].join(' or ')
        : null,
    ];

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

    try {
      const query = !this.isAdmin ? `id==${currentUser.domain_id}` : undefined;

      const paging = await regionApi
        .pagingRegions(
          undefined,
          this.model.pagination.page,
          this.model.pagination.rowsPerPage,
          query,
          fulltext
        )
        .then(({ data }) => data);

      this.model.pagination.rowsNumber = paging.totalRows ?? 0;
      this.model.regions = paging.records ?? [];
    } catch (e) {
      notifyError(e.message.toString());
    } finally {
      this.model.loading = false;
    }

    if (this.pending > 1) {
      this.pending = 0;
      await this.fetch();
      return;
    }
    this.pending = 0;
  }

  get isAdmin() {
    return this.$AC.haveScope(USER_SCOPES.CLOUD_ADMIN);
  }
}
