define(['jquery', 'knockout', 'bluebird', 'tnc/tnc-tools', 'service/xhrService'], function () {
    var $ = require('jquery');
    var Promise = require('bluebird');
    var tncTools = require('tnc/tnc-tools');
    var xhrService = require('service/xhrService');

    var widgetDataHelper = function () {
        var self = this;

        self.widget = {};
        self.layer = {};
        self.queryData = {};

        self.createQueryResultObject = function (resultArray) {
            var returnObject = {};
            for (var i = 0; i < resultArray.length; i++) {
                // create new object with custom propertynames
                var temp = {};
                temp.query = resultArray[i].query;
                temp.result = resultArray[i].result;
                temp.headers = {};

                // get all responseheaders and create an object from the string
                // assign the header object to temp.headers
                var responseHeaderString = resultArray[i].xhr.getAllResponseHeaders();
                var responseHeadersArray = responseHeaderString.split(/\r\n/);
                for (var int = 0; int < responseHeadersArray.length; int++) {
                    var headerArray = responseHeadersArray[int].split(' ');
                    //console.log("todo-lege headers worden nog meegegeven (sowieso na eerste split)");
                    if (headerArray[1] != "" || headerArray[1] != undefined) {
                        temp.headers[headerArray[0]] = headerArray[1];
                    }
                }

                // return the new object with properties: query, result and headers
                returnObject[resultArray[i].query.name] = temp;
            }
            return returnObject;
        };

        self.createOrderedQueriesObject = function (queries) {
            var i;
            var query;

            var orderedQueries = {};
            for (i = 0; i < queries.length; i++) {

                query = queries[i];
                var queryOrder = query.order;
                if (typeof orderedQueries[queryOrder] == 'undefined') orderedQueries[queryOrder] = [];
                orderedQueries[queryOrder].push(query);
            }

            var keys = Object.keys(orderedQueries);
            var queryTree = {};
            for (i = 0; i < keys.length; i++) {
                var key = keys[i];
                for (var subkey in orderedQueries[key]) {
                    if (typeof queryTree[i] == 'undefined') queryTree[i] = [];
                    query = orderedQueries[key][subkey];
                    queryTree[i].push(query);
                }
            }
            return queryTree;
        };

        self.createRequestQuery = function (query) {
            return new Promise(function (resolve, reject) {

                for (var prop in query.settings) {
                    switch (prop) {
                        case 'url':
                            query.settings.url = query.settings.url;
                            break;
                        case 'headers':
                            var headers = query.settings.headers;
                            for (var header in headers) {
                                headers[header] = headers[header];
                            }
                            break;
                    }
                }

                if (typeof query.settings['key'] == 'undefined' || query.settings['key'] == null) {

                    xhrService.customAjax.ajax(query.settings)
                    .done(function (data, status, xhr) {
                        resolve({ query: query, result: data, xhr: xhr });
                    })
                    .fail(reject);
                } else {
                    require(['tnc/tnc-widgetdata-maatwerk'], function (maatwerk) {
                        var layer = self.layer;
                        //var widget = self.widget;
                        //var src = widget.settings.src || '';
                        //var src = 'output.js';
                        //var srcUrl = layer.resourceUrl(src);
                        //var abc = layer.instanceIdString;
                        var folder = layer.template.folder;
                        //var jsUrl = widget.split('?')[0];
                        //var folderPath = folder == "" ? "" : folder + "/";
                        //var jsUrl = '../' + folderPath + src + '#'; //.split('.js')[0];
                        if (maatwerk && maatwerk.getData) {
                            //var params = require('tools/all').urls.getQueryParams(srcUrl);
                            maatwerk.themeFolder = folder;
                            maatwerk.dataFolder = query.settings.key;
                            maatwerk.getData(function (data) {
                                data.query = query;
                                resolve(data);
                            });
                        } else {
                            throw "Maatwerk or Maatwerk.getData does not exist.";
                        }
                    },
                    function (error) {
                        //log(error);
                        reject(error);
                        //self.knockoutItemsLoaded();
                    });
                }
            });
        };

        self.doQueriesInOrder = function (orderedQueries, queryIndex) {
            var queryArray = orderedQueries[queryIndex];
            var promisedQueries = queryArray.map(self.createRequestQuery); // this trigges an ajax request;
            return Promise.all(promisedQueries)
                .then(function (returnedDataArray) {
                    // all requests in the array succeeded;
                    for (var index in returnedDataArray) {
                        var returnedData = returnedDataArray[index];
                        var query = returnedData.query;
                        var xhrObject = returnedData.xhr;
                        var result = returnedData.result;
                        var data = result;
                        if (typeof query.settings['key'] == 'undefined') {
                            if (tncTools.contentTypeIsXml(xhrObject)) {
                                data = tncTools.xmlToJson(result);
                            }
                            else if (tncTools.contentTypeIsHtml(xhrObject)) {
                                data = result;
                            }
                        }

                        // else the datatype is probably json and jquery allready created an object.
                        self.queryData[query.name] = data;
                    }

                    queryIndex++;
                    if (queryIndex < Object.keys(orderedQueries).length) {
                        return widgetDataHelper.doQueriesInOrder(orderedQueries, queryIndex);
                    }
                    if (queryIndex === Object.keys(orderedQueries).length) {
                        return self.queryData;
                    }
                });
        };

        self.parseSettingsToJson = function (queries) {
            for (var index in queries) {
                var query = queries[index];
                query.settings = JSON.parse(query.settings);
            }
            return queries;
        };

        self.doQueries = function () {
            var widget = self.widget;
            var queries = widget.queries;

            return new Promise(function (resolve, reject) {
                queries = self.parseSettingsToJson(queries);
                var orderedQueries = self.createOrderedQueriesObject(queries);
                self.doQueriesInOrder(orderedQueries, 0)
                .catch(function (error) {
                    reject(error);
                })
                .then(function (data) {
                    self.widget.queryData = data;
                    resolve(data);
                });
            });
        };

        self.createItemsArray = function () {
            var countPath = self.widget.countPath;
            if (typeof countPath == 'undefined' || countPath.trim() == "") throw "Het ingestelde querypad bestaat niet";

            var maxNumberOfItems = self.widget.maxNumberOfItems;

            if (countPath.indexOf("queries.") == 0) {
                countPath = countPath.substring(8, countPath.length);
            }

            var pathData = tncTools.tryGetPath(self.queryData, countPath, [], maxNumberOfItems);
            if (pathData.constructor.name !== 'Array') {
                pathData = [pathData];
            }

            return pathData;
        };
    };

    return widgetDataHelper;
});
