// (C) Copyright 2020 Hewlett-Packard Enterprise Company, L.P.

define(['hp/core/EventDispatcher',
    'hp/model/NotificationResource',
    'hp/core/NotificationFormatter',
    'hp/model/Session',
    'hp/model/DevelopmentSettings',
    'hp/services/Log'], 
function(EventDispatcher, NotificationResource, notificationFormatter,
    session, settings, log) {"use strict";

    var SessionNotificationsPresenter = ( function() {
      
        var FLASH_INTERVAL = 5000; // 5 seconds
      
        /**
         * @constructor
         * @type {SessionNotificationsPresenter}
         */
        function SessionNotificationsPresenter() {

            var dispatcher = new EventDispatcher();
            var timer = null;
            var notificationResource;
            var enableDetails = false;
            var flashNotifications = [];
            var flashTimer = null;
            
            function flash() {
                var notification;
                if (flashNotifications.length > 0) {
                    notification = flashNotifications.shift();
                    dispatcher.fire('showFlash', notification);
                    flashTimer = setTimeout(flash, FLASH_INTERVAL);
                } else {
                    dispatcher.fire('clearFlash');
                    flashTimer = null;
                }
            }
            
            function addFlash(notification) {
                flashNotifications.push(notification);
                if (! flashTimer) {
                    flash();
                }
            }
            
            function flashStatusChanges(data) {
                var length = data.notifications.length;
                for (var i=0; i<length; i++) {
                    var notification = data.notifications[i];
                    if (notification._statusChanged) {
                        addFlash(notification);
                    }
                }
            }
            
            function poll() {
                var user = session.getUser();
                // don't bother if we don't have a session
                if (user) {
                    notificationResource.filter().setProperty('owner', user);
                    notificationResource.getNotifications();
                }
                
                clearTimeout(timer);
                timer = setTimeout(poll, settings.getActivityRefreshInterval());
            }
            
            // Resource events
            
            function onNotificationsChange(data) {
                dispatcher.fire('notificationsChange', data);
                flashStatusChanges(data);
                if (enableDetails) {
                    notificationResource.getSelectionDetails();
                }
            }
            
            function onNotificationsError(errorInfo) {
                dispatcher.fire('notificationsError', errorInfo);
            }
            
            function onSelectionChange(data) {
                dispatcher.fire('selectionChange', data);
                if (enableDetails) {
                    notificationResource.getSelectionDetails();
                }
            }
            
            function onResourceChange(data) {
                dispatcher.fire('notificationChange', data.selection.notification);
            }
            
            function onResourceError(errorInfo) {
                dispatcher.fire('resourceError', errorInfo);
            }
            
            /**
             * @public
             */
            this.init = function () {
                notificationResource = new NotificationResource();
                notificationResource.init();
                // only get recent ones
                notificationResource.filter().setProperty('modified', '<4h');
                
                notificationResource.on('notificationsChange', onNotificationsChange);
                notificationResource.on('notificationsError', onNotificationsError);
                notificationResource.on('selectionChange', onSelectionChange);
                notificationResource.on('resourceChange', onResourceChange);
                notificationResource.on('resourceError', onResourceError);
            };
            
            this.poll = function () {
                clearTimeout(timer);
                timer = setTimeout(poll, settings.getActivityRefreshInterval());
            };
            
            this.selectUri = function (uri) {
                enableDetails = true;
                notificationResource.selectUri(uri);
            };
            
            this.selectTimestamp = function (timestamp) {
                enableDetails = true;
                notificationResource.selectTimestamp(timestamp);
            };
            
            this.selectNext = function () {
                enableDetails = true;
                notificationResource.selectNext();
            };
            
            this.selectPrevious = function () {
                enableDetails = true;
                notificationResource.selectPrevious();
            };
            
            this.deselect = function () {
                enableDetails = false;
                notificationResource.deselect();
            };
            
            this.add = function (notification, doFlash) {
                notification._statusChanged = true; // to trigger flash
                notificationResource.add(notification);
            };
            
            this.remove = function (notification) {
                notificationResource.remove(notification);
            };
            
            this.clear = function () {
                notificationResource.clear();
            };
            
            /**
             * @public
             * Add a listener for a specified event.
             * @param {string} eventName The name of the event.
             * @param {function(...)}
             */
            this.on = function (eventName, callback) {
                dispatcher.on(eventName, callback);
            };
            
            this.off = function (eventName, callback) {
                dispatcher.off(eventName, callback);
            };
        }

        return SessionNotificationsPresenter;
    }());

    return SessionNotificationsPresenter;
});
