import { ValueSelected } from './../../../model/common-model';
import { UserFilterHelper } from './user-filter-helper';
import { IFilterParams } from 'ag-grid-community';
import { User, UserPreFilter } from '../../../model/common-model';
import BaseFilter from '../base-filter';
import { ServiceBase } from "../../../data/service-base";
import { Container } from 'aurelia-framework';
import { Config } from '../../../config';

export class UserFilter<T extends User> extends BaseFilter {
  public filterHelper: UserFilterHelper;

  public init(params: IFilterParams & { userServiceName: string, userService: ServiceBase<T> }): void {
    this.config = Container.instance.get(Config);

    if (params.userService == null && params.userServiceName == null && !this.config.agGridConfig.suppressMenu) {
      throw new Error("userService or userServiceName parameter is missing");
    }

    this.filterHelper = new UserFilterHelper(params.userService ?? new ServiceBase<T>(params.userServiceName),
      this.firstTime,
      (model) => this.setInstanceModel(model),
      () => this.setDropdownName()
    );

    this.filterChangedCallback = params.filterChangedCallback;
    super.init(params);
  }

  public async onOpenDropDown() {
    this.removeDisposables(false);

    let oldUserValues = this.filterHelper.userValues;
    await this.filterHelper.getUsers();
    if (oldUserValues && oldUserValues.length > 0) {
      this.filterHelper.onOpenDropDown(oldUserValues);
    }
    this.firstTime = false;
    this.filterHelper.setFirstTime(this.firstTime);
  }

  public async setupContentGui(): Promise<string> {
    await this.onOpenDropDown();
    return this.filterHelper.setupContentGui();
  }

  public isFilterActive(): boolean {
    return this.filterHelper.isFilterActive();
  }

  public resetFilter(): void {
    this.filterHelper.resetFilter();
  }

  public removeFilterValue(filterValue: ValueSelected | number): void {
    if (isNumber(filterValue)) {
      this.filterHelper.selectedUserPreFilter = UserPreFilter.None;
    }
    else {
      filterValue.selected = false;
    }
  }

  public getModel(): any {
    if (this.isFilterActive()) {
      let model = { filterType: 'user', displayEmptyFields: this.filterHelper.displayEmptyFields };
      if (this.filterHelper.selectedUserPreFilter == UserPreFilter.Me) {
        return Object.assign(model, { type: 'equals', userPreFilter: this.filterHelper.selectedUserPreFilter });
      }
      if (this.filterHelper.selectedUserPreFilter == UserPreFilter.NotMe) {
        return Object.assign(model, { type: 'notEqual', userPreFilter: this.filterHelper.selectedUserPreFilter });
      }
      return Object.assign(model, { filter: this.filterHelper.userValues });
    }
    return null;
  }

  public setModel(model: any): void {
    this.dispose()
    this.filterHelper.setModel(model);
    this.filterChangedCallback();
  }

  public getValue(): Array<ValueSelected> | number {
    return this.filterHelper.getValue();
  }

  public getModelAsString?(): string {
    return '';
  }

  public setupContentGuiSideFilter(): string {
    return this.filterHelper.setupContentGuiSideFilter();
  }

  protected dispose(): void {
    super.dispose();
    this.filterHelper.dispose();
  }

  private removeDisposables(all: boolean) {
    this.dispose();
    this.filterHelper.removeDisposables(all);
  }

  private setInstanceModel(model: any) {
    const instance = this.params.api.getFilterInstance((this.params as IFilterParams).colDef.field);
    instance.setModel(model);
  }

  private setDropdownName() {
    this.DROPDOWN_NAME = this.getModelAsString();
  }
}
