import { View, ViewCompiler, ViewResources, ViewSlot } from "aurelia-templating";
import { SideFilter } from "./SideFilter";
import { IFilterParams, IFloatingFilterParams } from "ag-grid-community";
import { BindingEngine, Disposable, createOverrideContext } from "aurelia-binding";
import { Container } from 'aurelia-framework';

export abstract class BaseFilterBase extends SideFilter {
  protected bindingEngine: BindingEngine;
  protected disposables: Array<Disposable>;
  protected DROPDOWN_NAME: string = null;
  protected DROPDOWN_ICON: string = 'digi-filter';
  protected eGui: HTMLElement;
  protected firstTime: boolean = true;
  protected floatingFilterHeaderTitle: string;
  protected params: IFilterParams | IFloatingFilterParams;
  protected showInputField: boolean;
  protected showDropdown: boolean;
  protected showEmptyFieldsCheckbox: boolean = false;
  protected view: View;
  protected viewSlot: ViewSlot;

  init(params: IFilterParams | IFloatingFilterParams) {
    this.params = params;
    // Global visibility config
    if (this.config.agGridConfig.showEmptyFieldsCheckbox) {
      this.showEmptyFieldsCheckbox = true;
    }
    // Override global visibility config if specified in colDef
    let colDefShowEmptyCheckbox = this.params.column.getColDef().filterParams?.showEmptyFieldsCheckbox;
    if (colDefShowEmptyCheckbox != null) {
      this.showEmptyFieldsCheckbox = colDefShowEmptyCheckbox;
    }
    this.showInputField = false;
    this.showDropdown = true;
    this.floatingFilterHeaderTitle = this.i18n.tr('grid.filter', { ns: "common" }) + " " + this.params.column.getColDef().headerName.toLowerCase();
    this.bindingEngine = Container.instance.get(BindingEngine);
    this.disposables = new Array();
    if (this.applyObservers) {
      this.applyObservers();
    }
  }

  async setupGui(compileView: boolean = true, showFilterButton: boolean = false) {
    this.eGui = document.createElement('div');
    this.eGui.style.width = '100%';
    this.eGui.style.height = '100%';

    if (compileView) {
      let html = this.setBaseView(await this.setupContentGui(), this.showInputField, this.setupInputField, this.showDropdown, this.floatingFilterHeaderTitle, showFilterButton);

      let viewCompiler = Container.instance.get(ViewCompiler);
      let viewResources = Container.instance.get(ViewResources);
      let viewFactory = viewCompiler.compile(html, viewResources);
      this.view = viewFactory.create(Container.instance);
      this.viewSlot = new ViewSlot(this.eGui, true);
      this.viewSlot.add(this.view);
      this.view.bind(this, createOverrideContext(this));
      this.viewSlot.attached();
    }
  }

  public getGui(): HTMLElement {
    return this.eGui;
  }

  protected dispose() {
    this.disposables?.forEach(x => x.dispose());
  }

  setBaseView(content: string, showInputField: boolean, setupInputField: Function, showDropdown: boolean, floatingFilterHeaderTitle: string, showFilterButton = true) {
    let html: string = "<template>";

    if (showInputField && setupInputField != null) {
      let inputField: string = setupInputField();
      html += `
      <div class="input-field" style="display: inline-block; margin: 0; width: ${showDropdown ? "calc(100% - 36px)" : "100%"}; height: 100%;">
        ${inputField || ''}
      </div>`;
    }
    if (showDropdown) {
      if (showFilterButton) {
        html += `
        <ui-button ref="btnMainDropdown" click.delegate="onOpenCloseDropDown()" class="floating-filter__button" type="solid" icon.bind="DROPDOWN_ICON" ${showInputField ? 'style="width: 32px;"' : ''}>
          <span class="truncate" innerhtml.bind="DROPDOWN_NAME"></span>
        </ui-button>
        <ui-drop close-on-click="false" position="tr" anchor="br"
          attach-to-viewport.one-time="true" anchor-el.bind="btnMainDropdown">`;
      }
      html += `
      <div class="floating-filter__container">
        <div class="floating-filter__header">
          <p>${floatingFilterHeaderTitle}</p>
        </div>
        <div class="floating-filter__body">
          ${(content || '')}   
        </div>          
        <div class="floating-filter__footer">
          <ui-button t="[label]common:grid.resetFilter" click.delegate="resetFilter()" icon="digi-cross-circle"></ui-button>
        </div>
      </div>`;
      if (showFilterButton) {
        html += "</ui-drop>";
      }
    }

    html += "</template>";
    return html;
  }

  public abstract setupContentGui(): string | Promise<string>;
  public setupInputField?(): string;
  public abstract resetFilter(): void;
  protected applyObservers?(): void;
}