import { Injectable } from '@angular/core';
import { Effect, Actions } from '@ngrx/effects';
import { Action, Store } from '@ngrx/store';

import 'rxjs/add/operator/map';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/switch';
import 'rxjs/add/observable/timer';

import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';

import * as ApplicationActions from './actions';
import { AuthService } from '../auth/auth.service';
import { MessageService } from 'node_modules/primeng/api';
import { AppConfig } from '../AppConfig/AppConfig';

@Injectable()
export class ApplicationEffects {

    DisableAutoLogout = true;
    TIMEOUT = false;
    interval: any;
    intervalMsg: any;
    countDownValue = 0;
    InterfaceSeasonTimeOut = 0;

    APPLICATION_TIMEOUT_TIME = 1000 * 60;
    TIMEOUT_COUNT_DOWN = 30;
    TIMEOUT_COUNT_DOWN_INTERVAL = 10;

    @Effect()
    extendApplicationTimeout$ = this.actions$
        .switchMap((action: Action) => {
            // console.log("action");
            // console.log(action);
            // var d = new Date();
            // console.log(d);
            if (this.TIMEOUT === true && action.type !== ApplicationActions.LOG_OUT) {
                // console.log(action.type);
                this.TIMEOUT = false;
            }
            return Observable.timer(this.APPLICATION_TIMEOUT_TIME);
        })
        .map(() => {
            if (this.DisableAutoLogout === false && this.checkIsTimeOut() === true && this.TIMEOUT === false) {
                console.log('LogoutTimer first', this.TIMEOUT_COUNT_DOWN);
                this.TIMEOUT = true;
                this.countDownValue = this.TIMEOUT_COUNT_DOWN - this.TIMEOUT_COUNT_DOWN_INTERVAL;
                if (this.InterfaceSeasonTimeOut > (this.TIMEOUT_COUNT_DOWN * 1000)
                && this.countDownValue > 0) {
                    this.messageService.add({
                        severity: 'error', summary: 'Logout Warning',
                        detail: 'No action detected in a period of time. System will auto logout if no action detect within '
                        + this.TIMEOUT_COUNT_DOWN + ' secound!'
                    });
                    this.countDownMessage();
                } else {
                    this.authService.logOut();
                }
            }
            return new ApplicationActions.LogOut();
        });

    constructor(private actions$: Actions, private authService: AuthService,
        public messageService: MessageService, private appconfig: AppConfig) {

        appconfig.onupdate.subscribe(result => {
            try {
                // console.log("AppConfig");
                // console.log(result);
                if (result) {
                    const s = AppConfig.systemSettings;
                    const i = s.find(a => a.name === 'InterfaceSeasonTimeOut');
                    // console.log(s);
                    // console.log(i);
                    if (i) {
                        this.DisableAutoLogout = false;
                        this.InterfaceSeasonTimeOut = 1000 * 60 * parseInt(i.value, 10);
                        if (parseInt(i.value, 10) >= 1) {
                            this.APPLICATION_TIMEOUT_TIME = 1000 * 60 * parseInt(i.value, 10);
                            console.log('TIMEOUT');
                            console.log(this.APPLICATION_TIMEOUT_TIME);
                        }
                    }
                    const c = s.find(a => a.name === 'LogoutTimer');
                    if (c) {
                        this.TIMEOUT_COUNT_DOWN = parseInt(c.value, 10);
                        console.log('LogoutTimer');
                        console.log(this.TIMEOUT_COUNT_DOWN);
                    }
                    const int = s.find(a => a.name === 'LogoutTimerInterval');
                    if (int) {
                        this.TIMEOUT_COUNT_DOWN_INTERVAL = parseInt(int.value, 10);
                        console.log('LogoutTimerInterval');
                        console.log(this.TIMEOUT_COUNT_DOWN_INTERVAL);
                    }
                    if (this.APPLICATION_TIMEOUT_TIME > (this.TIMEOUT_COUNT_DOWN * 1000)) {
                        this.APPLICATION_TIMEOUT_TIME -= (this.TIMEOUT_COUNT_DOWN * 1000);
                        console.log('TIMEOUT 2', this.APPLICATION_TIMEOUT_TIME);
                    }
                }
            } catch (error) {
                console.log(error);
            }
        });


    }

    countDownMessage() {
        this.intervalMsg = setInterval(() => {
            if (this.checkIsTimeOut() === false) {
                clearInterval(this.intervalMsg);
                this.TIMEOUT = false;
                this.messageService.add({
                    severity: 'info', summary: 'Logout Cancel',
                    detail: 'New action detected. Your current session has been extended.'
                });
                return;
            }

            if (this.countDownValue > 0) {
                this.messageService.add({
                    severity: 'error', summary: 'Logout Warning',
                    detail: 'No action detected in a period of time. System will auto logout if no action detect within '
                    + this.countDownValue + ' secound!'
                });
                this.countDownValue -= this.TIMEOUT_COUNT_DOWN_INTERVAL;
            } else {
                clearInterval(this.intervalMsg);
                if (this.TIMEOUT) {
                    this.authService.logOut();
                }
            }
        }, this.TIMEOUT_COUNT_DOWN_INTERVAL * 1000);
    }

    checkIsTimeOut(): boolean {
        const actionTime = this.authService.getLastActionTime();
        console.log('actionTime', actionTime);
        if (!actionTime || actionTime === null) { return true; }

        const at = new Date(actionTime);
        console.log('at', at.getTime());
        const ct = new Date();
        ct.setMilliseconds(ct.getMilliseconds() - this.APPLICATION_TIMEOUT_TIME);
        console.log('ct', ct.getTime());
        if (at.getTime() > ct.getTime()) {
            console.log('checkIsTimeOut false');
            return false;
        }
        return true;
    }

    countDown() {
        this.interval = setInterval(() => {
            const actionTime = this.authService.getLastActionTime();
            console.log('actionTime', actionTime);
            if (actionTime) {
                const at = new Date(actionTime);
                console.log('at', at.getTime());
                const ct = new Date();
                ct.setMilliseconds(ct.getMilliseconds() - this.APPLICATION_TIMEOUT_TIME);
                console.log('ct', ct.getTime());
                if (at.getTime() > ct.getTime()) {
                    console.log('bigger than');
                    this.TIMEOUT = false;
                }
            }
            if (this.TIMEOUT) {
                this.authService.logOut();
            } else {
                this.messageService.add({
                    severity: 'info', summary: 'Logout Cancel',
                    detail: 'New action detected. Auto logout temporarily canceled.'
                });
            }
            clearInterval(this.interval);
        }, 30000);

    }

}
