import BaseDateRange from '@components/common/base-date-range/index.vue';
import BaseApplicationInput from '@components/common/base-application-input/index.vue';
import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
import BaseSearch from '@components/common/base-search/index.vue';
import { VueClass } from 'vue-class-component/lib/declarations';
import { oidcClientComputed } from '@state/modules/oidc-client';
import { QSelect } from 'quasar';
import { convertDateFromBackendFormat } from '@utils/format-date';
import omit from 'lodash/omit';

export enum ConditionType {
  boolean = 'boolean',
  date = 'date',
  dictionary = 'dictionary',
  string = 'string',
  custom = 'custom',
}

const SearchBarInjection: VueClass<Vue> = Vue.extend({
  computed: {
    ...oidcClientComputed,
  },
});

interface Option {
  label?: string;
  value?: string;
}

export interface Attribute {
  attribute: string; // Уникальное значение атрибута, обязательное поле, используется в наименовании слота,
  // если передано свойство conditionType: 'custom'
  attributeName: string; // Выводится в интерфейс, является названием атрибута
  conditionType: ConditionType; // Тип условия фильтра, если добавлен слот, необходимо передать 'custom'
  dictionary?: Option[]; // Выбор для задания значений фильтрации с conditionType = 'dictionary'
  value?: any; // Значение фильтра, если не было передано, то добавляется на этапе инициализации
  select?: boolean; // Выбран ли атрибут
  settingValue?: {
    // Значение условия фильтрации, устанавливается на этапе инициализации
    label: string;
    value: string;
    prefix?: string; // Префикс, используется при составлении query
    postfix?: string; // Постфикс, используется при составлении query
  };
}

export interface SearchBarRefs {
  employee: QSelect;
  [key: string]: Vue | Element | Vue[] | Element[];
}

@Component({
  methods: {
    convertDateFromBackendFormat,
  },
  components: {
    BaseSearch,
    BaseDateRange,
    BaseApplicationInput,
  },
})
export default class SearchBar extends SearchBarInjection {
  $refs!: SearchBarRefs;

  private filter = {
    search: this.$route.query.search,
    visible: false,
    selected: [] as Attribute[],
  };

  @Prop({ default: '', required: true }) value!: string;

  @Prop({ type: Boolean, default: false }) saveQuery?: boolean;

  @Watch('value')
  private valueHandler(val: string): void {
    this.filter.search = val;
  }

  @Watch('filter.search')
  private filterSearchHandler(val: string): void {
    const search = val || undefined;
    const queryParams = this.resetPagination();

    if (this.saveQuery) {
      this.$router.push({ query: { ...queryParams, search } });
    }

    this.$emit('input', val);
  }

  protected resetPagination() {
    this.$emit('pagination');
    return omit(this.$route.query, 'page');
  }

  private created(): void {
    this.filter.search = this.value;
  }
}
