/* Copyright CloudLinux Zug GmbH 2010-2017 All Rights Reserved
 *
 * Licensed under CLOUD LINUX LICENSE AGREEMENT
 * http://cloudlinux.com/docs/LICENSE.TXT
 */

import {SafeHtml, DomSanitizer} from '@angular/platform-browser';
import {Component, OnInit, OnDestroy, ViewEncapsulation, trigger, state, style, transition, animate} from "@angular/core"
import {NotificationsService} from "./../services/notifiaction_service"
import {MaxPipe} from "./pipes/max"
import {Icons} from "./notification_icons"

@Component({
    selector: "simple-notification",

    inputs: [
        "item",
        "timeOut",
        "position",
        "clickToClose",
        "maxLength",
        "showProgressBar",
        "pauseOnHover",
        "theClass",
        "rtl",
        "animate",
        "icons",
        "open"
    ],
    encapsulation: ViewEncapsulation.None,
    animations: [
        trigger("enterLeave", [
            state("enter", style({opacity: 1, transform: "translateX(0)"})),
            transition("* => enter", [
                style({opacity: 0, transform: "translateX(5%)"}),
                animate(200)
            ]),
            state("leave", style({opacity: 0, transform: "translateX(-5%)"})),
            transition("* => leave", [
                style({opacity: 1, transform: "translateX(0)"}),
                animate(200)
            ]),
        ])
    ],
    template: require('./../../templates/notification.html'),
    styles: [require('../../styles/notification.less')]
})

export class NotificationComponent implements OnInit, OnDestroy {
    constructor(
        private _service: NotificationsService,
        private _sanitizer: DomSanitizer
    ) {}

    public icons: Icons;

    ////// Inputs
    public safeSvg: SafeHtml;
    public item: Notification;
    public maxLength: number;
    public showProgressBar: boolean;
    public theClass: string;
    public rtl: boolean;
    public animate: boolean;

    public overrides: any;

    ////// Locals

    // Progress bar variables
    public progressWidth: number = 0;
    private stopTime: boolean = false;
    private timer: any;
    private steps: number;
    private speed: number;
    private count: number = 0;
    private start: any;
    private diff: any;

    private timeOut: number;
    private position: number;
    private clickToClose: boolean;
    private pauseOnHover: boolean;
    private open: boolean;

    ngOnInit(): void {
        if (this.animate) this.item["state"] = "enter";
        if (this.item.override) this.attachOverrides();
        if (this.timeOut !== 0) this.startTimeOut();
        this.safeSvg = this._sanitizer.bypassSecurityTrustHtml(this.icons[this.item.type]);
    }

    startTimeOut(): void {
        this.steps = this.timeOut / 10;
        this.speed = this.timeOut / this.steps;
        this.start = new Date().getTime();
        this.timer = setTimeout(this.instance, this.speed);
    }

    onEnter(): void {
        if (this.pauseOnHover) this.stopTime = true
    }

    onLeave(): void {
        if (this.pauseOnHover) {
            this.stopTime = false;
            setTimeout(this.instance, (this.speed - this.diff));
        }
    }

    setPosition(): number {
        return this.position !== 0 ? this.position * 90 : 0;
    }

    removeOnClick(): void {
        if (this.clickToClose) this._remove()
    }

    // Attach all the overrides
    attachOverrides(): void {
        Object.keys(this.item.override).forEach(a => this[a] = this.item.override[a])
    }

    ngOnDestroy(): void { clearTimeout(this.timer) }

    private instance = () => {
        this.diff = (new Date().getTime() - this.start) - (this.count * this.speed);
        if (this.count++ === this.steps) this._remove();
        else if (!this.stopTime) {
            if (this.showProgressBar) this.progressWidth += 100 / this.steps;
            this.timer = setTimeout(this.instance, (this.speed - this.diff));
        }
    };

    private _remove() {
        if (this.animate) {
            this.item["state"] = "leave";
            setTimeout(() => this._service.set(this.item, false), 200)
        }

        else this._service.set(this.item, false)
    }
}

export interface Notification {
    id: string
    type: string
    createdOn: Date
    title?: string
    content?: string
    override?: any
    html?: any
}


export interface Options {
    timeOut?: number;
    showProgressBar?: boolean;
    pauseOnHover?: boolean;
    lastOnBottom?: boolean;
    clickToClose?: boolean;
    maxLength?: number;
    maxStacks?: number;
    preventDuplicates?: number;
    preventLastDuplicates?: boolean | string;
    theClass?: string;
    rtl?: boolean;
    animate?: boolean;
    icons?: Icons;
    open?: boolean;
}
