import Vue from 'vue';
import Axios from 'axios';
import { Component, Prop } from 'vue-property-decorator';
import PersonalAccountsSearchBar from './components/search-bar.vue';
import isEmpty from 'lodash/isEmpty';
import {
  Person,
  PersonalAccountApi,
} from '@openapi/personal-accounts';
import { notifyError, notifySuccess } from '@/utils/notify';
import { pushRoute } from '@utils/routes';

import type { TableColumn, TableColumnOptions } from '@/interfaces';
import type { TablePagination } from '@/models/base/TablePagination';
import { USER_SCOPES } from '@/constants/entities/Scope';
import { deletePersonalAccounts } from '@/services/personal-accounts';
import { convertDateFormat, DateFormat } from '@/utils/format-date';

const personalAccountApi = new PersonalAccountApi();

import type { SearchData, PersonalAccountsTableModel } from '@models/personal-accounts';

@Component({
  components: {
    PersonalAccountsSearchBar,
  },
})
export default class PersonalAccounts extends Vue {
  @Prop() searchQuery: SearchData;

  model: PersonalAccountsTableModel = {
    search: '',
    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
        : 'modified',
      rowsNumber: 0,
      page: this.$route.query.page ? Number(this.$route.query.page) : 1,
    },
    searchData: {
      // Номер заявления
      applicationNum: '',
      // Номр решения
      solutionNum: '',
  
      // Контакт
      phone: '',
      email: '',
  
      // Номер документа
      series: '',
      number: '',
      documentType: '',
  
      // Адрес
      address: '',
  
      snils: '',
      inn: '',
      birthday: '',
      fullName: '',
    },
    personalAccounts: [],
  };

  sortByDefault = 'modified';

  selected: Person[] = [];

  visibleColumns: string[] = ['fullName'];

  get columns(): TableColumn<Person>[] {
    return [
      {
        align: 'left',
        field: (i) => i,
        handler: this.goToPersonCard,
        label: this.$t('personalAccounts.fullName'),
        formatField: 'fullName',
        name: 'fullName',
        style: 'white-space: normal;',
        required: true,
        sortable: true,
      },
      {
        align: 'left',
        label: this.$t('personalAccounts.birthday'),
        field: 'birthday',
        name: 'birthday',
        required: true,
        sortable: true,
      },
      {
        align: 'left',
        label: this.$t('personalAccounts.snils'),
        field: 'snils',
        name: 'snils',
        required: true,
        sortable: true,
      },
      {
        align: 'left',
        label: this.$t('personalAccounts.inn'),
        field: 'inn',
        name: 'inn',
        required: true,
        sortable: true,
      },
    ] as TableColumn<Person>[];
  }

  updatePagination(pagination: TablePagination): void {
    if (pagination) {
      this.model.pagination.descending = pagination.descending;
      this.model.pagination.page = pagination.page;
      this.model.pagination.rowsPerPage = pagination.rowsPerPage;
      this.model.pagination.sortBy =
        pagination.sortBy === null ? this.sortByDefault : pagination.sortBy;
    }
  }

  requestTable(model: Pick<PersonalAccountsTableModel, 'pagination'>) {
    this.fetch({
      ...this.model,
      ...model
    });
  }

  async fetch(model?: PersonalAccountsTableModel): Promise<void> {
    this.model.loading = true;

    if (model?.pagination) {
      this.updatePagination(model.pagination);
    }
    if (!model) return;

    try {
      const {
        data: { records, totalRows },
      } = await personalAccountApi.fullSearchPerson({
        page: model.pagination.page,
        perPage: model.pagination.rowsPerPage,
        sort: `${model.pagination.descending ? '-' : '+'}${model.pagination.sortBy}`,
        searchData: model.searchData,
      });

      this.model.personalAccounts = records;
      this.model.pagination.rowsNumber = totalRows;
    } catch (error) {
      this.handleErrorMessage(error);
    }
    this.model.loading = false;
  }

  goToPersonCard(person: { id: string }, opts?: TableColumnOptions): void {
    pushRoute(
      this.$router,
      {
        name: 'cards',
        params: {
          id: String(person?.id),
          path: 'personal-accounts',
        },
        query: {
          components: this.$store.getters[
            'cardComponents/personalAccounts/components'
          ],
          active: 'personal',
        },
      },
      opts?.targetBlank
    );
  }

  get isAdmin(): boolean {
    return this.$AC.haveScope(USER_SCOPES.SOCIAL_PERSONAL_ACCOUNT_ADMIN);
  }

  createPerson(): void {
    this.$router.push({
      name: 'personalAccountsSearch',
    });
  }

  confirmDeletetionPersonalAccounts(): void {
    this.$q
      .dialog({
        title: this.$t('personalAccounts.deletePersonalAccounts') as string,
        message: this.$t('personalAccounts.doYouWantToDeletePersonalAccounts') as string,
        cancel: true,
      })
      .onOk(() => {
        this.deletePersonalAccounts();
      });
  }

  async deletePersonalAccounts(): Promise<void> {
    this.model.loading = true;
    const ids = this.selected
      .map(({ id }) => `${id}`)
      .filter((id) => id !== 'undefined');

    if (isEmpty(ids)) return;

    try {
      const responce = await deletePersonalAccounts(ids);
      responce.forEach(({ success }) => {
        if (success) {
          notifySuccess(
            this.$t('personalAccounts.personalAccountsDeleted').toString()
          );
          this.fetch(this.model);
        }
      })
    } catch (error) {
      if (error instanceof Error) notifyError(error.message);
    }
    this.model.loading = false;
  }

  created(): void {
    this.model.searchData = this.searchQuery;
    this.fetch(this.model);
  }

  handleErrorMessage(error: unknown): void {
    let status;
    let message = '';
    if (Axios.isAxiosError(error)) {
      status = error.request.status;
      message = this.$t(`personalAccounts.errors.${status}`).toString();
    } else if (error instanceof Error) {
      message = error.message;
    }
    if (status !== 404) notifyError(message);
  }

  formatBirthdayDate(date: string) {
    return convertDateFormat(date, DateFormat.invertedDate, DateFormat.date);
  }
}
