/*
 * Copyright (C) 2019 Robert Bosch GmbH Copyright (C) 2019 Robert Bosch Manufacturing Solutions GmbH, Germany. All rights reserved.
 */

import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs';
import { User } from '../../../shared/user';
import { DateFilter, Filter, ListFilter } from './filter.model';
import { BciFilterService } from '@bci-web-core/core';

@Injectable({
  providedIn: 'root',
})
export class UserFilterService {
  entryDateFilter = new DateFilter<User>(
    'Since: ',
    undefined,
    (user, term) => term.getTime() <= user.entryDate.getTime()
  );
  userTypeFilter = new Filter<User, string>('Usertype: ', 'Security', (user, term) => term === user.role);
  externalOnlyFilter = new Filter<User, string>('External: ', undefined, (user, term) =>
    user.email.toLowerCase().includes(term.toLowerCase())
  );
  departmentFilter = new ListFilter<User, string>(
    'Departments: ',
    [],
    (user, term) => term.indexOf(user.department) >= 0
  );
  filter1 = new Filter('Filter 1', '', () => true);
  filter2 = new Filter('Filter 2', '', () => true);
  filter3 = new Filter('Filter 3', '', () => true);
  filter4 = new Filter('Filter 4', '', () => true);

  activeFilters: Set<Filter<User, any>> = new Set([]);
  activeComplexFilters: Set<Filter<User, any>> = new Set([]);
  allActiveFilters: Set<Filter<User, any>> = new Set([...this.activeFilters, ...this.activeComplexFilters]);

  readonly filterDateRecent: Date;

  private _change: Subject<void> = new Subject<void>();
  change: Observable<void> = this._change.asObservable();

  constructor(private bciFilterService: BciFilterService) {
    const cutoffDate = new Date();
    const daysAgo = 31;
    cutoffDate.setDate(cutoffDate.getDate() - daysAgo);
    this.filterDateRecent = cutoffDate;
  }

  isActive(filter: Filter<User, any>) {
    return this.activeFilters.has(filter);
  }

  isComplexFilterActive(filter: Filter<User, any>) {
    return this.activeComplexFilters.has(filter);
  }

  deactivate(filter: Filter<User, any>): void {
    filter.clear();
    this.activeFilters.delete(filter);
    this.allActiveFilters.delete(filter);
    this._change.next();
  }

  deactivateFilters(filter: Filter<User, any>): void {
    filter.clear();
    this.activeComplexFilters.delete(filter);
    this.allActiveFilters.delete(filter);
    this._change.next();
  }

  activate(filter: Filter<User, any>): void {
    this.activeFilters.add(filter);
    this.allActiveFilters = new Set([...this.allActiveFilters, ...this.activeFilters]);
    this._change.next();
  }

  activateFilters(filter: Filter<User, any>): void {
    this.activeComplexFilters.add(filter);
    this.allActiveFilters = new Set([...this.allActiveFilters, ...this.activeComplexFilters]);
    this._change.next();
  }

  sortChange() {
    this._change.next();
  }

  /* The methods below are added only for the demo purpose to demosonstrate the apply filters functionality when the user selects any of the Departments filters, 
  this method should be changed accordingly with the user implementation */

  /**
   * Used for activating filters on click of apply button in the filter dialog
   * @param filterData
   */
  activateNewFilter() {
    this.removeNewComplexFilters();
    let filter: Filter<User, any>;
    this.bciFilterService.listOfActiveFilters.forEach((value, key) => {
      filter = new Filter(key + ': ', [], () => true);
      filter.term = [...value];
      filter?.term?.length > 0 && this.activateFilters(filter);
    });
    this._change.next();
  }

  /**
   * Method used for resetting all the active filters
   */
  removeNewComplexFilters(): void {
    this.activeComplexFilters = new Set([]);
    this.allActiveFilters = new Set([]);
  }

  /**
   * Used for deactivating the filters on click of 'x' button of the selected chips
   * @param filter
   */
  deactivateNewFilter(filter: Filter<User, any>) {
    const sectionLabel = filter.prefix.split(':')[0];
    this.bciFilterService.deactiveBciFilter(sectionLabel);
    this.deactivateFilters(filter);
  }
}
