/* eslint-disable @typescript-eslint/ban-ts-comment */
import get from 'lodash/get';
import { Component, Mixins, Prop, Vue, Watch } from 'vue-property-decorator';
import { oidcClientComputed } from '@state/modules/oidc-client';
import QColumn from '@/types/QColumn';
import { pushRoute } from '@utils/routes';
import { EnvOchnVisibility } from '@constants/types/env';
import { notifyError } from '@utils/notify';
import { ServiceApi } from '@openapi/registry-service';
import { USER_SCOPES } from '@constants/entities/Scope';
import { DocumentApi } from '@openapi/document-registry';
import SearchQuery from '@interfaces/entities/SearchQuery';
import { DocumentModel } from '@interfaces/base/DocumentModel';

const documentApi = new DocumentApi();

const statements = Vue.extend({
  computed: {
    ...oidcClientComputed,
  },
});

const serviceApi = new ServiceApi();

@Component({})
export default class StatementDrafts extends Mixins(statements) {
  @Prop() searchQuery: StatementsSearchQuery | undefined;

  private sortByDefault = 'modified';

  model: DocumentModel = {
    loading: false,
    onlyMy: 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,
    },
    records: [],
  };

  services: any[] = [];

  private queryString = '';
  private fulltextString = '';
  private fullQuery = '';
  private pending = 0;

  @Watch('statementsRowsNumber', {
    immediate: true,
  })
  private statementsRowsNumberHandler(val: number): void {
    this.model.pagination.rowsNumber = val;
  }

  private get showPersonalReception(): boolean {
    if (
      String(process.env.VUE_APP_OCHN_PRIEM_VISIBILITY) in EnvOchnVisibility
    ) {
      switch (process.env.VUE_APP_OCHN_PRIEM_VISIBILITY) {
        case EnvOchnVisibility.VISIBLE_FOR_ALL:
          return true;
        case EnvOchnVisibility.VISIBLE_FOR_ROLE_BEARERS:
          return this.$AC.haveScope(USER_SCOPES.PERSONAL_RECEPTION);
      }
    }
    return false;
  }

  private get columns(): QColumn[] {
    const columns = [
      {
        align: 'left',
        field: (val: any) => val,
        formatField: 'model.orderId',
        label: this.$t('statements.regNumber'),
        name: 'model.orderId',
        required: true,
        sortable: true,
      },
      {
        align: 'left',
        field: (val: any) => ({
          label:
            this.services.find((s) => s.name === val.statementType)
              ?.shortName || val.statementType,
          row: val,
        }),
        formatField: 'label',
        label: this.$t('statements.serviceType'),
        name: 'system.service',
        required: true,
        sortable: true,
        style: 'white-space: normal;',
        handlerField: 'row.id',
        handler: (uuid: string, options: any) => {
          pushRoute(
            this.$router,
            {
              name: 'from-draft',
              params: {
                id: uuid,
              },
            },
            options?.targetBlank
          );
        },
      },
      {
        align: 'left',
        field: 'model.currentDate',
        format: (val: any) => {
          if (val) {
            return val;
          }
          return '';
        },
        label: this.$t('statements.dateCreate'),
        name: 'model.currentDate',
        required: true,
        sortable: true,
      },
    ];

    return columns;
  }

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

  private get orgIdQuery(): string {
    return `orgId==${this.currentUser.domain_id}`;
  }

  private goTo(path: string) {
    this.$router.push({
      name: path,
    });
  }

  async created() {
    await this.$store.dispatch(
      'registryService/referenceBooks/initReferenceBooks',
      [
        {
          force: true,
          id: 'gpzu_2_application_status',
        },
      ]
    );

    this.services = await serviceApi
      .searchService()
      .then(({ data }) => {
        return data || [];
      })
      .catch(() => []);

    this.init();
  }

  @Watch('model.onlyMy')
  protected updateOnlyMy() {
    this.fetch();
  }

  private async fetch(q?: SearchQuery) {
    const prevQuery = this.fullQuery;
    const prevFulltext = this.fulltextString;
    const query = [this.orgIdQuery];
    if (typeof q !== 'undefined') {
      this.queryString = q?.query || '';
      this.fulltextString = q?.fulltext || '';
    }

    if (this.queryString) {
      query.push(`${this.queryString}`);
    }

    const assigneeId = this.currentUser.sub;
    if (this.model.onlyMy && assigneeId) {
      query.push(`userId==${assigneeId}`);
    }

    if (this.pending) {
      this.pending++;
      return;
    }
    this.pending = 1;
    this.fullQuery = query.join(' and ');
    this.model.loading = true;

    if (
      !prevQuery ||
      prevQuery !== this.fullQuery ||
      prevFulltext !== this.fulltextString
    ) {
      try {
        const { data: rowsNumber } = await documentApi.countDocuments(
          'ApplicationDrafts',
          this.fullQuery,
          this.fulltextString
        );
        this.model.pagination.rowsNumber = rowsNumber || 0;
      } catch (e) {
        notifyError(e.message.toString());
      }
    }

    try {
      const { data: statementsPaging } = await documentApi.pagingDocuments(
        'ApplicationDrafts',
        this.model.pagination.page,
        this.model.pagination.rowsPerPage,
        this.fullQuery,
        undefined,
        this.sort
      );
      this.model.records = statementsPaging.records;
    } catch (e) {
      notifyError(e.message.toString());
    } finally {
      this.$store
        .dispatch('registryService/referenceBooks/initReferenceBooks', [
          {
            force: true,
            id: 'gpzu_2_application_status',
          },
        ])
        .finally(() => {
          this.model.loading = false;
        });
    }

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

  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;
    }

    this.fetch();
  }

  private resetPagination(): void {
    this.model.pagination.page = 1;
  }
}

export interface StatementsSearchQuery {
  savedSearch?: boolean;
  onlyMy: boolean;
  status: string;
  daterange: string;
  employees: string;
  page: number;
  organizations: string;
  search: string;
  services: string;
  goals: string;
}
