var Clay = require('pebble-clay');
var clayConfig = require('./config');
var clay = new Clay(clayConfig);

var messageKeys = require('message_keys');

var message;

var locationInterval;
var locationOptions = {
  'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
  'timeout': 2000, //2s timeout
  'maximumAge': 1000 // 1s cache
};

// Store location in Pebble app local storage
//
function storeLocation(position) {
  var latitude = position.coords.latitude;
  var longitude = position.coords.longitude;
  var timestamp = position.timestamp;
  localStorage.setItem("latitude", latitude);
  localStorage.setItem("longitude", longitude);
  localStorage.setItem("timestamp", timestamp);
  // console.log("Stored location " + position.coords.latitude + ',' + position.coords.longitude);
}

// Get location from Pebble app local storage
//
function getLocation() {
  if (localStorage.getItem("latitude") || localStorage.getItem("longitude") || localStorage.getItem("timestamp")) {
    var la = localStorage.getItem("latitude");
    var lo = localStorage.getItem("longitude");
    var ti = localStorage.getItem("timestamp");
    var co = { "latitude": la, "longitude": lo };
    var pos = { "coords": co, "timestamp": ti };
    // console.log("Stored location " + pos.co.la + ',' + pos.co.lo);
    return pos;
  } else {
    return null;
  }
}


// Calculate the distance from 2 geoloc in degrees.
// IMPORTANT : this is a calculation from 2D projection, altitude is not involved
//
function distance_on_geoid(lat1, lon1, lat2, lon2) {
  // Convert degrees to radians
  lat1 = lat1 * Math.PI / 180.0;
  lon1 = lon1 * Math.PI / 180.0;
  lat2 = lat2 * Math.PI / 180.0;
  lon2 = lon2 * Math.PI / 180.0;
  // radius of earth in metres
  r = 6378100;
  // P
  rho1 = r * Math.cos(lat1);
  z1 = r * Math.sin(lat1);
  x1 = rho1 * Math.cos(lon1);
  y1 = rho1 * Math.sin(lon1);
  // Q
  rho2 = r * Math.cos(lat2);
  z2 = r * Math.sin(lat2);
  x2 = rho2 * Math.cos(lon2);
  y2 = rho2 * Math.sin(lon2);
  // Dot product
  dot = (x1 * x2 + y1 * y2 + z1 * z2);
  cos_theta = dot / (r * r);
  theta = Math.acos(cos_theta);
  // Distance in Metres
  return r * theta;
}

// Calculate speed from 2 geoloc point arrays (with lat,long,timestamp)
//
function speed_from_distance_and_time(p1, p2) {
  dist = distance_on_geoid(p1.coords.latitude, p1.coords.longitude, p2.coords.latitude, p2.coords.longitude);
  // timestamp is in milliseconds
  time_s = (p2.timestamp - p1.timestamp) / 1000.0;
  speed_mps = dist / time_s;
  speed_kph = (speed_mps * 3600.0) / 1000.0;
  return speed_kph;
}

// split float number into an array of int (null returned instead of 0 for decimal)
//
function splitFloatNumber(num) {
  const intStr = num.toString().split('.')[0];
  const decimalStr = num.toString().split('.')[1];
  return [Number(intStr), Number(decimalStr)];
}

// Build GPX headers
//
function GPXHeadersBuilder(timestamp, name, type) {
  var headers = '<?xml version="1.0" encoding="UTF-8"?><gpx creator="Pebble with barometer" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" version="1.1" xmlns="http://www.topografix.com/GPX/1/1"><metadata><time>' + timestamp + '</time></metadata><trk><name>' + name + '</name><type>' + type + '</type><trkseg>';
  var ret = localStorage.setItem("GPX", headers);
  return true;
}

// Build GPX footer
//
function GPXtrkptBuilder(lat, lon, ele, timestamp) {
  var GPX = localStorage.getItem("GPX");
  var trkpt = '<trkpt lat="' + lat + '" lon="' + lon + '"><ele>' + ele + '</ele><time>' + timestamp + '</time></trkpt>';
  var ret = localStorage.setItem("GPX", GPX + trkpt);
  return true;
}

// Build GPX footer
//
function GPXfooterBuilder() {
  var GPX = localStorage.getItem("GPX");
  var footer = '</trkseg></trk></gpx>';
  var ret = localStorage.setItem("GPX", GPX + footer);
  return true;
}

// Adding leading characters to string for nice displays
//
function padStart(string, max_length, padding) {
  if (string.length > max_length) {
    return string;
  } else {
    var new_str = string;
    for (index = string.length; index < max_length; index++) {
      new_str = "0" + new_str;
    }
    return new_str;
  }
}

// called in case of successful geoloc gathering and sends the coordinate to watch
//
function locationSuccess(new_pos) {
  var prev_pos = getLocation();
  storeLocation(new_pos);
  if (prev_pos === null) {
    GPXHeadersBuilder(timestampISO = new Date(new_pos.timestamp).toISOString(), "test", "18");
    return null;
  } else {
    var speed = speed_from_distance_and_time(prev_pos, new_pos);

    // Prepare display on watch
    // now it's only raw data
    //init strings
    var latitudeString = "";
    var longitudeString = "";
    var accuracyString = "";
    var altitudeString = "";
    //var altitudeAccuracyString = "";
    //var timestampString = "";
    var speedString = "";

    //formating for precision and max size
    latitudeString = new_pos.coords.latitude.toString().substring(0, 12);
    longitudeString = new_pos.coords.longitude.toString().substring(0, 12);
    accuracyString = new_pos.coords.accuracy.toString().substring(0, 4);
    altitudeString = splitFloatNumber(new_pos.coords.altitude)[0].toString().substring(0, 5);
    timestampISO = new Date(new_pos.timestamp).toISOString();
    speedString = speed.toString().substring(0, 5);

    if (speedString == "NaN") {
      speedString = "---";
    }
    // logging
    /*console.log('Your current position at ' + timestampString + ' is:');
    console.log('Coordinates: ' + latitudeString+ ', ' + longitudeString+' ; with a ' + accuracyString + 'm accuracy');
    console.log('Altitude: ' + altitudeString + 'm ; with a ' + altitudeAccuracyString + 'm accuracy');
    console.log('Speed: ' + speedString + ' km/h.');
    */
    GPXtrkptBuilder(latitudeString, longitudeString, altitudeString, timestampISO);

    console.log('GPX: ' + localStorage.getItem("GPX"));

    // Build message
    message = "OK";
    var dict = {
      //'latitude': padStart(latitudeString, 12, '0'),
      //'longitude': padStart(longitudeString, 12, '0'),
      'accuracy': accuracyString,
      'altitude': altitudeString,
      //'altitude_accuracy': padStart(altitudeAccuracyString, 3, '0'),
      //'timestamp': padStart(timestampString, 13, '0'),
      'speed': speedString,
      'status': message
    };
    //console.log('Message to send: ' + JSON.stringify(dict));

    // Send the message
    Pebble.sendAppMessage(dict, function () {
      console.log('Message sent successfully: ' + JSON.stringify(dict));
    }, function (e) {
      console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
    });
  }
}

function locationError(err) {
  console.warn('location error (' + err.code + '): ' + err.message);
  /* // No app when no location
       Pebble.sendAppMessage({
           'WEATHER_CITY_KEY': 'Loc Unavailable',
           'WEATHER_TEMPERATURE_KEY': 'N/A'
       });*/
}

function get_coordinate() {
  console.log('---- get_coordinate');
  navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);

}

/*
function switch_home(bool) {
  var response;
  console.log('---- authenticate');
  if (sid != ""){
    status = "";
    console.log('---- get_status');
    if (localStorage.getItem('username')  && localStorage.getItem('password') && localStorage.getItem('server') ){
      var username=localStorage.getItem('username');
      var password=localStorage.getItem('password');
      var server=localStorage.getItem('server');
      var xhr = new XMLHttpRequest();

      url = server + "/webapi/entry.cgi?api=SYNO.SurveillanceStation.HomeMode&version=1&method=GetInfo&_sid="+sid;

      xhr.open("GET", url,false);
      xhr.send();

      if(xhr.status == 200) {
        response = JSON.parse(xhr.responseText);
        if (response.success == true){
          status = response.data.on;
          console.log('------ status:'+status);
          var message;
          var dict;
          if ( status != bool){
            console.log('---- switching home mode to '+ bool);
            url = server + "/webapi/entry.cgi?api=SYNO.SurveillanceStation.HomeMode&version=1&method=Switch&on="+bool+"&_sid="+sid;

            xhr.open("GET", url,false);
            xhr.send();

            if(xhr.status == 200) {
              response = JSON.parse(xhr.responseText);
              if (response.success == true){
                status=bool;
                switch (status) {
                  case true:
                    message = "You just set Home mode ON";
                    break;
                  case false:
                    message = "You just set Home mode OFF";
                    break;
                  default:
                    message = "something happened, try again !";
                }
                // Build message
                dict = {
                  'status': message,
                };

                // Send the message
                Pebble.sendAppMessage(dict, function(e) {
                  console.log('sent');
                }, function() {
                  console.log('failed');
                });
              }
            }else {
              console.log('------Request returned error code ' + xhr.status.toString());
            }
          }else{
            console.log('---- nothing to do, status already '+status);
            switch (status) {
              case true:
                message = "Your Home Mode is already ON";
                break;
              case false:
                message = "Your Home Mode is already OFF";
                break;
              default:
                message = "something happened, try again !";
            }
            // Build message
            dict = {
              'status': message,
            };

            // Send the message
            Pebble.sendAppMessage(dict, function(e) {
              console.log('sent');
            }, function() {
              console.log('failed');
            });
          }
        }
      }else {
        console.log('------Request returned error code ' + xhr.status.toString());
      }
    }else{
      Pebble.showSimpleNotificationOnPebble("DSCam H-S", "You need to set your Synology account and server.");
    }
   }

}*/

function init() {
  // local storage init
  localStorage.clear();
  // clear any other var to do
  clearInterval(locationInterval);

  console.log('--- Starting regular getCurrentPosition loop using setInterval at 1 sec');
  locationInterval = setInterval(function () {
    navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
  }, 1000);


}

// Get JS readiness events
Pebble.addEventListener('ready', function (e) {
  console.log('PebbleKit JS is ready');
  // Update Watch on this
  Pebble.sendAppMessage({ 'JSReady': 1 });

  init();
});

// Get AppMessage events
Pebble.addEventListener('appmessage', function (e) {
  // Get the dictionary from the message
  var dict = e.payload;
  console.log(dict[0].toString());
  switch (dict[0]) {
    case 'get':
      get_coordinate();
      break;/*
    case 'home_on':
      switch_home(true);
      break;
    case 'home_off':
      switch_home(false);
      break;*/
    default:
      console.log('Sorry. I don\'t understand your request :' + dict[0]);
  }

});