import { IFloatingFilterParams } from "ag-grid-community";
import { EnumerationType, ValueSelected } from "../../model/common-model";
import { Predicate, FilterQueryOp } from "breeze-client";
import { EnumerationTypeService } from '../../services/enumeration-type-service';
import { BaseRelationFloatingFilter } from './base-relation-floating-filter';

export class EnumerationFloatingFilter extends BaseRelationFloatingFilter<EnumerationType> {
  public service: EnumerationTypeService;

  public filterValuesSelected: Array<ValueSelected> = [];

  private category: number;

  public get filterType(): string {
    return "enumeration";
  }

  public async init(params: IFloatingFilterParams & { category: number, service: EnumerationTypeService }) {
    if (params.service == null && params.category != null) {
      this.category = params.category;
      params.service = new EnumerationTypeService(params.category);
    }
    if (params.service == null) {
      throw new Error("service or category parameter is missing");
    }
    await super.init(params);
  }

  public async getEnumerationTypes() {
    this.filterValues = new Array<ValueSelected>();
    this.dispose();
    let predicates: Predicate;
    if (this.category != null) {
      predicates = new Predicate('category', FilterQueryOp.Equals, this.category);
    }
    else {
      predicates = this.service.gridDataSource.predicates;
    }
    let enumerationTypes = await this.service.getEntities(predicates, this.service.gridDataSource.expands, { ...this.service.gridDataSource.queryParameters, onlyActifs: true });
    enumerationTypes.forEach((enumerationType) => {
      let obj = { id: enumerationType.id, name: enumerationType.denomination._translation, selected: false, hide: false }
      this.filterValues.push(obj);
      let disposable = this.bindingEngine.propertyObserver(obj, 'selected').subscribe(this.filterValuesChanged.bind(this));
      this.disposables.push(disposable);
    });
    this.disposables.push(this.bindingEngine.collectionObserver(this.selectedIds).subscribe((changeRecords) => {
      if (!this.selectedIdInternalChange) {
        if (changeRecords[0].removed.length > 0) {
          changeRecords[0].removed.forEach(id => {
            this.filterValues.find(x => x.id == id).selected = false;
          });
        }
        this.selectedIds.forEach(id => {
          this.filterValues.find(x => x.id == id).selected = true;
        })
      }
    }));
    this.filterValues.sortBy("name");
  }

  public filterValuesChanged(newVal: boolean, oldVal: boolean) {
    if (newVal != oldVal && !this.firstTime) {
      this.selectedIdInternalChange = true;
      this.filterValuesSelected.splice(0);
      this.filterValuesSelected.push(...this.filterValues.filter(x => x.selected));
      this.selectedIds.splice(0);
      this.selectedIds.push(...this.filterValuesSelected.map(x => x.id));
      this.DROPDOWN_NAME = this.getModelAsString();
      this.setInstanceModel();
      this.selectedIdInternalChange = false;
    }
  }

  public async onOpenDropDown() {
    this.dispose();
    let oldFilterValues = this.filterValues;
    await 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="valueSearch & debounce:500" autofocus.one-time="true" allow-clear.one-time="true">
              <ui-input-addon icon="digi-search"></ui-input-addon>
            </ui-input>
          </ui-field>
          <div class="ui-check__wrapper" if.bind="showEmptyFieldsCheckbox">
            <ui-checkbox checked.bind="displayEmptyFields">\${ 'grid.displayEmptyFields' | t }</ui-checkbox>
          </div>
        </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 setupContentGuiSideFilter(): string {
    return `
    <div class="col s12 m12 l12">
      <ui-field label.bind="params.colDef.headerName">
        <ui-select multiple t="[placeholder]general.chooseAnOption" value.bind="selectedIds"
          data-source.bind="service.gridDataSource" options-text="denomination._translation"
          filter-properties.bind="['denomination._translation']" options-value="id">
          <option repeat.for="value of filterValuesSelected" value.bind="value.id" selected.bind="true">
            \${value.name}</option>
          <ui-select-header-template>
            <div class="ui-check__wrapper" if.bind="showEmptyFieldsCheckbox">
                <ui-checkbox checked.bind="displayEmptyFields">\${ 'grid.displayEmptyFields' | t }</ui-checkbox>
            </div>
          </ui-select-header-template>
        </ui-select>
      </ui-field>
    </div>
    `;
  }

  public toggleFilterMode() { }

  public setInstanceModel() {
    (this.params as IFloatingFilterParams).parentFilterInstance((instance) => {
      instance.setModel({ filterType: this.filterType, filter: this.filterValues, displayEmptyFields: this.displayEmptyFields });
    });
  }
}
