import { Component, Vue, Watch } from 'vue-property-decorator';
import { getDiff } from '@utils/base/Object';
import { TableFilter } from '@models/base/TableFilter';
import { convertDateToBackendFormat } from '@utils/format-date';
import { TablePagination } from '@models/base/TablePagination';
let prevFilterValue = {} as TableFilter;

/*
Использование:
Наследующийся компонент должен иметь поле filter типа TableFilter
В хуке mounted, необходимо вызвать метод миксина initFilter

Этой абстракции можно делегировать логику управления фильтром таблицы модели TableFilter.
В частности:
 - инициализацию фильтра
 - синхронизацию квери с состоянием фильтра
 - запрашивание данных при обновлении фильтра(TODO)
----------------------------------------------------------------
*/
@Component
export default class Filterable extends Vue {
  filter: TableFilter;

  initFilter(): void {
    this.filter = new TableFilter({
      pagination: new TablePagination({
        rowsPerPage: this.$route.query.rowsPerPage
          ? Number(this.$route.query.rowsPerPage)
          : undefined,
        rowsNumber: this.$route.query.rowsNumber
          ? Number(this.$route.query.rowsNumber)
          : undefined,
        page: this.$route.query.page
          ? Number(this.$route.query.page)
          : undefined,
        sortBy: this.$route.query.sortBy,
        descending: this.$route.query.descending
          ? Boolean(this.$route.query.descending)
          : undefined,
      }),
      dateFrom: this.$route.query.dateFrom
        ? new Date(this.$route.query.dateFrom as string)
        : undefined,
      dateTo: this.$route.query.dateTo
        ? new Date(this.$route.query.dateTo as string)
        : undefined,
      search: this.$route.query.search,
    });
  }

  fetchFilterable() {
    // implement me
  }

  @Watch('filter', { deep: true })
  onFilterChanged(to: TableFilter): void {
    if (!to) return;
    const diffs = getDiff(
      (to as unknown) as Record<string, unknown>,
      (prevFilterValue as unknown) as Record<string, unknown>
    ) as (keyof TableFilter)[];
    prevFilterValue = Object.assign({}, to);

    diffs.forEach((diff) => {
      // TODO: избавиться от свича, привести к виду [diff]: to[diff]
      switch (diff) {
        case 'dateFrom':
          this.$router.replace({
            query: {
              ...this.$route.query,
              dateFrom: to.dateFrom
                ? convertDateToBackendFormat(to.dateFrom!)
                : undefined,
            },
          });
          break;
        case 'dateTo':
          this.$router.replace({
            query: {
              ...this.$route.query,
              dateTo: to.dateTo
                ? convertDateToBackendFormat(to.dateTo!)
                : undefined,
            },
          });
          break;
        case 'search':
          this.$router.replace({
            query: {
              ...this.$route.query,
              search: to.search,
            },
          });
          break;
      }
    });
  }
}
