// (C) Copyright 2020 Hewlett-Packard Enterprise Company, L.P.
/**
 * @type {NetworksPresenter}
 */
define(['hpsum/model/alert/AlertResource',
    'hp/services/IndexFilter',
    'hp/core/EventDispatcher'], 
function(resource, IndexFilter, EventDispatcher) {"use strict";

    var AlertsPresenter = ( function() {
      
        var STATE_MAP = {'active' : 'Active',
            'cleared' : 'Cleared'};
        var STATUS_MAP = {'error' : 'Critical',
            'warning' : 'Warning', 'ok' : 'Informational'};

        /**
         * @constructor
         */
        function AlertsPresenter() {
          
            var dispatcher = new EventDispatcher();
            
            function indexResultsChange(indexResults) {
                dispatcher.fire("indexResultsChange", indexResults);
            }
            
            function selectionChange(uris) {
                dispatcher.fire("selectionChange", uris);
                if (uris) {
                    // no multi-select yet
                    resource.getItem(uris[0], {
                        success: function (item) {
                            dispatcher.fire("itemChange", item);
                        },
                        error: function (errorMessage) {
                            dispatcher.fire("itemError", errorMessage);
                        }
                    });
                }
            }
            
            this.getIndexResults = function (newFilter, handlers) {
                var filter = resource.getIndexFilter();
                if (! filter || newFilter.isDifferent(filter)) {
                    resource.getIndexResults(handlers, newFilter);
                }
            };
            
            this.haveItems = function () {
                return resource.haveSome();
            };
            
            this.addItem = function (item, handlers) {
                resource.addItem(item, handlers);
            };
            
            this.getItem = function(uri) {
                return resource.getItem(uri);
            };
            
            this.updateSelectedItems = function (item, handlers) {
                resource.updateItems(resource.getSelection().uris, item, handlers);
            };
            
            this.deleteSelectedItems = function (handlers) {
                resource.deleteItems(resource.getSelection().uris, {
                    success: function (name) {
                        resource.removeSelectedUris();
                        if (handlers && handlers.success) {
                            handlers.success(name);
                        }
                    },
                    error: handlers.error
                });
            };
            
            /*this.getAlertsBySource = function (uri, filter, handlers) {
                resource.getIndexResults(filter, {
                    success: function (indexResults) {
                        var result = [];
                        $.each(indexResults.members, function (index, alert) {
                            if (alert.sourceUri === uri) {
                                result.push(alert);
                            }
                        });
                        if (handlers) {
                            handlers.success(result);
                        }
                    },
                    error: (handlers ? handlers.error : null)
                });
            };*/
            
            this.getAlertsSourceOverview = function (uris, handlers) {
                var filter = new IndexFilter();
                filter.setProperty('sourceUri', uris);
                filter.setProperty('state', 'active');
                resource.getIndexResults({
                    success: function (indexResults) {
                        var result = {numError: 0, numWarning: 0, numOk: 0, alerts: []};
                        $.each(indexResults.members, function (index, alert) {
                            result.alerts.push(alert);
                            if ('error' === alert.status) {
                                result.numError += 1;
                            } else if ('warning' === alert.status) {
                                result.numWarning += 1;
                            } else if ('ok' === alert.status) {
                                result.numOk += 1;
                            }
                        });
                        if (handlers) {
                            handlers.success(result);
                        }
                    },
                    error: (handlers ? handlers.error : null)
                }, filter);
            };
            
            this.setDefaultFilterProperties = function() {
                var newFilter = new IndexFilter();
                newFilter.setProperty('state', 'active');
                newFilter.setProperty('status', ['error', 'warning', 'ok', 'unknown']);
                this.getIndexResults(newFilter, null);
            }
            
            this.setFilterProperties = function(properties) {
                var newFilter = new IndexFilter();
                
                if ('string' === $.type(properties)) {
                    if ('Active' === properties) {
                        this.setDefaultFilterProperties();
                        return;
                    }
                    var terms = properties.split(', ');
                    var states = $.grep(
                        ['active', 'cleared'],
                        function(val, index) {
                            return (-1 !== $.inArray(STATE_MAP[val], terms));
                        });
                    if (0 !== states.length) {
                        newFilter.setProperty('state', states);
                    }
                    
                    var statuses = $.grep(
                        ['error', 'warning', 'ok'],
                        function(val, index) {
                            return (-1 !== $.inArray(STATUS_MAP[val], terms));
                        });
                    if (0 !== statuses.length) {
                        newFilter.setProperty('status', statuses);
                    }
                } else {
                    newFilter.setProperties(properties);
                }
                
                this.getIndexResults(newFilter, null);
            };
            
            this.setFilterSearch = function(query) {
                var newFilter = new IndexFilter();
                newFilter.setUserQuery(query);
                this.getIndexResults(newFilter, null);
            };
            
            this.getFilterSummary = function() {
                var result = [];
                var statuses = filter.getProperty('status');
                var states = filter.getProperty('states');
                if (statuses && statuses.length > 0 && statuses.length < 3) {
                    result = result.concat($.map(statuses, function (status) {
                        return STATUS_MAP[status];
                    }));
                }
                if (states && states.length > 0 && states.length < 2) {
                    result = result.concat($.map(states, function (state) {
                        return STATE_MAP[state];
                    }));
                }
                if (0 === result.length) {
                    result = ['All alerts'];
                }
                return result.join(', ');
            };
            
            /**
             * @public
             */
            this.init = function() {
                this.setDefaultFilterProperties();
                resource.on("indexResultsChange", indexResultsChange);
                resource.on("selectionChange", selectionChange);
            };
            
            this.getSelection = function() {
                return resource.getSelection();
            };
            
            this.isSelectedUri = function(uriArg) {
                var result = false;
                $.each(resource.getSelection().uris, function (index, uri) {
                    if (uri === uriArg) result = true;
                });
                return result;
            };
            
            this.toggleSelectedUri = function(uriArg, clear) {
                var uris = $.grep(resource.getSelection().uris, function (uri) {
                    return (uriArg !== uri);
                });
                if (uris.length === resource.getSelection().uris.length) {
                    // wasn't already selected
                    if (clear) {
                        uris = [uriArg];
                    } else {
                        uris.push(uriArg);
                    }
                } else {
                    if (clear) uris = [];
                }
                resource.setSelectedUris(uris);
            };
            
            this.setSelectedUris = function(uris) {
                resource.setSelectedUris(uris);
            };
            
            this.selectAll = function() {
                resource.selectAll();
            };
            
            this.removeSelectedUri = function(uri) {
                var uris = resource.getSelection().uris;
                resource.setSelectedUris($.grep(uris, function(elem, index) {
                    return elem !== uri;
                }));
            };
            
            this.clear = function(uri) {
                var alert = resource.getIndexResultForUri(uri);
                alert.state = 'cleared';
                resource.getIndexResults(null, filter);
            };
            
            this.clearSelected = function() {
                var uris = resource.getSelection().uris;
                $.each(uris, function(index, uri) {
                    var alert = resource.getIndexResultForUri(uri);
                    alert.state = 'cleared';
                });
                resource.clearSelectedUris();
                resource.getIndexResults(null, filter);
            };
            
            this.restore = function(uri) {
                var alert = resource.getIndexResultForUri(uri);
                alert.state = 'active';
                resource.getIndexResults(null, filter);
            };
            
            this.toggleState = function(uri) {
                var alert = resource.getIndexResultForUri(uri);
                if ('cleared' === alert.state) {
                    alert.state = 'active';
                } else {
                    alert.state = 'cleared';
                }
                resource.getIndexResults(null, filter);
            };
            
            this.addNote = function(uri, note) {
                var alert = resource.getIndexResultForUri(uri);
                alert.notes.push(note);
            };
            
            this.assignAlert = function(uri, owner) {
                var alert = resource.getIndexResultForUri(uri);
                if (! owner || 'no one' === owner) {
                    alert.owner = null;
                } else {
                    alert.owner = owner;
                }
            };
            
            /**
             * Add a listener for a specified event.
             * @public
             * @param {string} eventName The name of the event.
             * @param {function(...)}
             */
            this.on = function(eventName, callback) {
                var uris;
                dispatcher.on(eventName, callback);
                /*
                // fire initial state
                switch (eventName) {
                    case 'indexResultsChange':
                        resource.getIndexResults(null, filter);
                        break;
                    case 'selectionChange':
                        dispatcher.fire('selectionChange',
                            resource.getSelection());
                        break;
                    case 'itemChange':
                        uris = resource.getSelection().uris;
                        if (uris && uris.length > 0) {
                            resource.getItem(uris[0],
                                {success: function (item) {
                                    dispatcher.fire('itemChange', item);
                                }}
                            );
                        }
                        break;
                }
                */
            };
            
            this.off = function(eventName, callback) {
                dispatcher.off(eventName, callback);
            };
        }

        return AlertsPresenter;
    }());

    return AlertsPresenter;
});
