var firebase = require('../firebase.js')

const INVALID = 'INVALID';
const PLUS = 'PLUS';
const MINUS = 'MINUS';
const CHECK = 'CHECK';

function trigger(user, api, message) {
  var originalMsg = message.body.substring(1);
  if (originalMsg.startsWith(' ')) originalMsg = originalMsg.substring(1);
  var mode;
  if (originalMsg.startsWith('++')) {
    mode = PLUS;
  } else if (originalMsg.startsWith('--')) {
    mode = MINUS;
  } else if (originalMsg.startsWith('karma')) {
    mode = CHECK;
  } else {
    return;
  }
  // grab threadID
  var threadID = message.threadID;
  // get users and nicks
  getThreadUsers(threadID, api, function(info) {
    var nicks = info.nicknames;
    var users = info.participantIDs;
    // check if user used a nickname
    for (var id in nicks) {
      if (nicks[id] == user) {
        // execute appropriate action
        doKarma(id, threadID, message.senderID, api, mode);
        return;
      }
    }
    // check if user used real name
    getIDFromName(user, users, threadID, api, function(userID) {
      if (userID != INVALID) {
        // execute appropriate action
        doKarma(userID, threadID, message.senderID, api, mode);
        return;
      }
    });
  });
}

function getThreadUsers(threadID, api, callback) {
  api.getThreadInfo(threadID, function(err, info) {
    callback(info);
  });
}

function getIDFromName(user, users, threadID, api, callback) {
  if (!user) return callback(INVALID);
  api.getUserID(user, function(err, data) {
    if (err) return console.log(err);
    for (var id in data) {
      for (var userID in users) {
        if (data[id].userID == users[userID]) return callback(users[userID]);
      }
    }
    return callback(INVALID);
  });  
}

function doKarma(userID, threadID, senderID, api, mode) {
  isCooledDown(threadID, senderID, function(cooled) {
    if (mode == PLUS && userID != senderID && cooled) {
      doModify(userID, threadID, senderID, api, true);
    } else if (mode == MINUS && userID != senderID && cooled) {
      doModify(userID, threadID, senderID, api, false);
    } else if (mode == CHECK) {
      doCheck(userID, threadID, api);
    }
  });
}

function doModify(userID, threadID, senderID, api, plus) {
  // get real names
  api.getUserInfo(userID, function(err, obj) {
    if (err) return console.error(err);
    // access db
    firebase(function(db) {
      // thread
      var threadRef = db.ref(threadID);
      // karma settings
      var karmaRef = threadRef.child('/karma');
      // initialize karma to 0
      var karma = {};
      karma[userID] = 0;
      karmaRef.once('value', function(snap) {
        // check if user already has karma
        if (snap.val() && snap.val()[userID]) {
          karma[userID] = snap.val()[userID];
        }
        // change val
        if (plus) {
          karma[userID]++;
        } else {
          karma[userID]--;
        }
        // update in db
        karmaRef.update(karma);
        // send confirmation message
        var msg = {
          body: obj[userID].firstName + ' has ' + karma[userID] + ' karma'
        }
        api.sendMessage(msg, threadID);
        var cooldownRef = threadRef.child('/cooldown');
        var d = Date.now();
        var opt = {};
        opt[senderID] = d;
        cooldownRef.update(opt);
      });
    });
  });
}

function doCheck(userID, threadID, api) {
  // get real names
  api.getUserInfo(userID, function(err, obj) {
    if (err) return console.error(err);
    // access db
    firebase(function(db) {
      // thread
      var threadRef = db.ref(threadID);
      // karma settings
      var karmaRef = threadRef.child('/karma');
      // initialize karma to 0
      karma = 0;
      karmaRef.once('value', function(snap) {
        // check if user already has karma
        if (snap.val() && snap.val()[userID]) {
          karma = snap.val()[userID];
        }
        // send confirmation message
        var msg = {
          body: obj[userID].firstName + ' has ' + karma + ' karma'
        }
        api.sendMessage(msg, threadID);
      });
    });
  });
}

function isCooledDown(threadID, senderID, callback) {
  firebase(function(db) {
    var threadRef = db.ref(threadID);
    var cooldownRef = threadRef.child('/cooldown');
    cooldownRef.once('value', function(snap) {
      if (snap.val()) {
        var d = new Date(snap.val()[senderID]);
        callback(Date.now() - d.getTime() > 30000);
        return;
      }
      callback(true);
    });
  });
}

module.exports = {
  trigger: trigger
}
@@ -3115,24 +3115,57 @@
  threadID);%0A
+        // get cooldown settings%0A
         var 
@@ -3204,24 +3204,57 @@
 cooldown');%0A
+        // get current timestamp%0A
         var 
@@ -3269,16 +3269,42 @@
 .now();%0A
+        // options object%0A
         
@@ -3344,16 +3344,45 @@
 D%5D = d;%0A
+        // update timestampt%0A
         
@@ -4265,24 +4265,47 @@
 ction(db) %7B%0A
+    // thread settings%0A
     var thre
@@ -4326,24 +4326,53 @@
 (threadID);%0A
+    // get cooldown settings%0A
     var cool
@@ -4468,73 +4468,213 @@
     
-if (snap.val()) %7B%0A        var d = new Date(snap.val()%5BsenderID%5D);
+// check if theres a timestamp%0A      if (snap.val()) %7B%0A        // if so, make a new Date based on it%0A        var d = new Date(snap.val()%5BsenderID%5D);%0A        // callback with whether 30s (30k ms) has passed
 %0A   
@@ -4742,24 +4742,73 @@
 rn;%0A      %7D%0A
+      // callback with true because no timestamp%0A
       callba

Update comments