import { Router, activationStrategy } from 'aurelia-router';
import { CustomLogger } from '../modules/custom-logger';
import { EventAggregator } from 'aurelia-event-aggregator';
import { Container } from 'aurelia-framework';
import { I18N } from 'aurelia-i18n';
import { Box } from '../modules/box';
import { Datacontext } from '../data/data-context';
import { Config } from '../config';
import { AuthService } from '../security/auth-service';
import { DisposableViewModelBase } from './disposable-view-model-base';
import { Actions } from '../constants/constants';


export abstract class ViewModelBase extends DisposableViewModelBase {
    public authService: AuthService;
    public eventAggregator: EventAggregator;
    public abstract get ribbonHeaderText(): string;
    public abstract get ressourceName(): string;
    public showLoadingSpinner: boolean = false;
    public i18n: I18N;
    public box: Box;
    public isDialogView: boolean = false;
    public datacontext: Datacontext;
    public config: Config;

    constructor(public router: Router, public logger: CustomLogger) {
        super();
        this.eventAggregator = Container.instance.get(EventAggregator);
        this.i18n = Container.instance.get(I18N);
        this.box = Container.instance.get(Box);
        this.datacontext = Container.instance.get(Datacontext);
        this.config = Container.instance.get(Config);
        this.authService = Container.instance.get(AuthService);
    }

    public async activate(params: any) {
        if (params?.dialogType) this.isDialogView = true;
    }

    public navigateBack(): void {
        this.router.navigateBack();
    }

    public determineActivationStrategy() {
        return activationStrategy.replace; //replace the viewmodel with a new instance
        // or activationStrategy.invokeLifecycle to invoke router lifecycle methods on the existing VM
        // or activationStrategy.noChange to explicitly use the default behavior
    }

    public canDeactivate(): any {
        return Promise.resolve(true);
    }

    public entityMatcher = (a, b) => {
        var a_id = a != null && a.id != null ? a.id : a;
        var b_id = b != null && b.id != null ? b.id : b;
        if (a_id == "") a_id = 0;
        if (b_id == "") b_id = 0;
        return (a_id != null && b_id != null && a_id.toString != null && b_id.toString != null) ? a_id.toString() === b_id.toString() : a_id == b_id;
    };

    public log(message: string, data: any, showToast: boolean, translationOptions?: any): void {
        message = this.i18n.tr(message, translationOptions);
        this.logger.Log(message, data, 'ViewModelBase', showToast);
    }

    public logError(message: string, error: any, showToast: boolean = true, translationOptions?: any): void {
        message = this.i18n.tr(message, translationOptions);
        this.logger.LogError(message, error, 'ViewModelBase', showToast);
    }

    /**
     *
     * @param {string} url
     * @param {{ trigger: boolean, replace: boolean }} [options]
     * @memberof ViewModelBase
     */
    public navigateTo(url: string, options?: { trigger: boolean, replace: boolean }) {
        if (options == null) options = { replace: false, trigger: true };
        if (options.replace == null) options.replace = false;
        if (options.trigger == null) options.trigger = true;
        this.router.navigate(url, options);
    }

    public get canAdd() {
        return this.authService.checkAccess(this.ressourceName, Actions.Create);
    }

    public get canDelete() {
        return this.authService.checkAccess(this.ressourceName, Actions.Delete);
    }

    public get canUpdate() {
        return this.authService.checkAccess(this.ressourceName, Actions.Update);
    }
}
