backupApp.service('NotificationService', function($rootScope, $timeout, AppService, ServerStatus) {
    
    // Track repeated refresh requests
    var isRefreshing = false;
    var needsRefresh = false;

    var notifications = [];

    this.notifications = notifications;

    function sortFn(a, b) {
        if(a.HasBeenSeen == false && b.HasBeenSeen == true) {
            return -1
        }
        
        if(b.HasBeenSeen == false && a.HasBeenSeen == true) {
            return 1
        }

        if (a.ID < b.ID)
            return -1;
        else if (a.ID > b.ID)
            return 1;
        else
            return 0;
    }

    function refresh_notifications() {

        if (isRefreshing) {
            needsRefresh = true;
            return;
        }

        needsRefresh = false;
        isRefreshing = true;

        AppService.get('/notifications').then(
            function(resp) {
                
                var idmap = {};
                for(var n in resp.data)
                    idmap[resp.data[n].ID] = resp.data[n];

                // Sync map and list
                for (var i = notifications.length - 1; i >= 0; i--)
                    if (!idmap[notifications[i].ID])
                        notifications.splice(i, 1);
                    else {
                        if (idmap[notifications[i].ID].HasBeenSeen == notifications[i].HasBeenSeen)
                            delete idmap[notifications[i].ID];
                        else
                        {
                            notifications.splice(i, 1);
                        }
                    }

                // Then add all new items
                for (var n in idmap)
                    notifications.push(idmap[n]);

                notifications.sort(sortFn);
                
                $rootScope.$broadcast('notificationschanged');

                isRefreshing = false;
                if (needsRefresh)
                    refresh_notifications();

            },
            function(resp) {
                isRefreshing = false;
            }
        );
    };

    this.watch = function(scope, m) {
        scope.$on('notificationschanged', function() {
            $timeout(function() {
                if (m) m();
                scope.$digest();
            });
        });

        if (m) $timeout(m);
        return notifications;
    }

    var first = ServerStatus.state.lastNotificationUpdateId == -1;
    $rootScope.$on('serverstatechanged.lastNotificationUpdateId', function() { 
        // We always refresh, so no need to use the initial event
        if (first)
            first = false;
        else
            refresh_notifications();
    });

    this.refresh_notifications = refresh_notifications;

    this.getAllNotifications = function() {
        return new Promise((resolve, reject) => {
            AppService.get('/notifications/all').then(
                function(resp) {
                    const notifications = resp.data;
                    notifications.sort(sortFn);

                    resolve(notifications);
                },
                function() { reject()}
            );
        })
    }

    refresh_notifications();
});
