import { DialogOpenResult, DialogCancellableOpenResult } from 'aurelia-dialog';
import { ValidationController } from 'aurelia-validation';
import { ServiceBase } from '../data/service-base';
import * as breeze from 'breeze-client';
import { Router } from 'aurelia-router';
import { CustomLogger } from '../modules/custom-logger';
import { observable, Container } from 'aurelia-framework';
import { ListViewModelBase } from './list-view-model-base';
import { computedFrom } from 'aurelia-binding';

export abstract class EditableListViewModelBase<T extends breeze.Entity> extends ListViewModelBase<T> { // <<<--- Attention: remplacé 'Model.BaseEntityWithId' par 'breeze.Entity'
  constructor(router: Router, logger: CustomLogger, serviceInstance: ServiceBase<T>,) {
    super(router, logger, serviceInstance);
    this.hasChanges = this.manager.hasChanges();
    this.hasChangesSubscriptionKey = this.manager.hasChangesChanged.subscribe((data) => {
      // console.debug("data has change, " + data.hasChanges);
      this.hasChanges = data.hasChanges;
    });
    this.controller = Container.instance.get(ValidationController);
    this.gridOptions.undoRedoCellEditingLimit = 20;
    this.gridOptions.enableCellChangeFlash = true;
    this.gridOptions.undoRedoCellEditing = true;
    this.gridOptions.rowSelection = 'single';
    this.gridOptions.onRowSelected = (event) => {
      if (event != null) {
        this.selectedItem = event.data;
      }
      else {
        this.selectedItem = null;
      }

    }
    this.gridOptions.suppressRowClickSelection = false;
  }
  public hasChanges = false;
  hasChangesSubscriptionKey: number;
  @observable isSaving = false;
  @observable public selectedItem: T;
  @computedFrom("hasChanges", "isSaving")
  public get canSave(): boolean {
    return this.hasChanges && !this.isSaving;
  }
  controller: ValidationController;
  deactivate() {
    this.manager.hasChangesChanged.unsubscribe(this.hasChangesSubscriptionKey);
  }

  public async save(silentSave: boolean = false, byPassLocking?: boolean, navigateBack: boolean = false): Promise<any> {
    let validationResult = await this.controller.validate();
    if (validationResult.valid === true) {
      await this.innerSave(silentSave, byPassLocking)
    }
    else {
      validationResult.results.forEach(r => {
        //var msg = r.message;
        this.logError(r.message, r, (r.message != null));
      });
      throw "There are errors";
    }
  }
  protected undo() {
    this.gridOptions.api.undoCellEditing()
  }
  protected redo() {
    this.gridOptions.api.redoCellEditing();
  }
  private innerSave(silentSave: boolean, byPassLocking?: boolean): Promise<any> {
    var p = new Promise((resolve, reject) => {
      if (this.isSaving === true) {
        this.logError("Save in progress", "", !silentSave);
        reject("Save in progress");
        return;
      }

      if (this.hasChanges === false) {
        this.log("Nothing to save", "", !silentSave);
        reject("Nothing to save");
        return;
      }
      this.controller.validate().then(
        (validationResult) => {
          if (validationResult.valid === true) {
            this.isSaving = true;

            this.service.save(silentSave, byPassLocking)
              .then(() => resolve(true))
              .catch((errors) => {
                reject(errors.message);
              })
              .catch(() => console.log('Rejection of the Promise'))
              .then(() => {
                this.isSaving = false;
              });
          } else {

            validationResult.results.forEach(r => {
              //var msg = r.message;
              this.logError(r.message, r, (r.message != null));
            });
            reject("There are errors");
          }

        }, (rejectReason) => {
          this.logError("Error when saving", rejectReason, true);
          reject(rejectReason);
        }
      )
    });
    return p;
  }
}
