const _ = require('underscore');
const Backbone = require('backbone');
const geolocation = require('geolocation');

const { distance } = require('./utils');

const NodeGeocoder = require('node-geocoder');

const LocationModel = Backbone.Model.extend({
  'defaults': {

    // defaults go here - "children" may be contained here
  },
  'initialize': function() {
    // this.listenTo(this, 'change sync reset', this.onChange);

    const geoOptions = {
      'maximumAge': 5 * 60 * 1000,
      'timeout': 10 * 1000
    };

    geolocation.options = geoOptions;

    geolocation.on('error', function(err) {
      console.warn('Geolocation error');
      console.error(err);
    });

    geolocation.on('change', function( position) {
      console.log('Location update');
      const location = { 'latitude': position.coords.latitude, 'longitude': position.coords.longitude, 'timestamp': position.timestamp };
      this.processPosition(location);
      //     this.set('location', location);
    }.bind(this));

    this.watcher = geolocation.createWatcher();

    this.listenTo(this, 'change:location', this.onChange);
  },
  'onChange': function() {
    console.log('>> Location updated');
    console.log(this.get('location'));
  },
  'processPosition': function(pos) {
    console.log('processPosition');
    const { latitude, longitude, timestamp } = pos;

    const current = this.get('location');

    const options = {
      'provider': 'google',

      // Optional depending on the providers
      'httpAdapter': 'https', // Default
      'apiKey': 'AIzaSyA7oGP6QS28tTwtT6UzA7hzh0b3MWwMYB8', // for Mapquest, OpenCage, Google Premier
      'formatter': null // 'gpx', 'string', ...
    };
    const geocoder = NodeGeocoder(options);

    const homeDistance = distance(55.942673, -4.556334, latitude, longitude);
    const workDistance = distance(55.861939, -4.259338, latitude, longitude);
    const atHome = (homeDistance < 0.10);
    const atWork = (workDistance < 0.10);
    const latlong = { 'lat':latitude, 'lon':longitude };
    const ll = `${latitude},${longitude}`;
    const llFixed = `${Number.parseFloat(latitude).toFixed(3)},${Number.parseFloat(longitude).toFixed(3)}`;

    const newLocation = { homeDistance, workDistance, latitude, longitude, atHome, atWork, timestamp, ll, llFixed, 'city' : '', 'cityCC':'' };

    // console.log('>> NewLocation', JSON.stringify(newLocation));
    //  const distanceFromLast = distance(current.latitude, current.longitude, latitude, longitude);

    if (!current /* || distanceFromLast > 1.5*/)
      geocoder.reverse(latlong)
        .then(function(res) {
          newLocation.city = res[0].city;
          newLocation.cityCC = `${res[0].city},${res[0].countryCode}`;
          this.set('location', newLocation);
        }.bind(this))
        .catch(function(err) {
          console.error(err);
          this.set('location', newLocation);
        });
    else {
      newLocation.city = current.city;
      const distanceFromLast = distance(current.latitude, current.longitude, latitude, longitude);

      if (distanceFromLast > 0.5 && distanceFromLast < 2.0) {
        // dont bother re geocoding
        console.log('Slightly moved from previous');
        this.set('location', newLocation);
      }
      else if (distanceFromLast >= 2.0 || (timestamp - current.timestamp > 1.8e+6) ) {
        console.log('Moved from previous', (timestamp - current.timestamp > 1.8e+6));
        geocoder.reverse(latlong)
          .then(function(res) {
            newLocation.city = res[0].city;
            newLocation.cityCC = `${res[0].city},${res[0].countryCode}`;
            this.set('location', newLocation);
          }.bind(this))
          .catch(function(err) {
            console.error(err);
            this.set('location', newLocation);
          });
      }
    }
  }

});

module.exports = { LocationModel };

// https://www.npmjs.com/package/node-geocoder
