import { ValueSelected, EnumSelected, AgGridView, FieldType, UserPreFilter } from './../../../model/common-model';
import { ColDef, FilterChangedEvent, GridOptions } from "ag-grid-community";
import { autoinject, bindable, bindingMode, customElement } from "aurelia-framework";
import BaseFilter from '../../../resources/filters/base-filter';

@autoinject
@customElement("summary-filter")
export class SummaryFilter {
  private FieldType = FieldType;

  @bindable({ bindingMode: bindingMode.fromView })
  private gridOptions: GridOptions;
  @bindable({ bindingMode: bindingMode.fromView })
  private entitiesCount: number;
  @bindable({ bindingMode: bindingMode.fromView })
  private usedView: AgGridView;
  @bindable({ bindingMode: bindingMode.fromView })
  private maxShowedFilter: number = 3;
  @bindable({ bindingMode: bindingMode.fromView })
  private afterFilterChanged: (event: FilterChangedEvent<any>) => {};

  private currentSelectedFilters: Array<CurrentSelectedFilter>;

  public gridOptionsChanged(newValue: GridOptions, oldValue: GridOptions) {
    this.gridOptions.onFilterChanged = (event) => {
      this.filterCurrent();
      if (this.afterFilterChanged != null) {
        this.afterFilterChanged(event);
      }
    }
  }

  public resetAllFilter() {
    if (this.currentSelectedFilters.length > 0) {
      for (const currentSelectedFilter of this.currentSelectedFilters) {
        if (currentSelectedFilter.instance.resetFilter != null) {
          currentSelectedFilter.instance.resetFilter();
        }
      }
    }
  }

  public showAll(filter: CurrentSelectedFilter) {
    filter.show = true;
  }

  public filterCurrent() {
    this.currentSelectedFilters ??= new Array<CurrentSelectedFilter>();
    this.currentSelectedFilters.splice(0);
    let filters = this.gridOptions?.api?.getFilterModel();
    if (filters != null) {
      for (const filter in filters) {
        let colDef: ColDef = this.gridOptions.columnDefs.find((y: ColDef) => y.field == filter);
        this.createCurrentSelectedFilter(colDef, filters[filter]);
      }
    }
  }

  public createCurrentSelectedFilter(colDef: ColDef, value: any) {
    if (colDef.filter !== false && colDef.type != null && colDef.type != FieldType.Base) {
      let currentSelectedFilter: CurrentSelectedFilter = new CurrentSelectedFilter();
      currentSelectedFilter.columnName = colDef.headerName;
      currentSelectedFilter.type = (colDef.type as string);
      currentSelectedFilter.instance = this.gridOptions?.api?.getFilterInstance(colDef.field) as BaseFilter;
      let value = currentSelectedFilter.instance.getValue();

      switch (currentSelectedFilter.type) {
        case FieldType.String:
        case FieldType.Html:
        case FieldType.Number:
        case FieldType.Currency:
        case FieldType.Date:
          currentSelectedFilter.value = value as string;
          break;
        case FieldType.Boolean:
          currentSelectedFilter.value = value?.toString() as string;
          break;
        case FieldType.Enum:
          let translationFirstPart = colDef.floatingFilterComponentParams.category + '.';
          currentSelectedFilter.enumValues = value as Array<EnumSelected>;
          currentSelectedFilter.enumValues.forEach((x: EnumSelected) => {
            (x as any).name = translationFirstPart + x.key;
          })
          break;
        case FieldType.User:
          if (Array.isArray(value)) {
            currentSelectedFilter.valueSelected = value as Array<ValueSelected>;
          } else {
            switch (value as number) {
              case UserPreFilter.Me:
                currentSelectedFilter.value = "common:grid.me";
                break;
              case UserPreFilter.NotMe:
                currentSelectedFilter.value = "common:grid.notMe";
                break;
            }
          }
          break;
        case FieldType.Enumeration:
        case FieldType.OneToMany:
        case FieldType.ManyToMany:
          currentSelectedFilter.valueSelected = value as Array<ValueSelected>;
          break;
        default:
          break;
      }
      this.currentSelectedFilters.push(currentSelectedFilter);
    }
  }

  public beforeCloseFn(value: any, filter: CurrentSelectedFilter) {
    if (filter.type != null && filter.type != FieldType.Base) {
      let instance = filter.instance;
      instance.removeFilterValue(value);
      instance.setModel(instance.getModel());
      this.gridOptions?.api?.onFilterChanged();
    }
  }

  public unselectEmptyFields(filter: CurrentSelectedFilter) {
    let instance: any = filter.instance;
    if (filter.type == "Date") {
      instance.filterHelper.isDateNullable = false;
    }
    else if (instance.filterHelper) {
      instance.filterHelper.displayEmptyFields = false;
    }
    else {
      instance.displayEmptyFields = false;
    }
    instance.setModel(instance.getModel());
    this.gridOptions?.api?.onFilterChanged();
  }
}

class CurrentSelectedFilter {
  columnName: string;
  type: string;
  value: string;
  valueSelected: Array<ValueSelected>;
  enumValues: Array<EnumSelected>;
  instance: BaseFilter;
  show: boolean = false;
}
