import {
  GridColumnIdUtils,
  GridRow, GridRowModelType,
  GridV2, GridV2Column, NotNull
} from "@webbpm/base-package";
import {ChangeDetectionStrategy, Component} from "@angular/core";
import {
  ColDef,
  ICellRendererParams,
  ITooltipParams,
  ValueFormatterParams,
  ValueGetterParams
} from "ag-grid-community";
import {ErvuDataService} from "../../../modules/app/service/ervu-data.service";
import {Subscription} from "rxjs";
import {StaticColumnInitializer} from "./StaticColumnInitializer";
import {StaticGridColumn} from "../../../generated/ru/micord/ervu/property/grid/StaticGridColumn";

@Component({
             moduleId: module.id,
             selector: 'in-memory-static-grid',
             templateUrl: './../../../../../src/resources/template/component/grid/GridV2.html',
             changeDetection: ChangeDetectionStrategy.OnPush
           })
export class InMemoryStaticGrid extends GridV2 {

  @NotNull()
  public dataList: string;
  private subscription: Subscription;

  getRowModelType(): string {
    return GridRowModelType.CLIENT_SIDE;
  }

  protected initGrid() {
    super.initGrid();
    this.subscription = this.injector.get(ErvuDataService).message.subscribe(value => {
      this.rowData = value ? value[this.dataList] : null;
      this.initDeferred.promise.then(() => {
        this.refreshData();
      });
    });
  }

  getColumns(): any[] {
    return this.getScriptsInChildren(GridV2Column)
        .map(columnV2 => columnV2.getScript(StaticGridColumn));
  }

  protected columnV2ToColumnDef(column: GridV2Column): ColDef {
    let gridColumn = column.getScript(StaticGridColumn);
    let colDef = this.columnToColumnDef(gridColumn);
    if (column.renderer) {
      colDef.cellRenderer = (params: ICellRendererParams) => column.renderer.render(params);
    }
    if (column.valueGetter) {
      colDef.valueGetter = (params: ValueGetterParams) => column.valueGetter.get(params);
    }
    if (column.tooltipValueGetter) {
      if (gridColumn.columnTooltip) {
        throw new Error("Only one type of tooltip should be specified: tooltipValueGetter or columnTooltip");
      }
      colDef.tooltipValueGetter = (params: ITooltipParams) => column.tooltipValueGetter.get(params);
    }
    column.setGridRef(this);
    column.setColDef(colDef);
    return colDef;
  }

  protected columnToColumnDef(column: any): ColDef {
    let colDef = StaticColumnInitializer.columnToColumnDef(this, column);
    let columnComp = column.context;
    colDef['columnUid'] = columnComp.getObjectId();

    if (columnComp.cellCssClassRulesProvider) {
      colDef.cellClassRules = columnComp.cellCssClassRulesProvider.getRules();
    }

    if (columnComp.valueFormatter) {
      colDef.valueFormatter = (params?: ValueFormatterParams) => {
        return columnComp.valueFormatter.format(params);
      }
    }
    return colDef;
  }

  public load(): void {
    this.onLoadStart();
    let rows: GridRow[] = [];

    if (this.rowData) {
      this.rowData.forEach((data, i) => {
        let row: GridRow = new GridRow();
        row[GridColumnIdUtils.ROW_UID] = i;
        this.getColumns().forEach(col => {
          let column = col.field.column;
          row[column] = data[column];
        })
        rows.push(row);
      })
    }
    this.getGridApi().setRowData(rows);
    this.onLoadEnd();
  }

  ngOnDestroy() {
    super.ngOnDestroy();
    this.subscription.unsubscribe();
  }
}
