<template>
  <div class="q-gutter-y-md">
    <q-input
      v-model="filter.search"
      dense
      filled
      debounce="1000"
      placeholder="Введите название услуги"
      @input="handleSearchChange"
      @keydown.enter="handleSearchChange"
      @keydown.esc="filter.search = ''"
    >
      <template #prepend>
        <q-icon name="search" />
      </template>
      <template #append>
        <q-btn dense flat icon="settings" round @click="toggleFilter">
          <q-badge
            color="red"
            floating
            style="border-radius: 50%"
            v-if="!!filterCount"
          >
            {{ filterCount }}
          </q-badge>
        </q-btn>
      </template>
    </q-input>

    <q-slide-transition>
      <q-card bordered flat v-show="filter.visible">
        <q-card-section>
          <div class="row q-gutter-x-md" style="margin-bottom: -16px">
            <div class="q-mb-md row q-gutter-x-sm items-center">
              <p class="q-ma-none">Статус</p>
              <q-select
                v-model="filter.status"
                filled
                stretch
                flat
                dense
                borderless
                multiple
                style="min-width: 20em"
                :emit-value="false"
                :options="statusOptions"
                @input="handleStatusChange"
              >
                <template #option="scope">
                  <q-item v-bind="scope.itemProps" v-on="scope.itemEvents">
                    <q-item-section side>
                      <q-checkbox
                        :value="scope.selected"
                        @input="scope.itemEvents.click"
                      />
                    </q-item-section>
                    <q-item-section>
                      <q-item-label v-html="scope.opt.label" />
                    </q-item-section>
                  </q-item>
                </template>
              </q-select>
            </div>
          </div>
        </q-card-section>
      </q-card>
    </q-slide-transition>
  </div>
</template>

<script lang="ts">
import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
import { SearchBarRefs } from '@/components/common/base-search-bar';
import { ServiceSearchQuery } from '@components/services/index';
import omit from 'lodash/omit';

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

@Component({})
export default class ServicesSearchBar extends Vue {
  $refs!: SearchBarRefs;

  @Prop({
    required: true,
  })
  query!: ServiceSearchQuery;

  // todo статусы
  statusOptions = [
    {
      label: 'Черновик',
      value: 'draft',
    },
    {
      label: 'В работе',
      value: 'inProgress',
    },
    {
      label: 'Готова к подписанию',
      value: 'readyToPublish',
    },
    {
      label: 'Подписана',
      value: 'signed',
    },
    {
      label: 'Опубликована',
      value: 'published',
    },
  ];

  @Watch('query', { deep: true })
  queryHandler(query: ServiceSearchQuery): void {
    this.parseQueryParams(query);
  }

  handleStatusChange(): void {
    const RESult = this.filter.status.map((el) => el.value);
    const status = RESult.join() || undefined;

    const queryParams = this.resetPagination();

    this.$router.push({ query: { ...queryParams, status } });

    this.startSearch();
  }

  handleSearchChange(): void {
    const search = this.filter.search || undefined;
    const queryParams = this.resetPagination();

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

  protected get selectedStatus(): string {
    return this.filter.status.length
      ? this.filter.status.map((e) => e.label).join(', ')
      : '';
  }

  protected toggleFilter(): void {
    this.filter.visible = !this.filter.visible;
  }

  protected saveData(): void {
    this.$emit('save-data');
  }

  protected RESetFilter(): void {
    this.filter.search = '';
    this.filter.status = [];
    this.filter.visible = false;
    this.startSearch();
  }

  protected get filterCount(): number {
    let RESult = 0;

    if (this.filter.status.length) {
      RESult++;
    }

    return RESult;
  }

  protected filter: Filter = {
    search: '',
    status: [],
    visible: false,
  };

  protected startSearch(): void {
    const fulltext: string[] = [];
    const query: string[] = [];
    const { status, search } = this.filter;

    if (search) {
      fulltext.push(
        `(shortName=searchprefix="${search}" or shortName=search="${search}")`
      );
      fulltext.push(
        `(name=searchprefix="${search}" or name=search="${search}")`
      );
      fulltext.push(
        `(fullName=searchprefix="${search}" or fullName=search="${search}")`
      );
    }
    if (status.length) {
      let statusesArr: Array<string> = [];

      for (const val of status) {
        if (val.value && val.value.includes(',')) {
          const temp = val.value.split(',');
          statusesArr = statusesArr.concat(temp);
        } else {
          statusesArr.push(val.value ?? '');
        }
      }
      query.push(statusesArr.map((e) => `state==${e}`).join(' or '));
    }

    const qObj = {
      query: query.join(' and '),
      fulltext: fulltext.join(' or '),
    };
    this.$emit('query', qObj);
  }

  parseQueryParams(query: ServiceSearchQuery): void {
    const { status } = query;
    const { search } = query;

    if (status) {
      const codes: string[] = status.split(',');

      codes.forEach((code) => {
        const stItem: Option | undefined = this.statusOptions.find(
          (el) => el.value === code
        );
        const alreadyInList = this.filter.status.find(
          (el) => el.value === code
        );

        if (stItem && !alreadyInList) {
          this.filter.status.push(stItem);
        }
      });
    }

    if (search) {
      this.filter.search = search;
    }

    if ((status && this.statusOptions.length > 0) || search) {
      this.filter.visible = true;
      this.startSearch();
    }
  }

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

  protected async created(): Promise<void> {
    this.parseQueryParams(this.query);
    this.startSearch();
  }
}

export interface Filter {
  search: string;
  status: Option[];
  visible: boolean;
}
</script>

<style lang="sass">
.m-search-bar .q-field__control-container > .q-field__native.row.items-center > span
  white-space: nowrap
  text-overflow: ellipsis
  overflow: hidden

.m-search-bar
  justify-content: space-between
  background: white
  color: #757575
</style>
