var Group = require('./../lib/model')('groups');

// users: Array
//    name
//    email
// current_user: int
// on_hold: bool
// emergency: bool

var mailer = require('./../mailers/group');

Group.instance.sortUsers = function(){
  this.users = _.sortBy(this.users, function(u){
    return u.name;
  });
};

Group.instance.addUser = function(user, callback) {
  var groupId = this._id;
  var hasUser = _.some(this.users, function(u){
    return u.email === user.email;
  });

  if (hasUser) {
    mailer.add(user.email, groupId, hasUser);
    return callback();
  }

  this.users.push(user);
  this.sortUsers();
  this.save(function(err){
    if (err) return callback(err);
    mailer.add(user.email, groupId, hasUser);
    callback();
  });
};

Group.instance.removeUser = function(user, callback){
  var hadUser = false;
  var groupId = this._id;
  this.users = _.reject(this.users, function(u){
    var userMatch = u.email === user.email;
    if (userMatch) hadUser = true;
    return userMatch;
  });

  if (!hadUser) {
    mailer.remove(user.email, groupId, hadUser);
    return callback();
  }

  this.save(function(err){
    if (err) return callback(err);
    mailer.remove(user.email, groupId, hadUser);
    callback();
  });
};

Group.instance.activateHold = function(user, callback) {
  if (this.on_hold) {
    mailer.hold(user.email, this._id, false);
    return callback();
  }

  this.on_hold = true;
  var _this = this;
  this.save(function(err){
    if (err) return callback(err);
    for (var i = 0, len=_this.users.length; i<len; i++) {
      mailer.hold(_this.users[i].email, _this._id, true);
    }
    callback();
  });
};

Group.instance.raiseEmergency = function(user, callback) {
  var groupId = this._id;

  if (this.emergency) {
    mailer.emergency(user.email, groupId, false);
    return callback();
  }

  this.emergency = true;
  var origPicker = this.users[this.current_user];

  this.users = _.reject(this.users, function(u){
    return u.email === origPicker.email;
  });

  var currPicker = this.users[this.current_user];
  this.save(function(err){
    if (err) return callback(err);
    if (origPicker) mailer.remove(origPicker.email, groupId, true);
    if (currPicker) mailer.alert(currPicker.email, groupId);
    mailer.emergency(user.email, groupId, true);

    callback();
  });
};

Group.instance.listUsers = function(user, callback) {
  mailer.list(user.email, this._id, this.users, callback);
};

Group.instance.currUserResponse = function(user, message, callback) {
  if (this.users[this.current_user].email !== user.email) return callback();

  console.log(message);
  if (message.match('pass')) {
    this.incrementUser();
    var newUser = this.users[this.current_user];
    var groupId = this._id;
    this.save(function(err){
      if (err) return callback(err);
      mailer.pass(this.email, groupId, callback);
      mailer.alert(newUser.email, groupId, callback);
      callback();
    });
  }
};

Group.instance.incrementUser = function() {
  this.current_user = this.current_user >= this.users.length-1 ? 0 : this.current_user+1;
};

Group.createFromUser = function(id, user, callback) {
  var group = {
    _id: id,
    emergency: false,
    on_hold: false,
    users: [],
    current_user: 0
  };

  group.users.push(user);

  Group.save(group, function(err, group){
    if (err) return callback(err);
    mailer.created(user.email, group._id);
    callback();
  });
};

Group.idFromEmail = function(email) {
  var emailParts = email.match(/(.+@)(.+)(\..+$)/);
  return emailParts.length > 3 ? emailParts[2] : false;
};


Group.createOrUpdate = function(user, action, message, callback) {
  var id = Group.idFromEmail(user.email);

  if (!id) {
    console.log('NO ID EXTRACTED:', user.email);
    return callback();
  }

  if (action === 'help') {
    return mailer.help(user.email, callback);
  }

  Group.get(id, function(err, group){
    if (err) return callback(err);
    if (!group) {
      Group.createFromUser(id, user, callback);
    } else {
      var methods = {
        add: 'addUser',
        remove: 'removeUser',
        hold: 'activateHold',
        emergency: 'raiseEmergency',
        list: 'listUsers'
      };

      if (methods[action]) {
        group[methods[action]](user, callback);
      } else {
        group.currUserResponse(user, message, callback);
      }
    }
  });
};

module.exports = Group;