import { I18N } from 'aurelia-i18n';

import { ICellEditorComp, ICellEditorParams, ICellRendererComp, ICellRendererParams } from "ag-grid-community";
import { createOverrideContext, Container, ViewResources, autoinject } from 'aurelia-framework';
import { View, ViewCompiler, ViewSlot } from "aurelia-templating";

@autoinject
export default class CustomHtmlRendererEditor implements ICellRendererComp, ICellEditorComp {
  protected eGui: HTMLElement;

  protected view: View;
  protected viewSlot: ViewSlot;
  protected params: (ICellRendererParams | ICellEditorParams) & { isPopup: boolean, getHtml: (vm: any) => string };  
  public i18n: I18N;
  public value;  
  private get uiSelect(): any {
    let controllers: Array<any> = (<any>this.view)?.controllers;
    if (controllers?.length > 0) {
      let uiSelectController = controllers.find(c => c.viewModel?.constructor.name == "UISelect");
      if (uiSelectController != null) {
        return uiSelectController.viewModel;
      }
    }
  }

  constructor() { }

  public getValue() {
    return this.params.value;
  }

  isPopup(): boolean {
    return this.params.isPopup ?? false;
  }

  public init(params: any) {
    this.params = params;
    this.setupGui();
  }

  public setupGui() {
    this.eGui = document.createElement('div');
    this.eGui.style.width = '100%';
    this.eGui.style.height = '100%';

    let content: string = this.setupContentGui();
    let html: string = `<template>${content}</template>`;

    this.i18n = Container.instance.get(I18N);
    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();
  }

  afterGuiAttached(): void {
    setTimeout(() => this.uiSelect?.open(), 10);
  }

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

  public refresh(params): boolean {
    return true;
  }

  public destroy() {
    // Special rule for UISelect
    this.uiSelect?.close();
    if (this.uiSelect != null) {
      let id = this.uiSelect.select2Instance.id;
      let uiScrollElts = $('.ui-scroll');
      let scrollEvent = 'scroll.select2.' + id;
      let resizeEvent = 'resize.select2.' + id;
      uiScrollElts.off(scrollEvent);  
      uiScrollElts.off(resizeEvent);  
    }
    
    if (this.view) this.view.unbind();
    if (this.viewSlot) this.viewSlot.detached();
  }


  public setupContentGui(): string {
    return this.params.getHtml(this);
  }
}
