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

    var TasksPresenter = ( function() {
      
        var STATE_MAP = {'pending' : 'Pending',
            'running' : 'Running', 'finished' : 'Finished'};
        var STATUS_MAP = {'error' : 'Failed',
            'warning' : 'Warning', 'ok' : 'Succeeded'};

        /**
         * @constructor
         */
        function TasksPresenter() {
          
            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.setDefaultFilterProperties = function() {
                var newFilter = new IndexFilter();
                newFilter.setProperty('state', ['active', 'running']);
                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(
                        ['running', 'pending', 'finished'],
                        function(val, index) {
                            return (-1 !== $.inArray(STATE_MAP[val], terms));
                        });
                    if (0 !== states.length) {
                        newFilter.setProperty('state', states);
                    }
                    
                    var statuses = $.grep(
                        ['error', 'warning', 'ok', 'unknown'],
                        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 tasks'];
                }
                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;
                }));
            };
            
            /**
             * 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 TasksPresenter;
    }());

    return TasksPresenter;
});
