import { observable, Container } from 'aurelia-framework';
import { IFloatingFilterParams, FilterChangedEvent } from "ag-grid-community";
import { I18N } from "aurelia-i18n";
import BaseFloatingFilter from "./base-floating-filter";
import { ValueSelected } from "../../model/common-model";
import { EnumerationTypeCategory } from '../../utils/enumeration-types-helper';

export class EnumerationCategoryFloatingFilter extends BaseFloatingFilter {
  private categories: Array<EnumerationTypeCategory>;
  private filterValues: Array<ValueSelected>;

  private category: string;
  @observable
  private searchText: string;

  public init(params: IFloatingFilterParams & { categories: Array<EnumerationTypeCategory> }) {
    if (params.categories != null) {
      // TODO sort by name
      this.categories = params.categories;
    } else {
      throw new Error("Categories parameter is missing");
    }
    super.init(params);
    this.i18n = Container.instance.get(I18N);
    if (this.i18n != null) {
      this.DROPDOWN_NAME = this.i18n.tr('grid.noFilter', { ns: "common" });
    }
    super.setupGui();
  }

  public getEnumerationTypes() {
    this.filterValues = this.categories.map(cat => {
      return {
        id: cat.category,
        name: this.i18n.tr(cat.name),
        selected: false,
        hide: false,
      };
    })
    this.dispose();
    this.disposables.push(...this.filterValues.map(fv => this.bindingEngine.propertyObserver(fv, 'selected').subscribe(this.filterValuesChanged.bind(this))));
  }

  public filterValuesChanged(newVal: boolean, oldVal: boolean) {
    if (newVal != oldVal && !this.firstTime) {
      this.DROPDOWN_NAME = this.getModelAsString();
      (this.params as IFloatingFilterParams).parentFilterInstance((instance) => {
        instance.setModel({ filterType: 'set', values: this.filterValues.filter(v => v.selected).map(v => v.id) });
      });
    }
  }

  public searchTextChanged(newVal: string, oldVal: string) {
    if (newVal != oldVal) {
      this.filterValues.forEach(filterValue => {
        filterValue.hide = !(filterValue.name.toLowerCase().includes(newVal.toLowerCase()));
      });
    }
  }

  public async onOpenDropDown() {
    this.dispose();
    let oldFilterValues = this.filterValues;
    this.getEnumerationTypes();
    if (oldFilterValues && oldFilterValues.length > 0) {
      oldFilterValues.forEach(oldFilterValue => {
        if (this.filterValues && this.filterValues.some(x => x.name == oldFilterValue.name)) {
          this.filterValues.find(x => x.name == oldFilterValue.name).selected = oldFilterValue.selected;
        }
      });
    } else {
      this.resetFilter();
    }
  }

  public setupContentGui() {
    return `     
      <div class="floating-filter__body__enum">
        <div class="floating-filter__body__search">
          <ui-field t="[label]common:grid.searchShort">
            <ui-input type="text" value.bind="searchText & debounce:500" clear>
              <ui-input-addon icon="digi-search"></ui-input-addon>
            </ui-input>
          </ui-field>
        </div>

        <div class="floating-filter__body__enum__list">
          <div repeat.for="filterValue of filterValues" if.bind="!filterValue.hide" class="floating-filter__body__enum__list__elem">
            <ui-checkbox checked.bind="filterValue.selected" title.bind="filterValue.name">
              \${filterValue.name}
            </ui-checkbox>
          </div>
        </div>
      </div>`;
  }

  public resetFilter() {
    if (this.filterValues != null) {
      this.filterValues.forEach(filterValue => {
        filterValue.selected = false;
      });
    }
  }

  public onParentModelChanged(parentModel: any, filterChangedEvent?: FilterChangedEvent) {
    if (parentModel) {
      if (parentModel.values) {
        if (!this.filterValues) {
          this.getEnumerationTypes();
        }
        parentModel.values.forEach(id => {
          let value = this.filterValues.find(v => v.id == id);
          if (value) {
            value.selected = true;
          }
        });
      }
    } else if (this.filterValues) {
      this.resetFilter();
    }
    this.DROPDOWN_NAME = this.getModelAsString();
  }

  public getModelAsString(): string {
    if (this.filterValues && this.filterValues.some(x => x.selected)) {
      return `${this.i18n.tr('grid.filterOoo', { ns: "common" })} <span style='background-color: gray; color: white; padding: 0 5px 0 5px; border-radius: 20px;'>${this.filterValues.filter(x => x.selected).length}</span>`;
    }
    else {
      return this.i18n.tr('grid.noFilter', { ns: "common" });
    }
  }

  public setupContentGuiSideFilter(): string {
    return `<h5>Filtre à implémenter</h5>`
  }
}
