const $ = require('jquery');
const _ = require('underscore');
const Backbone = require('backbone');
const request = require('request');
const { get } = require('lodash');
const { reduceOpenWeather } = require('./libs/reducers');
const { distance } = require('./libs/utils');
const TimeFormat = require('hh-mm-ss');

const weatherItem = Backbone.Model.extend({

});

const WeatherCollection = Backbone.Collection.extend({
  'model': weatherItem
});

const weatherCollection = new WeatherCollection();

const weatherItemView = Backbone.View.extend({
  'tagName': 'div',

  'template': _.template(`
  <div>
        <div class="mui-col-md-4 mui-col-xs-4">
          <div class="mui--text-display1 mui--text-center temp<%=temp %>"><%= temp %>°</div>
        </div>
        <div class="mui-col-md-4 mui-col-xs-4 mui--text-center">
                 <i class="mui--text-display1 wi <%= icon %>"></i>
                </div>
        <div class="mui-col-md-4 mui-col-xs-4">
          <div>
            <div class="mui--text-subhead summary"><%= summary %></div>
            <span class="mui--text-body2 temp<%=~~(tempHigh) %>"><%= tempHigh %>°</span> /
            <span class="mui--text-body1 temp<%=~~(tempLow) %>"><%= tempLow %>°</span></div>
            
          </div>
          </div>
          <div class="mui--text-dark-secondary mui--text-caption mui--text-right">
          For <%=city%> to <%= readdate %>
        </div>
        <div id='wForecast' class="cardLink">
        <i class="seemore material-icons mui--align-middle " >arrow_forward</i> <span class="seemore mui--align-middle">See forecast</span>
        </div>
        `),
  'initialize': function() {
    this.render();
  },
  'attributes': function() {
    return {
      // 'data-id': this.model.id
    };
  },

  'render': function() {
    this.$el.html(this.template(this.model.toJSON()));
  }
});

const WeatherModel = Backbone.Model.extend({
  'defaults' : function (obj) {
    // return a new object
    return {
      'update' : new Date().getTime()
    };
  },
  'initialize': function() {
    this.weatherCollection = weatherCollection;
    this.run = false;
    this.listenTo(this, 'change:llFixed', this.onChange);
    this.listenTo(this, 'change:update', this.onChange);
  },
  'onChange': function() {
    console.log('Weather LL has changed');
    // if distance change > 10km
    // if its been an hour since last update

    if (!this.has('log')) {
      console.info('First run');
      this.getWeather();
    }
    else {
      const log = this.get('log');
      const timeDiff = new Date().getTime() - log.time;
      console.log('this', this);
      const dist = distance(log.lat, log.long, this.get('latitude'), this.get('longitude'));
      console.log('Weather distance:', dist);

      if ((dist > 5.0) && (timeDiff > 1.8e+6))
        this.getWeather();
      else if (timeDiff > 3.6e+6) {
        console.log('Weather hourly update');
        this.getWeather();
      }
    }
  },
  'getWeather': function() {
    // const ll = this.get('llShort');
    console.log('>> Weather request');
    const llFixed = this.get('llFixed');
    request({
      'url': `${window.loc}/weather`,
      'method': 'GET',
      'qs': {
        'll': llFixed
      }
    }, function(err, res, body) {
      if (err)
        console.error(err);
      else {
        // console.log(body);
        const fsJSON = JSON.parse(body);
        const city = get(fsJSON, 'city.name', '');
        const list = get(fsJSON, 'list', []);
        const newItems = [];
        for(const item of list)
          newItems.push(reduceOpenWeather(item, city));

        this.weatherCollection.reset(newItems);

        this.logUpdate();
      }
    }.bind(this));
  },
  'logUpdate': function() {
    console.log('Weather logging:');

    const log = { 'lat' : this.get('latitude'), 'long': this.get('longitude'), 'time': new Date().getTime() };

    this.set('log', log);

    this.timerID = setTimeout(
      () => this.tick(),
      3.6e+6 + 1000
    );

    // console.log(this);
  },
  'tick': function() {
    console.log('Set update');
    this.set('update', new Date().getTime());
  }
});

const WeatherView = Backbone.View.extend({
  'className': 'mui--align-middle',

  'initialize': function(options) {
    this.eventBus = options.eventBus;
    this.location = options.location;
    this.wCollection = weatherCollection;

    // this.model.bind('change', this.render, this);
    this.location.bind('change:llFixed', this.updateLocation, this);

    /* this.wCollection.on('all', function(eventName) {
      console.log(`${eventName } was triggered!`);
    });*/

    this.wCollection.bind('reset', this.render, this);
    this.eventBus.on('focused', this.focused, this);
  },
  'attributes': function() {
    return {
      'class': 'mui--align-middle'
    };
  },
  'events': {
    'click #wForecast': 'doClick'
  },
  'updateLocation': function(l) {
    console.log('>> Weather Location has changed...');

    if (l.has('atHome')) {
      const llFixed = l.get('llFixed');
      const latitude = l.get('latitude');
      const longitude = l.get('longitude');
      this.model.set({ llFixed, latitude, longitude });
    }
    else
      console.log('>> Weather No location yet');
  },
  'render': function() {
    console.log('>> Weather:Render');

    this.$el.empty();
    const item = this.wCollection.first();

    const wView = new weatherItemView({ 'model': item });
    this.$el.append(wView.el);

    this.$el.parent().show();
    // console.log(wView.el);
  }, 'doClick': function(d) {
    console.log('Do click', this);
    const llFixed = this.location.get('llFixed');
    console.log(llFixed);
    this.eventBus.trigger('showForecast', llFixed);
  }, 'focused': function() {
    console.log('>> Weather received focus msg');
    const now = new Date().getTime();
    const log = this.model.get('log');
    const since = now - log.time;

    console.log(`Weather was last updated: ${TimeFormat.fromMs(since, 'hh:mm')} ago`);

    if (since > (60 * 1000 * 60) )
      this.model.set('update', now);
  }

});

module.exports = { WeatherModel, WeatherView };
