var models  = require('../models');
var gconfig = require('./config.controller');

var Api = function() {

    var nInitial = 0;
    var nRealtime = 0;
    var nSec = 0;

    // private function
    // return a list of active sensors
    var SensorsByType = function (sensortipo, callback){

      gconfig.loadJson(function(err, json){
        if(!err){
          nInitial = json.nInitial;
          nRealtime = json.nRealtime;
          nSec = json.nSec;
          
          models.Sensor.findAll({ include: [{model: models.SensorLocation},{model: models.SensorDetails, where:{ evento:sensortipo}}], where: {active:1} }).then(function(sensors){
            if(sensors.length > 0){
          		var listname = [];
          		var listaddress = [];
          		for (var i = 0; i<sensors.length; i++){
          			var id = sensors[i].identifier.split("+")[0];
          			listname.push(sensors[i].SensorLocation.nombre);
          			listaddress.push(id);
          		}
        		  return callback({ names: listname, address: listaddress, unidad: sensors[0].SensorDetail.unidad});
            }else{
              return callback(0);
            }
        	});
          
        }
      });
    }

    // private function
    // return a list of active sensors
    var SensorsByTypeAndLocation = function (location, sensortipo, callback){
      models.Sensor.findAll({ include: [{model: models.SensorLocation, where:{nombre:{$like: '%'+location+'%'}}},{model: models.SensorDetails, where:{ evento:sensortipo}}], where: {active:1} }).then(function(sensors){
        if(sensors.length > 0){
      		var listname = [];
      		var listaddress = [];
      		for (var i = 0; i<sensors.length; i++){
      			var id = sensors[i].identifier.split("+")[0];
      			listname.push(sensors[i].SensorLocation.nombre);
      			listaddress.push(id);
      		}
    		  return callback({ names: listname, address: listaddress, unidad: sensors[0].SensorDetail.unidad});
        }else{
          return callback(0);
        }
    	});
    }

    // public functions
    var getstartChart = function(tipo, callback) {
        SensorsByType(tipo, function(list){
          if(list == 0){
            return callback({});
          }
    	    var nodeslist = list.address;
    	    var result = {};
    	    result['val'] = [];
    	    result['params'] = list.names;
          console.log(nodeslist+" "+nInitial);
    	    // añado un indice al campo date para que al ordenar la consulta sea mas rapida
    	    models.Event.findAll({ include: [{model: models.SensorLocation}], where: { address : nodeslist}, order: 'date DESC', limit: nInitial}).then( function(events) {
    	      if (events.length > 0 ){
    	          events.forEach(function(anevent) {
    	          	var obj = {};
    	          	obj['name'] = anevent.SensorLocation.nombre;
    	          	obj[anevent.SensorLocation.nombre] = parseFloat(anevent.value);
    	          	obj['unidad'] = list.unidad;
    	          	obj['date'] = anevent.date.getTime();
    	            result['val'].push(obj);
    	          });
    	      }
    	      return callback( result );
    	    });
        });
    }

    var getstartCostChart = function(tipo, callback){
        SensorsByType(tipo, function(list){
          if(list == 0){
            return callback({});
          }
    	    var nodeslist = list.address;
    	    var result = {};
    	    result['val'] = [];
    	    result['params'] = list.names;

    	    // añado un indice al campo date para que al ordenar la consulta sea mas rapida
    	    models.CostEvent.findAll({ include: [{model: models.SensorLocation}], where: { address : nodeslist}, order: 'date DESC', limit: nRealtime}).then( function(events) {
    	      if (events.length > 0 ){
    	          events.forEach(function(anevent) {
    	          	var obj = {};
    	          	obj['name'] = anevent.SensorLocation.nombre;
    	          	obj[anevent.SensorLocation.nombre] = parseFloat(anevent.value);
    	          	obj['unidad'] = list.unidad;
    	          	obj['date'] = anevent.date.getTime();
    	            result['val'].push(obj);
    	          });
    	      }
    	      return callback( result);
    	    });
	     });
    }

    var getstartAvgChart = function(tipo, mode, callback){
      var Datatype = null;

      if(mode == 'am'){
        Datatype = models.PerMinutesMeanEvent;
      }else if(mode == 'ah'){
        Datatype = models.PerHoursMeanEvent;
      }else{
        //
      }

    	if(Datatype){
    		SensorsByType(tipo, function(list){
          if(list == 0){
            return callback({});
          }
    	    var nodeslist = list.address;
    	    var result = {};
    	    result['val'] = [];
    	    result['params'] = list.names;

    	    // añado un indice al campo date para que al ordenar la consulta sea mas rapida
    	    Datatype.findAll({ include: [{model: models.SensorLocation}], where: { address : nodeslist}, order: 'date DESC', limit: nInitial}).then( function(events) {
    	      if (events.length > 0 ){
    	          events.forEach(function(anevent) {
    	          	var obj = {};
    	          	obj['name'] = anevent.SensorLocation.nombre;
    	          	obj[anevent.SensorLocation.nombre] = parseFloat(anevent.value);
    	          	obj['unidad'] = list.unidad;
    	          	obj['date'] = anevent.date.getTime();
    	            result['val'].push(obj);
    	          });
    	      }
    	      return callback( result );
    	    });
      	});
    	}
    }

    var getrealTimeData = function(tipo, callback){
        SensorsByType(tipo, function(list){
          if(list == 0){
            return callback({key: tipo, data:{val: [], params: []}});
          }
          var nodeslist = list.address;
    	    var result = {val: [], params: list.names};

    	    // añado un indice al campo date para que al ordenar la consulta sea mas rapida
    	    models.Event.findAll({ include: [{model: models.SensorLocation}], where: { address : nodeslist}, order: 'date DESC', limit: nRealtime}).then( function(events) {
    	      if (events.length > 0 ){
    	          events.forEach(function(anevent) {
    	          	var obj = {};
    	          	obj['name'] = anevent.SensorLocation.nombre;
    	          	obj[anevent.SensorLocation.nombre] = parseFloat(anevent.value);
    	          	obj['unidad'] = list.unidad;
    	          	obj['date'] = anevent.date.getTime();
    	            result['val'].push(obj);
    	          });
    	      }

    	      return callback( {key: tipo, data:result} );
    	    });
        });
    }

    var getrealTimeCostData = function(tipo, callback){
        SensorsByType(tipo, function(list){
          if(list == 0){
            return callback({key: tipo, data:{val: [], params: []}});
          }
    	    var nodeslist = list.address;
    	    var result = {};
    	    result['val'] = [];
    	    result['params'] = list.names;

    	    // añado un indice al campo date para que al ordenar la consulta sea mas rapida
    	    models.CostEvent.findAll({ include: [{model: models.SensorLocation}], where: { address : nodeslist}, order: 'date DESC', limit: nRealtime}).then( function(events) {
    	      if (events.length > 0 ){
    	          events.forEach(function(anevent) {
    	          	var obj = {};
    	          	obj['name'] = anevent.SensorLocation.nombre;
    	          	obj[anevent.SensorLocation.nombre] = parseFloat(anevent.value);
    	          	obj['unidad'] = list.unidad;
    	          	obj['date'] = anevent.date.getTime();
    	            result['val'].push(obj);
    	          });
    	      }
    	      return callback( {key: tipo, data:result} );
    	    });
	     });
    }

    var getLastValueLab = function(location, tipo, callback){
      SensorsByTypeAndLocation(location, tipo, function(list){
        if(list == 0){
          return callback({key: tipo, data:{val: [], params: []}});
        }
  	    var nodeslist = list.address;
  	    var result = {};
  	    result['val'] = [];

  	    // añado un indice al campo date para que al ordenar la consulta sea mas rapida
  	    models.Event.findAll({ include: [{model: models.SensorLocation}], where: { address : nodeslist}, order: 'date DESC', limit: 1}).then( function(events) {
  	      if (events.length > 0 ){
	          events.forEach(function(anevent) {
	          	var obj = {};
	          	obj['name'] = anevent.SensorLocation.nombre;
	          	obj[anevent.SensorLocation.nombre] = parseFloat(anevent.value);
	          	obj['unidad'] = list.unidad;
	          	obj['date'] = anevent.date.getTime();
	            result['val'].push(obj);
	            result['params'] = anevent.SensorLocation.nombre;
	          });
  	      }
  	      return callback( {key: tipo, data:result} );
  	    });
      });
    }

    var setDataWebCC = function(tmin, tmax, callback){
      models.DataWeb.update({ valuemin: tmin, valuemax: tmax }, { where: { id : 0 } }).then(function (result) {
        return callback(result);
      });
    }

    var setDataWebCCR = function(tobj, callback){
      models.DataWeb.update({ valueobj: tobj }, { where: { id : 0 } }).then(function (result) {
        return callback(result);
      });
    }

    var getDataWeb = function(callback){

      models.DataWeb.findById(0).then(function(result) {
        return callback({tmin: result.valuemin, tmax: result.valuemax, tobj: result.valueobj});
      });

    }

    return {
        getstartChart: getstartChart
        ,getstartCostChart: getstartCostChart
        ,getstartAvgChart: getstartAvgChart
        ,getrealTimeData: getrealTimeData
        ,getrealTimeCostData: getrealTimeCostData
        ,getLastValueLab: getLastValueLab
        ,setDataWebCC: setDataWebCC
        ,setDataWebCCR: setDataWebCCR
        ,getDataWeb: getDataWeb
    }
}();

module.exports = Api;
