/**
 * Глобальный класс для фильтров по проекту
 * Все доп параметры для фильтров необходимо добавлять в init/ervu-service.yaml дабы бэк был готов их принимать.
 * .../ervu-person-registry/... - схема FilterRecruit
 * .../ervu-subpoena-registry/... - схема SubpoenasListSearch
 * Для подготовки данных к отправке, используем prepareApiParams() в ./prepare-api-params.ts
 */
import moment from 'moment';
import { SearchFilter, UrlQueryParams, Option, sex } from '@/recruits/models';

// TODO - нужен конструктор для передачи начальных параметров для фильтров, вместо прокидывания query в роутере

export class SearchFilterUtils extends SearchFilter {
  firstName = '';
  lastName = '';
  middleName = '';
  fullName = '';
  idERN = '';
  inn = '';
  snils = '';
  series = '';
  number = '';
  documentSeries = '';
  documentNumber = '';
  summonObjective = '';
  nameVK = '';
  source = '';
  status = '';
  fileName = '';
  result = '';
  initiator = '';
  listNumber = '';
  requester = '';
  reason = '';
  type = '';
  incidentProvider = '';
  sourceCode = '';
  registrationReasons: string[] = [];
  statuses: Array<Option> = [];
  causes: Array<Option> = [];
  genders: Array<Option> = [];
  birthDateFrom: Date | null = null;
  birthDateTo: Date | null = null;
  turnoutDateFrom: Date | null = null;
  turnoutDateTo: Date | null = null;
  createDateFrom: Date | null = null;
  createDateTo: Date | null = null;
  sendingDateFrom: Date | null = null;
  sendingDateTo: Date | null = null;
  dateStartFrom: Date | null = null;
  dateStartTo: Date | null = null;
  dateEndFrom: Date | null = null;
  dateEndTo: Date | null = null;
  summonsDateFrom: Date | null = null;
  summonsDateTo: Date | null = null;
  formationDateFrom: Date | null = null;
  formationDateTo: Date | null = null;
  requestDateTo: Date | null = null;
  requestDateFrom: Date | null = null;
  resolveDateFrom: Date | null = null;
  resolveDateTo: Date | null = null;
  registeredDateFrom: Date | null = null;
  registeredDateTo: Date | null = null;
  sendDateFrom: Date | null = null;
  sendDateTo: Date | null = null;
  receiveDateFrom: Date | null = null;
  receiveDateTo: Date | null = null;
  militaryRegistrationDateFrom: Date | null = null;
  militaryRegistrationDateTo: Date | null = null;
  conscriptionExemptAbsent = false;
  medExemptAbsent: 'true' | 'false' | undefined = undefined;

  public countFilters(): number {
    let filtersCount = super.countFilters();
    if (this.firstName) {
      filtersCount++;
    }
    if (this.lastName) {
      filtersCount++;
    }
    if (this.middleName) {
      filtersCount++;
    }
    if (this.birthDateFrom || this.birthDateTo) {
      filtersCount++;
    }
    if (this.idERN) {
      filtersCount++;
    }
    if (this.inn) {
      filtersCount++;
    }
    if (this.snils) {
      filtersCount++;
    }
    if (this.series) {
      filtersCount++;
    }
    if (this.number) {
      filtersCount++;
    }
    if (this.statuses && this.statuses.length > 0) {
      filtersCount++;
    }
    if (this.causes && this.causes.length > 0) {
      filtersCount++;
    }
    if (this.genders && this.genders.length > 0) {
      filtersCount++;
    }
    if (this.turnoutDateFrom || this.turnoutDateTo) {
      filtersCount++;
    }
    if (this.summonObjective) {
      filtersCount++;
    }
    if (this.createDateFrom || this.createDateTo) {
      filtersCount++;
    }
    if (this.sendingDateFrom || this.sendingDateTo) {
      filtersCount++;
    }
    if (this.nameVK) {
      filtersCount++;
    }
    if (this.dateEndFrom || this.dateEndTo) {
      filtersCount++;
    }
    if (this.dateStartFrom || this.dateStartTo) {
      filtersCount++;
    }
    if (this.summonsDateFrom || this.summonsDateTo) {
      filtersCount++;
    }
    if (this.formationDateFrom || this.formationDateTo) {
      filtersCount++;
    }
    if (this.requestDateFrom || this.requestDateTo) {
      filtersCount++;
    }
    if (this.militaryRegistrationDateFrom || this.militaryRegistrationDateTo) {
      filtersCount++;
    }
    if (this.resolveDateFrom || this.resolveDateTo) {
      filtersCount++;
    }
    if (this.registeredDateFrom || this.registeredDateTo) {
      filtersCount++;
    }
    if (this.sendDateFrom || this.sendDateTo) {
      filtersCount++;
    }
    if (this.receiveDateFrom || this.receiveDateTo) {
      filtersCount++;
    }
    if (this.source) {
      filtersCount++;
    }
    if (this.status) {
      filtersCount++;
    }
    if (this.fullName) {
      filtersCount++;
    }
    if (this.fileName) {
      filtersCount++;
    }
    if (this.result) {
      filtersCount++;
    }
    if (this.initiator) {
      filtersCount++;
    }
    if (this.registrationReasons && this.registrationReasons.length) {
      filtersCount++;
    }
    if (this.listNumber) {
      filtersCount++;
    }
    if (this.requester) {
      filtersCount++;
    }
    if (this.reason) {
      filtersCount++;
    }
    if (this.type) {
      filtersCount++;
    }
    if (this.incidentProvider) {
      filtersCount++;
    }
    if (this.sourceCode) {
      filtersCount++;
    }
    if (this.documentSeries) {
      filtersCount++;
    }
    if (this.documentNumber) {
      filtersCount++;
    }
    if (this.conscriptionExemptAbsent) {
      filtersCount++;
    }
    if (this.medExemptAbsent) {
      filtersCount++;
    }
    return filtersCount;
  }

  public prepareRequestParams(): UrlQueryParams {
    function prepareString(string: string) {
      return string || undefined;
    }

    function prepareDate(date: Date | null) {
      const momentDate = moment(date);
      return (
        (momentDate.isValid() && momentDate.format('YYYY-MM-DD')) || undefined
      );
    }

    return Object.assign(super.prepareRequestParams(), {
      firstName: prepareString(this.firstName),
      lastName: prepareString(this.lastName),
      middleName: prepareString(this.middleName),
      source: prepareString(this.source),
      status: prepareString(this.status),
      fullName: prepareString(this.fullName),
      nameVK: prepareString(this.nameVK),
      fileName: prepareString(this.fileName),
      result: prepareString(this.result),
      initiator: prepareString(this.initiator),
      listNumber: prepareString(this.listNumber),
      requester: prepareString(this.requester),
      reason: prepareString(this.reason),
      type: prepareString(this.type),
      incidentProvider: prepareString(this.incidentProvider),
      sourceCode: prepareString(this.sourceCode),
      documentSeries: prepareString(this.documentSeries),
      documentNumber: prepareString(this.documentNumber),
      summonObjective: prepareString(this.summonObjective),
      idERN: prepareString(this.idERN),
      inn: prepareString(this.inn),
      snils: prepareString(this.snils),
      series: prepareString(this.series),
      number: prepareString(this.number),
      conscriptionExemptAbsent: this.conscriptionExemptAbsent || undefined,
      medExemptAbsent: (() => {
        if (this.medExemptAbsent === 'true') return true;
        if (this.medExemptAbsent === 'false') return false;
      })(),

      birthDateFrom: prepareDate(this.birthDateFrom),
      birthDateTo: prepareDate(this.birthDateTo),
      dateStartFrom: prepareDate(this.dateStartFrom),
      createDateFrom: prepareDate(this.createDateFrom),
      createDateTo: prepareDate(this.createDateTo),
      sendingDateFrom: prepareDate(this.sendingDateFrom),
      sendingDateTo: prepareDate(this.sendingDateTo),
      turnoutDateFrom: prepareDate(this.turnoutDateFrom),
      turnoutDateTo: prepareDate(this.turnoutDateTo),
      dateStartTo: prepareDate(this.dateStartTo),
      dateEndFrom: prepareDate(this.dateEndFrom),
      dateEndTo: prepareDate(this.dateEndTo),
      summonsDateFrom: prepareDate(this.summonsDateFrom),
      summonsDateTo: prepareDate(this.summonsDateTo),
      formationDateFrom: prepareDate(this.formationDateFrom),
      formationDateTo: prepareDate(this.formationDateTo),
      requestDateFrom: prepareDate(this.requestDateFrom),
      requestDateTo: prepareDate(this.requestDateTo),
      resolveDateFrom: prepareDate(this.resolveDateFrom),
      resolveDateTo: prepareDate(this.resolveDateTo),
      registeredDateTo: prepareDate(this.registeredDateTo),
      registeredDateFrom: prepareDate(this.registeredDateFrom),
      sendDateFrom: prepareDate(this.sendDateFrom),
      sendDateTo: prepareDate(this.sendDateTo),
      receiveDateTo: prepareDate(this.receiveDateTo),
      receiveDateFrom: prepareDate(this.receiveDateFrom),
      militaryRegistrationDateFrom: prepareDate(
        this.militaryRegistrationDateFrom
      ),
      militaryRegistrationDateTo: prepareDate(this.militaryRegistrationDateTo),

      statuses: this.statuses.length
        ? this.statuses?.flatMap(({ value }) => value || [])
        : undefined,
      causes: this.causes.length
        ? this.causes?.flatMap(({ value }) => value || [])
        : undefined,
      genders: this.genders.length
        ? this.genders?.flatMap(({ value }) => value || [])
        : undefined,
      registrationReasons: this.registrationReasons.length
        ? this.registrationReasons
        : undefined,
    });
  }

  public updateParamsFromRoute(query: { [key: string]: string }): void {
    function getStringValue(key: string) {
      return query[key] ? String(query[key]) : '';
    }

    function getDateValue(key: string) {
      const momentDate = moment(String(query[key]));
      return momentDate.isValid() ? momentDate.toDate() : null;
    }

    super.updateParamsFromRoute(query);
    this.firstName = getStringValue('firstName');
    this.lastName = getStringValue('lastName');
    this.middleName = getStringValue('middleName');
    this.idERN = getStringValue('idERN');
    this.inn = getStringValue('inn');
    this.snils = getStringValue('snils');
    this.series = getStringValue('series');
    this.number = getStringValue('number');
    this.source = getStringValue('source');
    this.status = getStringValue('status');
    this.fullName = getStringValue('fullName');
    this.fileName = getStringValue('fileName');
    this.initiator = getStringValue('initiator');
    this.listNumber = getStringValue('listNumber');
    this.requester = getStringValue('requester');
    this.reason = getStringValue('reason');
    this.type = getStringValue('type');
    this.incidentProvider = getStringValue('incidentProvider');
    this.sourceCode = getStringValue('sourceCode');
    this.documentSeries = getStringValue('documentSeries');
    this.documentNumber = getStringValue('documentNumber');
    this.summonObjective = getStringValue('summonObjective');
    this.result = getStringValue('result');
    this.nameVK = getStringValue('nameVK');

    this.birthDateFrom = getDateValue('birthDateFrom');
    this.birthDateTo = getDateValue('birthDateTo');
    this.dateStartFrom = getDateValue('dateStartFrom');
    this.createDateTo = getDateValue('createDateTo');
    this.createDateFrom = getDateValue('createDateFrom');
    this.sendingDateFrom = getDateValue('sendingDateFrom');
    this.sendingDateTo = getDateValue('sendingDateTo');
    this.turnoutDateFrom = getDateValue('turnoutDateFrom');
    this.turnoutDateTo = getDateValue('turnoutDateTo');
    this.dateStartTo = getDateValue('dateStartTo');
    this.dateEndTo = getDateValue('dateEndTo');
    this.dateEndFrom = getDateValue('dateEndFrom');
    this.summonsDateFrom = getDateValue('summonsDateFrom');
    this.summonsDateTo = getDateValue('summonsDateTo');
    this.formationDateFrom = getDateValue('formationDateFrom');
    this.formationDateTo = getDateValue('formationDateTo');
    this.requestDateFrom = getDateValue('requestDateFrom');
    this.resolveDateFrom = getDateValue('resolveDateFrom');
    this.resolveDateTo = getDateValue('resolveDateTo');
    this.registeredDateFrom = getDateValue('registeredDateFrom');
    this.registeredDateTo = getDateValue('registeredDateTo');
    this.sendDateTo = getDateValue('sendDateTo');
    this.sendDateFrom = getDateValue('sendDateFrom');
    this.receiveDateFrom = getDateValue('receiveDateFrom');
    this.receiveDateTo = getDateValue('receiveDateTo');
    this.requestDateTo = getDateValue('requestDateTo');
    this.militaryRegistrationDateFrom = getDateValue(
      'militaryRegistrationDateFrom'
    );
    this.militaryRegistrationDateTo = getDateValue(
      'militaryRegistrationDateTo'
    );

    if (query.conscriptionExemptAbsent) {
      this.conscriptionExemptAbsent = true;
    }

    if (query.medExemptAbsent === 'true') this.medExemptAbsent = 'true';
    if (query.medExemptAbsent === 'false') this.medExemptAbsent = 'false';

    if (query.statuses) {
      this.statuses = String(query.statuses)
        .split(',')
        .map((value) => {
          return {
            label: '',
            value,
          };
        });
    }
    if (query.causes) {
      this.causes = String(query.causes)
        .split(',')
        .map((value) => {
          return {
            label: '',
            value,
          };
        });
    }
    if (query.genders) {
      this.genders = String(query.genders)
        .split(',')
        .map((value) => {
          return {
            label: sex[value],
            value,
          };
        });
    }
    if (query.registrationReasons) {
      this.registrationReasons = String(query.registrationReasons).split(',');
    }
  }
}
