<template>
  <div class="q-gutter-y-md">
    <q-input
      v-model="filter.search"
      dense
      filled
      debounce="1000"
      placeholder="Номер заявления"
      @input="startSearch"
      @keydown.enter="startSearch"
      @keydown.esc="filter.search = ''"
    >
      <template #prepend>
        <q-icon name="search" />
      </template>
      <template #append>
        <q-btn dense flat icon="settings" round @click="toggleFilter" />
      </template>
    </q-input>

    <q-slide-transition>
      <q-card v-show="filter.visible" bordered flat>
        <div class="row q-pa-md 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">
              {{ $t('registries.status') }}
            </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 class="q-mb-md row q-gutter-x-sm items-center">
            <p class="q-ma-none">
              {{ $t('registries.employee') }}
            </p>
            <q-select
              ref="employee"
              v-model="filter.employee"
              filled
              multiple
              dense
              borderless
              style="min-width: 20em"
              :options="employeeFilterOptions"
              @input="handleEmployeeChange"
            >
              <template #option="scope">
                <template v-if="scope.index === 0">
                  <q-input
                    outlined
                    dense
                    placeholder="Найти пользователей"
                    :value="employeeSearch"
                    @input="getEmployees"
                  >
                    <template #append>
                      <q-icon name="search" size="20px" />
                    </template>
                  </q-input>
                </template>
                <q-separator v-if="scope.opt.separator" inset />
                <q-item v-else 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 class="q-mb-md row q-gutter-x-sm items-center">
            <p class="q-ma-none">
              {{ $t('registries.decisionDate') }}
            </p>
            <q-field borderless dense style="min-width: 20em">
              <x-date-range
                :from.sync="filter.from"
                :to.sync="filter.to"
                @input="handleRangeChange"
              />
            </q-field>
          </div>

          <div
            v-if="$listeners['save-data']"
            class="q-mb-md row q-gutter-x-sm items-center"
          >
            <q-btn
              color="primary"
              label="Сформировать выгрузку"
              @click="saveData"
            />
          </div>
          <div class="q-mb-md q-ml-md q-gutter-x-sm items-center">
            <q-input
              v-model="cashbackFilter.departmentName"
              dense
              filled
              debounce="1000"
              placeholder="Уполномоченный орган"
              @input="startSearch"
              @keydown.enter="startSearch"
              @keydown.esc="cashbackFilter.departmentName = ''"
            >
              <template #prepend>
                <q-icon name="search" />
              </template>
            </q-input>
          </div>
          <div class="q-mb-md q-ml-md q-gutter-x-sm items-center">
            <q-input
              v-model="cashbackFilter.searchSeria"
              dense
              filled
              debounce="1000"
              placeholder="Серия ДУЛ ребенка"
              @input="startSearch"
              @keydown.enter="startSearch"
              @keydown.esc="cashbackFilter.searchSeria = ''"
            >
              <template #prepend>
                <q-icon name="search" />
              </template>
            </q-input>
          </div>
          <div class="q-mb-md q-ml-md q-gutter-x-sm items-center">
            <q-input
              v-model="cashbackFilter.searchNumber"
              dense
              filled
              debounce="1000"
              placeholder="Номер ДУЛ ребенка"
              @input="startSearch"
              @keydown.enter="startSearch"
              @keydown.esc="cashbackFilter.searchNumber = ''"
            >
              <template #prepend>
                <q-icon name="search" />
              </template>
            </q-input>
          </div>
          <div class="q-mb-md q-ml-md q-gutter-x-sm items-center">
            <q-input
              v-model="cashbackFilter.campName"
              dense
              filled
              debounce="1000"
              placeholder="Наименование лагеря"
              @input="startSearch"
              @keydown.enter="startSearch"
              @keydown.esc="cashbackFilter.campName = ''"
            >
              <template #prepend>
                <q-icon name="search" />
              </template>
            </q-input>
          </div>
          <div class="q-mb-md q-ml-md q-gutter-x-sm items-center">
            <q-input
              v-model="cashbackFilter.campInn"
              dense
              filled
              debounce="1000"
              placeholder="ИНН лагеря"
              @input="startSearch"
              @keydown.enter="startSearch"
              @keydown.esc="cashbackFilter.campInn = ''"
            >
              <template #prepend>
                <q-icon name="search" />
              </template>
            </q-input>
          </div>
          <div class="q-mb-md q-ml-md q-gutter-x-sm items-center">
            <q-select
              label="Статус платежа"
              v-model="cashbackFilter.paymentStatus"
              filled
              multiple
              dense
              borderless
              style="min-width: 20em"
              :options="cashbackFilter.paymentStatusFilterOptions"
              @input="startSearch"
            >
              <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 class="q-mb-md row q-gutter-x-sm items-center">
            <p class="q-ma-none">Дата поступления обращения</p>
            <q-field borderless dense style="min-width: 20em">
              <x-date-range
                :from.sync="cashbackFilter.appealFrom"
                :to.sync="cashbackFilter.appealTo"
                @input="handleRangeChange"
              />
            </q-field>
          </div>
        </div>
      </q-card>
    </q-slide-transition>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import {
  EmployeeOption,
  Filter,
  Option,
} from '@components/statements/components/search-bar.vue';
import map from 'lodash/map';
import { oidcClientComputed } from '@state/modules/oidc-client';
import XDateRange from '@components/statements/components/x-date-range.vue';
import {
  convertDateFormat,
  convertDateFormatWithoutLocale,
} from '@utils/format-date';
import { DateFormat } from '@constants/utils/format-date';
import { SearchBarRefs } from '@components/common/base-search-bar/index';
import { REG_ORDER_ID } from '@components/registries/search-bars/search-bar.vue';

class AccountsCreateInjection extends Vue.extend({
  computed: {
    ...oidcClientComputed,
  },
}) {}

@Component({
  components: {
    XDateRange,
  },
})
export default class CashbackSearchBar extends AccountsCreateInjection {
  $refs!: SearchBarRefs;
  protected filter: Filter = {
    search: '',
    status: [],
    employee: [],
    from: '',
    to: '',
    fromDecision: '',
    toDecision: '',
    visible: false,
  };

  cashbackFilter = {
    departmentName: '',
    campName: '',
    campInn: '',
    appealTo: '',
    appealFrom: '',
    searchSeria: '',
    searchNumber: '',
    paymentStatus: [],
    paymentStatusFilterOptions: [
      {
        label: 'Распоряжение не сформировано',
        value: 'Распоряжение не сформировано',
      },
      {
        label: 'Сформировано распоряжение',
        value: 'Сформировано распоряжение',
      },
      {
        label: 'Выплата произведена',
        value: 'Выплата произведена',
      },
      {
        label: 'Выплата невозможна',
        value: 'Выплата невозможна',
      },
    ],
  };

  protected startSearch(): void {
    const fulltext: string[] = [];
    const query: string[] = [];

    let { search } = this.filter;
    const { status, from, to, employee } = this.filter;
    const {
      searchSeria,
      searchNumber,
      paymentStatus,
      departmentName,
      campName,
      campInn,
      appealTo,
      appealFrom,
    } = this.cashbackFilter;

    if (search) {
      if (REG_ORDER_ID.test(search)) {
        query.push(`orderId=like=*${search}*`);
      } else {
        search = search.replace(/\\/g, '');
        fulltext.push(`document.resNumber=search='${search}'`);
        fulltext.push(`document.resApplicant=search='${search}'`);
        fulltext.push(`applicant.fullName=search='${search}'`);
      }
    }
    if (status.length) {
      query.push(status.map((e) => `status.internal==${e.value}`).join(' or '));
    }
    if (employee.length) {
      query.push(employee.map((e) => `assigneeId==${e.value}`).join(' or '));
    }
    if (from) {
      query.push(
        `document.resDate>=${convertDateFormat(
          from,
          '',
          DateFormat.invertedDate
        )}`
      );
    }
    if (to) {
      const toPlus = new Date(to as any);
      toPlus.setDate(toPlus.getDate() + 1);
      query.push(
        `document.resDate<${convertDateFormat(
          toPlus,
          '',
          DateFormat.invertedDate
        )}`
      );
    }
    if (appealFrom) {
      query.push(
        `applicationSystem.startDate>=${convertDateFormat(
          appealFrom,
          '',
          DateFormat.invertedDate
        )}`
      );
    }
    if (appealTo) {
      const toPlus = new Date(appealTo as any);
      toPlus.setDate(toPlus.getDate() + 1);
      query.push(
        `applicationSystem.startDate<${convertDateFormat(
          toPlus,
          '',
          DateFormat.invertedDate
        )}`
      );
    }
    if (searchSeria) {
      fulltext.push(
        `statement.childAckt.seryaChild=searchphrase='${searchSeria}' or statement.childPasportDock.childPasportSeries=searchphrase='${searchSeria}'`
      );
    }
    if (searchNumber) {
      query.push(
        `statement.childAckt.numberChild=like=*${searchNumber}* or statement.childPasportDock.childPasportkNumber=like=*${searchNumber}*`
      );
    }
    if (paymentStatus.length) {
      query.push(
        paymentStatus
          .map((st: any) => {
            if (st.value === 'Распоряжение не сформировано') {
              return `(export.status=='${st.value}' or export.status==null)`;
            }
            return `export.status=='${st.value}'`;
          })
          .join(' or ')
      );
    }
    if (departmentName.length) {
      fulltext.push(`departmentFullName=search='${departmentName}'`);
    }
    if (campName.length) {
      fulltext.push(`statement.camp.selectCamp=search='${campName}'`);
    }
    if (campInn.length) {
      fulltext.push(`statement.camp.innCamp=search='${campInn}'`);
    }

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

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

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

  protected async created(): Promise<void> {
    await this.$store.dispatch('idm/accounts/dispatchAccounts', {
      expand: 'person',
      page: 1,
      perPage: 50,
      handler: 'my',
    });
    this.employeeOptions = this.accountsRecords.map(
      ({ id, person }: { id: any; person: any }) => {
        let label = 'Неизвестный';

        if (person && typeof person === 'object') {
          label = `${person.surname || ''} ${person.firstname || ''} ${
            person.middlename || ''
          } `;
        }

        return {
          label,
          value: id,
          checked: true,
        };
      }
    );
  }

  handleRangeChange() {
    const result = ['', ''];

    if (this.filter.from !== null) {
      result[0] = convertDateFormatWithoutLocale(this.filter.from);
    }

    if (this.filter.to !== null) {
      result[1] = convertDateFormatWithoutLocale(this.filter.to);
    }
    this.startSearch();
  }

  handleEmployeeChange() {
    this.startSearch();
  }

  handleStatusChange(): void {
    this.startSearch();
  }

  private get accountsRecords() {
    return this.$store.getters['idm/accounts/accountsRecords'];
  }

  protected get selectedDate(): string {
    const out = [
      convertDateFormat(
        this.filter.from || this.filter.to,
        '',
        DateFormat.date
      ),
    ];

    return out.length ? out.join(' - ') : '';
  }

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

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

  protected employeeOptions = [];
  protected employeeSearch = '';

  protected async getEmployees(val: string) {
    this.employeeSearch = val;
    this.$refs.employee.refresh();
  }

  protected get employeeFilterOptionsDefault(): EmployeeOption[] {
    return [
      {
        label: 'Текущий',
        value: this.userid,
        checked: false,
      },
      {
        label: 'Не назначен',
        value: 'null',
        checked: false,
      },
    ];
  }

  protected filterOutDefault({ value }: EmployeeOption): boolean {
    return !this.employeeFilterOptionsDefault.some((d) => d.value === value);
  }

  protected get employeeFilterOptions(): EmployeeOption[] {
    const def = this.employeeFilterOptionsDefault;
    const checked = this.filter.employee.filter(this.filterOutDefault);
    const employeeSearch = this.employeeSearch
      .replace(/[^\s'`a-zа-яё-]/i, '')
      .trim();

    let employeeFilterOptions: EmployeeOption[] = [];

    if (employeeSearch) {
      const employeeSearchRegExp = new RegExp(
        employeeSearch.replace(/\s+/g, '\\S*\\s+'),
        'i'
      );

      employeeFilterOptions = this.employeeOptions.filter(
        ({ label, value }: Option) =>
          employeeSearchRegExp.test(label as string) &&
          !def.some((d) => d.value === value) &&
          !checked.some((d) => d.value === value)
      );
    }

    const result: EmployeeOption[] = [{ separator: true }];

    if (checked.length) {
      result.push(...checked);
    }
    if (employeeFilterOptions.length) {
      result.push(...employeeFilterOptions);
    }

    if (result.length === 1) {
      return def;
    }

    return def.concat(result);
  }

  protected get employeeFilterChecked(): EmployeeOption[] {
    return this.employeeFilterOptions.filter((e) => e.checked);
  }

  protected get statusOptions(): Option[] {
    return map(
      this.$store.getters['registryService/referenceBooks/referenceBooks']
        .gpzu_2_application_status || {},
      (label, value) => ({ value, label: label.description })
    ).filter((e) => ['10', '11', '12'].includes(e.value));
  }

  protected get userid() {
    // @ts-ignore
    return this.currentUser?.sub ?? null;
  }
}
</script>
