import { Component, Vue } from 'vue-property-decorator';
import { oidcClientComputed } from '@state/modules/oidc-client';
import XDateRange from '@components/statements/components/x-date-range.vue';
import {
  convertDateFormat,
  convertDateFormatWithoutLocale,
  getCurrentDate,
} from '@utils/format-date';
import { DateFormat } from '@constants/utils/format-date';
import { SearchBarRefs } from '@components/common/base-search-bar';
import { date } from 'quasar';

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

@Component({
  components: {
    XDateRange,
  },
})
export default class TicketsSearchBar extends AccountsCreateInjection {
  public $refs!: SearchBarRefs;
  protected filter: TicketsFilter = {
    employee: [],
    from: null,
    to: null,
  };

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

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

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

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

  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 userid() {
    // @ts-ignore
    return this.currentUser?.sub ?? null;
  }

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

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

  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,
        };
      }
    );
  }

  protected startSearch(): void {
    this.$emit('query', this.filter);
  }

  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();
  }

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

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

  private dateLimit(day: string): boolean {
    return getCurrentDate() < day;
  }
}

export interface TicketsFilter {
  employee: EmployeeOption[];
  from: Date | null;
  to: Date | null;
}

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

interface EmployeeOption extends Option {
  checked?: boolean;
  separator?: boolean;
}
