'use strict';
/* global Backbone, _, $, AmCharts */
/* global  mainview */
/* jshint browser: true , devel: true*/

(function($) {

  var GraphView;
  var mqttConfig = {
    orgId: 'qz0da4',
    userName: 'a-qz0da4-dfwwdkmkzr',
    appKey: '9txJEf3Cjy7hkSOvkv',
    prefix: 'iot-2/type/mDot/id/'
  };

  var sendAuthentication = function(xhr) {
    var user = 'a-qz0da4-dfwwdkmkzr'; // Your actual username
    var pass = '9txJEf3Cjy7hkSOvkv'; // Your actual password
    var token = user.concat(':', pass);
    xhr.setRequestHeader('Authorization', ('Basic '.concat(btoa(token))));

    console.log('Auth:', ('Basic '.concat(btoa(token))));
  };

  var EventsModel = Backbone.Model.extend({
    initialize: function() {
      _.bindAll(this, 'processAdded');
      this.on('all', function(d) {
        console.log('model:all', d);
        this.temporal = {low: 0, high: 0};
      });
      this.on('remove', function() {
        $('#output').empty();
      });

      this.on('add', function() {
        this.processAdded();
      });

    },
    splitOccupancy: function(item) {

      var start = new Date(item.start);
      var msStart = ~~(start.getTime() / 300000);

      var end = new Date(item.end);
      var msEnd = ~~(end.getTime() / 300000);

      var newArray = [];

      for (var t = 0; t < (msEnd - msStart);t++) {
        newArray.push({date: new Date((msStart * (300000)) + (t * 300000)), count: item.count});
      }
      return newArray;

    },
    findOccupancy: function(ts, occupancy)
    {
      let tsMS = new Date(ts).getTime();

     // console.log(new Date(ts).getTime());
     // console.log(ts);
      _(occupancy).each(function(item) {

    //    console.log(new Date(item.start).getTime(), new Date(item.start).getTime());
    //    console.log(item.start, item.end);
        if ((ts >= new Date(item.start).getTime()) && (ts <= new Date(item.end).getTime()))
        {
     //     console.log('Occupancy', item.count);
          return item.count;
        }

            }, this);
      return 0;
    },
    processAdded: function() {
      console.log('Model:ProcessAdded');
      var self = this;
      var tempCollection = new Backbone.Collection();
      var occuCollection = new Backbone.Collection();
      var occupancy = [];

      var events;

      _.invoke(DeviceCollection.toArray(), 'destroy');
      //   _.invoke(OccupancyCollection.toArray(), 'destroy');

     // console.log(this);

      this.temporal = {low: 0, high: 0};
      events = this.get('events');

      //_(this.get('events')).each(function(i) {
      _(events.data).each(function(i) {
        let _occupancy;

        if (this.temporal.low === 0 || this.temporal.low > i.timestamp) {
          this.temporal.low = i.timestamp;
        }

        if (this.temporal.high === 0 || this.temporal.high < i.timestamp) {
          this.temporal.high = i.timestamp;
        }

      //  _occupancy = this.findOccupancy(i.timestamp, events.occupancy);

        tempCollection.add({
          dt: i.timestamp,
          lux: i.lux,
          temp: i.temp,
          co2: i.co2,
          humid: i.humidity,
          noise: i.sound/*,
          occupancy: _occupancy*/
        });
      }, this);

     /* _(events.occupancy).each(function(item) {

        occupancy = occupancy.concat(this.splitOccupancy(item));

      }, this);*/

      console.log('occupancy:', occupancy);

      DeviceCollection.temporal = this.temporal;
      //DeviceCollection.occupancy = occupancy;

      DeviceCollection.models = tempCollection.models;

      DeviceCollection.trigger('update');
      console.log('temporal:', this.temporal);
    }, decoder: function(data) {
      var _obj = {};
      var _data = window.atob(data).split('');

      var bytes = _data.map(i => i.charCodeAt());

      _obj.light = parseInt('0x' + ('0' + bytes[0]).substr(-2) + ('0' + bytes[1]).substr(
          -2));
      _obj.co2 = parseInt(_data[2] + _data[3] + _data[4] + _data[5] + _data[6],
        10);
      _obj.temp = (parseInt(_data[7] + _data[8] + _data[9] + _data[10] + _data[11],
          10) - 1000) / 10;
      _obj.humid = (parseInt(_data[12] + _data[13] + _data[14] + _data[15] + _data[16],
        10) / 10);
      _obj.noise = parseInt('0x' + ('0' + bytes[17]).substr(-2) + ('0' + bytes[18]).substr(
          -2));
      _obj.binData = bytes;
      return _obj;
    }, dateTime: function($date) {
      var dateTime = new Date.create($date);
      var date = dateTime.format('{yyyy}-{MM}-{dd}');
      var time = dateTime.format('{HH}:{mm}:{ss}');
      return {
        dateTime: dateTime.format('{yyyy}-{MM}-{dd} {HH}:{mm}:{ss}'),
        date: date,
        time: time
      };
    }
  });

  var mDotCollection = Backbone.Collection.extend({
    model: EventsModel,
    url: 'https://qz0da4.internetofthings.ibmcloud.com/api/v0002/historian/types/mDot/devices/',
    initialize: function() {
      this.on('update', function() {
        // Console.log('Collection:update',this);
      });
    }

  });

  var ItemView = Backbone.View.extend({
    tagName: 'div', className: 'item mui-container', initialize: function() {
      this.template = _.template($('#item-template').html());
      console.log('ItemView:Init');
      //  This.render();
    }, render: function() {

      console.log('ItemView:Render');
      _(this.model.events).each(function(i) {
        this.$el.append(this.template({item: i}));
      }, this);

      return this;
    }
  });

  var MDOT = Backbone.View.extend({
    model: EventsModel, el: $('#output'),

    events: {
      'click button#refresh': 'refresh'
    }, initialize: function() {
      _.bindAll(this, 'render', 'refresh', 'update');
      this.collection.bind('change reset add remove', this.render, this);

      //This.template = _.template($('#list-template').html());
      this.template = _.template($('#loaded-template').html());
      //This.render();
    }, refresh: function() {

    }, update: function() {
      console.log('MDOT:update');
      this.collection.each(function(model) {

      });

    }, render: function() {
      console.log('MDOT:render');
      $('#output').empty();
      var that = this;
      that.$el.append(this.template);

      return this;
    }
  });

  var MainModel = Backbone.Model.extend({});

  var MainView = Backbone.View.extend({
    el: $('#main'), template: _.template($('#main-template').html()), events: {
      'change select#device': 'changeDevice',
      'click button#refresh': 'updateDevice',
      submit: function(event) {}

    }, initialize: function() {
      _.bindAll(this, 'render', 'changeDevice', 'updateDevice');

      this.model.on('change', this.updateDevice);
      console.log('MainView:', this);
      this.render();
    }, render: function() {
      $(this.el).html(this.template());
      return this;
    }, changeDevice: function() {
      var newDevice;
      console.log('MainView:ChangeDevice');
      newDevice = this.$el.find('#device')[0].value;

      this.model.set('device', newDevice);
    }, updateDevice: function() {
      var fetchObj = {beforeSend: sendAuthentication};
      console.log('MainView:Updatedevice');
      if (this.model.has('device')) {
        // FetchObj.data = $.param({key:'"'+ this.model.get('device') + '"'});
        // this.collection.url =  'https://qz0da4.internetofthings.ibmcloud.com/api/v0002/historian/types/mDot/devices/' + this.model.get('device');
        // this.collection.url =  '/api/mdot/' + this.model.get('device');
        this.collection.url = '/apiv2/mdot/' + this.model.get('device');
        // this.collection.url =  'http://127.0.0.1:5984/mdot/_design/getDevice/_view/getDevice';

        $('#output').empty();
        this.collection.fetch(fetchObj);
      } else {
        console.error('Nothing to get!');
      }

    }

  });

  GraphView = Backbone.View.extend({
    el: $('#graph'), initialize: function() {
      this.modes = ['', 'lux', 'temp', 'co2', 'humid', 'noise'];
      this.titles = [
        '', 'Light Levels', 'Temperature', 'Co2 Levels', 'Humidity', 'Sound'
      ];

      this.mode = 0;

      // Config AMChart
      this.chart = {};
      this.categoryAxesSettings = new AmCharts.CategoryAxesSettings();
      this.dataSet = new AmCharts.DataSet();

      console.log('GraphView!');
      _.bindAll(this, 'render', 'updateGraph', 'setupChart');
      this.collection.on('update', function(d) {
        console.log('GraphView Collection update trigger!!');
        this.updateGraphV2();
      }, this);

      // This.setupChart();
    }, events: {
      'change select#displaymode': 'changeMode'
    }, setupChart: function() {
      console.log('chart:SetupChart');

      this.categoryAxesSettings.minPeriod = 'mm';
      this.chart.categoryAxesSettings = this.categoryAxesSettings;

      this.dataSet.color = '#b0de09';

      this.chart.dataSets = [this.dataSet];
      //      This.chart.write('chartdiv');
    },

    doChartV2: function(chartData) {
      var self = this;

      self.chart = AmCharts.makeChart('chartdiv', {
        type: 'serial',
        theme: 'light',
        dataSets: [

        ],

        legend: {
          useGraphSettings: true
        },
        color: '#ffffff',
        dataProvider: chartData,
        dataDateFormat: 'YYYY-MM-DDTHH:NN:SS.QQQ',
        synchronizeGrid: true,
        valueAxes: [
          {
            id: 'lux',
            axisColor: '#FFC802',
            axisThickness: 2,
            axisAlpha: 1,
            position: 'left'
          },
          {
            id: 'co2',
            axisColor: 'rgba(0,191,255,1)',
            axisThickness: 2,
            axisAlpha: 1,
            position: 'right'
          },
          {
            id: 'temp',
            axisColor: 'rgba(46,255,0,1)',
            axisThickness: 2,
            gridAlpha: 0,
            offset: 50,
            axisAlpha: 1,
            position: 'left'
          },
          {
            id: 'humid',
            axisColor: 'rgba(255,0,99,1)',
            axisThickness: 2,
            axisAlpha: 1,
            offset: 50,
            position: 'right'
          },
          {
            id: 'noise',
            axisColor: 'rgb(99, 157, 189)',
            axisThickness: 2,
            gridAlpha: 0,
            offset: 100,
            axisAlpha: 1,
            position: 'left'
          }
        ],
        graphs: [
          {
            valueAxis: 'lux',
            lineColor: '#FFC802',
            title: 'Light Level',
            valueField: 'lux',
            fillAlphas: 0
          },
          {
            valueAxis: 'co2',
            lineColor: 'rgba(0,191,255,1)',
            title: 'Co2',
            valueField: 'co2',
            fillAlphas: 0
          },
          {
            valueAxis: 'temp',
            lineColor: 'rgba(46,255,0,1)',
            title: 'Temperature',
            valueField: 'temp',
            fillAlphas: 0
          },
          {
            valueAxis: 'humid',
            lineColor: 'rgba(255,0,99,1)',
            title: 'Humidity',
            valueField: 'humid',
            fillAlphas: 0
          },
          {
            valueAxis: 'noise',
            lineColor: 'rgb(99, 157, 189)',
            title: 'Sound',
            valueField: 'noise',
            fillAlphas: 0
          }
        ],
        chartScrollbar: {},
        chartCursor: {
          cursorPosition: 'mouse'
        },
        categoryField: 'date',
        categoryAxis: {
          minPeriod: 'mm',
          parseDates: true,
          axisColor: '#ff0000',
          minorGridEnabled: true
        },
        export: {
          enabled: true, position: 'bottom-right'
        }
      });

      $('#chartdiv').empty();
      self.chart.write('chartdiv');

    }, updateGraphV2: function() {
      var self = this;
      var chartData = [];
      _(this.collection.models).each(function(i) {
        chartData.push({
          date: i.get('dt'),
          co2: i.get('co2'),
          humid: i.get('humid'),
          lux: i.get('lux'),
          noise: i.get('noise'),
          temp: i.get('temp')
        });
      });
      //  Console.log(chartData);
      self.doChartV2(chartData);
    }, updateGraph: function() {
      var self = this;
      let getMode = this.modes[this.mode];

      var chartData = [];

      var temporal = {high: 0, low: 0};
      var HL = {high: 0, low: 0};

      var mode = parseInt(this.mode);
      console.log('mode:', mode, this.mode);

      _(this.collection.models).each(function(i) {
        var dt = i.get('dt');
        var obj;
        var value, valueB;
        if (mode < 6) {
          value = i.get(getMode);
        } else {
          if (mode === 6) {
            value = i.get(this.modes[1]);
            valueB = i.get(this.modes[3]);
          } else {

            value = i.get(this.modes[2]);
            valueB = i.get(this.modes[4]);

          }
        }

        if (temporal.low === 0 || dt < temporal.low) {
          temporal.low = dt;
        }
        if (temporal.high === 0 || dt > temporal.high) {
          temporal.high = dt;
        }

        if (HL.low === 0 || value < HL.low) {
          HL.low = value;
        }
        if (HL.high === 0 || value > HL.high) {
          HL.high = value;
        }

        obj = {date: dt, value: value};

        if (mode => 6) {
          obj.valueB = valueB;
        }
        chartData.push(obj);

      }, this);

      self.doChartV2(mode, chartData);

    }

  });

  var DeviceCollection = new Backbone.Collection;
  var OccupancyCollection = new Backbone.Collection;

  var mdotCollection = new mDotCollection();

  var mainSettings = new MainModel();
  var mainview = new MainView({
    collection: mdotCollection, model: mainSettings
  });

  var mdot = new MDOT({collection: mdotCollection});

  var grapher = new GraphView({collection: DeviceCollection});

})(jQuery);