define(['bluebird', 'jquery', 'service/xhrService', 'tnc/tnc-tools', 'lib/moment-with-locales', 'tnc/tnc-data-tools'], function () {
    var Promise = require('bluebird');
    var xhrService = require('service/xhrService');
    var tncTools = require('tnc/tnc-tools');
    var $ = require('jquery');
    var moment = require('lib/moment-with-locales');
    var dataTools = require('tnc/tnc-data-tools');
    var config = require('config');

    var exports = {};

    var compare = function(a, b) {
        if (a < b) return -1;
        if (a > b) return 1;
        return 0;
    };

    var qetQueryDataFromMaatwerk = function(settings, themeFolder) {
        return new Promise(function (resolve, reject) {
            require(['tnc/tnc-widgetdata-maatwerk'], function (maatwerk) {
                if (maatwerk && maatwerk.getData) {
                    maatwerk.themeFolder = themeFolder;
                    maatwerk.dataFolder = settings.key;
                    maatwerk.getData(function (data) {
                        resolve(data);
                    });
                } else {
                    reject("Maatwerk or Maatwerk.getData does not exist.");
                }
            }, reject);
        });
    };

    var getQueryDataFromSettings = function(settings) {
        return new Promise(function (resolve, reject) {
            if(settings.url) {
                settings.url = settings.url;
            }

            if (settings.headers) {
                var headers = settings.headers;
                for (var header in headers) {
                    headers[header] = headers[header];
                }
            }

            xhrService.customAjax.ajax(settings)
                .done(function (data, status, xhr) {
                    try {
                        var strData = xhr.responseText;
                        var result = strData;
                        var contentType = tncTools.getContentTypeFromHeader(xhr);

                        if (tncTools.contentTypeIsXml(contentType)) {
                            result = tncTools.parseXml(strData);
                        } else if (tncTools.contentTypeIsJson(contentType)) {
                            result = JSON.parse(strData);
                        }

                        resolve(result);
                    } catch(err) {
                        reject(err);
                    }
                })
                .fail(reject);
        });
    };

    var getQueryDataFromFunction = function(fnText, params, paramDisplayNames) {
        return new Promise(function (resolve, reject) {
          try {
              var fullFnText = "return function($, Promise, moment, tools, params, paramDisplayNames, window) { var document = undefined, alert = undefined, confirm = undefined, self = undefined, parent = undefined, global = undefined; return new Promise(function(resolve, reject) { try { " + fnText + " } catch(e) { reject(e); } })};";
              var fn = new Function(fullFnText)();

              var customWindow = {
                  isDesktop: config.isDesktop
              };

              fn(xhrService.customAjax, Promise, moment, dataTools, params, paramDisplayNames, customWindow)
              .then(function(data) {
                  resolve(data);
              })
              .catch(function(err) {
                  var error = err.toString();
                  if (err.stack) {
                      error = err.stack;
                  }
                  console.warn('getQueryDataFromFunction', error);
                  reject(error);
              });
            } catch(err) {
               var error = err.toString();
                  if (err.stack) {
                      error = err.stack;
                  }
                  console.warn('getQueryDataFromFunction', error);
                  reject(error);
            }
        });
    };

    var getQueryData = function(query, themeFolder, params, paramDisplayNames, debug) {
        var settingsStr = ('' + query.settings).trim();
        if (settingsStr[0] === '{' && settingsStr[settingsStr.length-1] === '}') {
            var settings = JSON.parse(settingsStr);
            if (!settings['key']) {
                return getQueryDataFromSettings(settings);
            } else {
                if (debug){
                  return Promise.reject("Loading addon is not supported here.");
                } else{
                  return qetQueryDataFromMaatwerk(settings, themeFolder);
                }
            }
        } else {
            // Ga er vanuit dat het een javascript functie is.
            var functionStr = settingsStr;
            return getQueryDataFromFunction(functionStr, params, paramDisplayNames);
        }
    };

    exports.loadDataMultipleQueries = function (queryArray, themeFolder, params, paramDisplayNames, debug) {
        return new Promise(function (resolve, reject) {
            var queries = queryArray.map(function(query) {
                return {
                    name: query.name || '',
                    order: query.order || 0,
                    settings: query.settings
                };
            });

            queries.sort(function(a, b) {
                return compare(a.order, b.order);
            });

            var queryDataByName = {};
            return Promise.mapSeries(queries, function(query) {
                return getQueryData(query, themeFolder, params, paramDisplayNames, debug)
                    .then(function(data) {
                        queryDataByName[query.name] = data;
                    });
            })
            .then(function(result) {
              resolve({ queries: queryDataByName });
            })
            .catch(function(err) {
                if (debug) {
                  reject(err);
                } else {
                  resolve({ queries: queryDataByName });
                }
            })
        });
    };

    return exports;
});
