import ngModule from '../module';

/**
 * Saves and loads the token for the current logged in user.
 *
 * @property {String} token The current login token or %null
 */
export default class Token {
    constructor(vnInterceptor, $http, $rootScope) {
        Object.assign(this, {
            vnInterceptor,
            $http,
            $rootScope
        });

        try {
            this.getStorage(sessionStorage);
            this.remember = true;

            if (!this.token) {
                this.getStorage(localStorage);
                this.remember = false;
            }
        } catch (e) {}
    }

    set(token, tokenMultimedia, created, ttl, remember) {
        this.unset();

        Object.assign(this, {
            token,
            tokenMultimedia,
            created,
            ttl,
            remember
        });
        this.vnInterceptor.setToken(token, tokenMultimedia);
        try {
            if (remember)
                this.setStorage(localStorage, token, tokenMultimedia, created, ttl);
            else
                this.setStorage(sessionStorage, token, tokenMultimedia, created, ttl);
        } catch (err) {
            console.error(err);
        }
    }

    unset() {
        this.token = null;
        this.tokenMultimedia = null;
        this.created = null;
        this.ttl = null;
        this.remember = null;
        this.vnInterceptor.setToken(null);

        this.removeStorage(localStorage);
        this.removeStorage(sessionStorage);
    }

    getStorage(storage) {
        this.token = storage.getItem('vnToken');
        // Cambio realizado temporalmente
        this.tokenMultimedia = this.token; // storage.getItem('vnTokenMultimedia');
        if (!this.token) return;
        const created = storage.getItem('vnTokenCreated');
        this.created = created && new Date(created);
        this.ttl = storage.getItem('vnTokenTtl');
    }

    setStorage(storage, token, tokenMultimedia, created, ttl) {
        storage.setItem('vnTokenMultimedia', tokenMultimedia);
        storage.setItem('vnToken', token);
        storage.setItem('vnTokenCreated', created.toJSON());
        storage.setItem('vnTokenTtl', ttl);
    }

    removeStorage(storage) {
        storage.removeItem('vnToken');
        storage.removeItem('vnTokenMultimedia');
        storage.removeItem('vnTokenCreated');
        storage.removeItem('vnTokenTtl');
    }

    fetchConfig() {
        const filter = {fields: ['renewInterval', 'renewPeriod']};
        this.$http.get('AccessTokenConfigs/findOne', {filter}).then(res => {
            const data = res.data;
            if (!data) return;
            this.renewPeriod = data.renewPeriod;
            this.stopRenewer();
            this.intervalId = setInterval(() => this.checkValidity(), data.renewInterval * 1000);
        });
    }

    checkValidity() {
        if (this.checking || !this.created) return;
        this.checking = true;
        const renewPeriod = Math.min(this.ttl, this.renewPeriod) * 1000;
        const maxDate = this.created.getTime() + renewPeriod;
        const now = new Date();

        if (now.getTime() <= maxDate) {
            this.checking = false;
            return;
        }

        this.$http.post('VnUsers/renewToken')
            .then(res => {
                const token = res.data;
                this.set(token.id, now, token.ttl, this.remember);
            })
            .finally(() => {
                this.checking = false;
            });
    }

    stopRenewer() {
        clearInterval(this.intervalId);
    }
}
Token.$inject = ['vnInterceptor', '$http', '$rootScope'];

ngModule.service('vnToken', Token);