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

define(['hp/core/EventDispatcher',
    'hp/core/Router',
    'hp/core/LinkTargetBuilder',
    'hp/core/UrlFragment',
    'hp/model/DevelopmentSettings',    
    'hp/services/IndexService',
    'hp/services/IndexFilter',
    'fs/model/activity/ActivityResource',    
    'hp/services/Log'

    ], 
function(EventDispatcher, router, linkTargetBuilder, urlFragment, settings,
    indexService, IndexFilter, resource, log) {"use strict";

    var SearchPresenter = ( function() {

        // consts/statics can go here.
        //

        /**
         * @constructor
         * @type {SearchPresenter}
         */
        function SearchPresenter() {

            var dispatcher = new EventDispatcher();
            var parameters = {};
            var filter;
            var moreResult = false;

            function parseParameters(url) {
                var parameters = urlFragment.getParameters(url);
                parameters.start = parseInt(parameters.start, 10) || 0;
                parameters.count = parseInt(parameters.count, 10) || settings.getMaxIndexItems();
                return parameters;
            }
            
            function onIndexResultsSuccess(data) {
                moreResult = data && (data.total > (parameters.start + parameters.count));
                dispatcher.fire('indexResultsChange', data);
            }
            
            function onIndexResultsError(errorInfo) {
                log.warn(errorInfo.errorMessage);
            }
            
            function search(userQuery, start, count) {
                filter = new IndexFilter();
                filter.ensureDefaults(null, start, count);  
                // set hidden properties filtering so that we don't show them to a user              
                resource.initializeDefaultFilter(filter);
                filter.setUserQuery(userQuery);
                indexService.getFilteredIndexResources(filter, {
                    success : onIndexResultsSuccess,
                    error : onIndexResultsError
                });
            }
            
            this.hasMoreResult = function() {
                return moreResult;
            };
            
            this.getQuery = function() {
                return parameters.query;
            };
            
            /**
             * Determines which attributes match the filter used and returns them.
             */
            this.resultMatches = function(indexResult) {
                var matches = [];
                if (indexResult.attributes) {
                    $.each(indexResult.attributes, function (name, value) {
                        if (filter.match(name, value)) {
                            matches.push([name, value]);
                        }
                    });
                }
                return matches;
            };
            
            /**
             * @public
             */
            this.search = search;
            
            this.searchMore = function() {
                parameters.start = parameters.start + parameters.count;
                search(parameters.query, parameters.start, parameters.count);
            };

            /**
             * @public
             */
            this.init = function() {
                router.watch('search', '/search.*', {
                    parent: '/search',
                    change: function (location) {
                        parameters = parseParameters(location);
                        search(parameters.query, parameters.start, parameters.count);
                }});
            };
            
            /**
             * @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);
            };

            /**
             * @public
             * Remove a listener for a specified event.
             * @param {string} eventName The name of the event.
             * @param {function(...)}
             */
            this.off = function(eventName, callback) {
                dispatcher.off(eventName, callback);
            };

        }

        return new SearchPresenter();
    }());

    return SearchPresenter;
});
