import { Router } from 'aurelia-router';
import { DialogController, DialogService } from 'aurelia-dialog';
import { ValidationController } from 'aurelia-validation';
import { Disposable, inject, InlineViewStrategy, noView } from 'aurelia-framework';
import { BoxSize } from '../../constants/constants';

@inject(DialogController, ValidationController, Router)
@noView()
export abstract class FloatingBoxViewModel {
    protected dialogService: DialogService;
    protected dialogController: DialogController;

    protected disposables: Disposable[] = [];

    private _size: BoxSize;

    constructor(private _view: string, size: BoxSize = 'sm') {
        this._size = size;
    }

    public async activate(config) {
        this.dialogService = config.dialogService;
        document.body.addEventListener('click', this.clickOutsideListener);
    }
    public async close(): Promise<void> {
        this.dispose();
        this.dialogController.close(true);
    }
    public async cancel(): Promise<void> {
        this.dispose();
        this.dialogController.cancel();
    }
    protected async dispose(): Promise<void> {
        this.disposables.forEach(d => d.dispose());
        document.body.removeEventListener('click', this.clickOutsideListener);
    }
    public async setDialogController(controller: DialogController): Promise<void> {
        this.dialogController = controller;
    }

    public get size(): BoxSize {
        return this._size;
    }
    public get view(): string {
        return this._view;
    }

    private clickOutsideListener = (event: Event) => {
        if (!this.dialogController.settings.lock
            && hasParent(event.target as HTMLElement, "ui-viewport__body")
            && !hasParent(event.target as HTMLElement, "floating-box-view")) {
            this.close();
        }
    };
}