var EventEmitter = require('events');
var Express = require('express');
var Router = Express.Router();
var Token = require('../modules/token');
var UserModel = require('../models/user');

function updateUser (req, res, next) {
  Token.verifyThen(req.get('authorization'), 'super', (err, decoded) => {
    if (err) {
      res.status(403).json({ message: 'User not authorized to perform this action.', err: err });
      return;
    } 
    
    if (decoded && decoded.hasPermission) {
      var UserEvents = new EventEmitter();
      var id = req.params.id;
      var data = req.body;

      if (id === decoded.data.uid || decoded.canElevate) {
        if (!decoded.canElevate) {
          delete data.permission;
        }
    
        UserEvents.once('updateUser', (err, result) => {
          if (err) {
            res.status(500).json({message: 'Could not update user id ' + id, err: err});
          }

          if (result) {
            res.status(200).json(result);
          }
        });

        UserModel.updateUser(UserEvents, id, data);
      } else {
        res.status(403).json({ message: 'User not authorized to perform this action.' });
      }
    }
  });
}

function updateUserSetting (req, res, next) {
  Token.verifyThen(req.get('authorization'), 'view', (err, decoded) => {
    if (err) {
      res.status(403).json({ message: 'User not authorized to perform this action.', err: err });
      return;
    }
    
    if (decoded && decoded.hasPermission) {
      var UserEvents = new EventEmitter();
      var userId = req.params.userId;
      var settingsId = req.params.settingsId;
      var data = req.body;


      UserEvents.once('updateUserSetting', (err, result) => {
        if (err) {
          res.status(500).json({ message: 'Could not update setting' + (data.key ? ' key:' + data.key : 's') + ' for user ' + (userId ? userId : ''), err: err });
        }

        if (result) {
          res.status(200).json(result);
        }
      });

      UserModel.updateUserSetting(UserEvents, userId, settingsId, data);
    }
  });
}

Router.route('/')
  .post((req, res, next) => {
    Token.verifyThen(req.get('authorization'), 'super', (err, decoded) => {
      if (err || (decoded && !decoded.hasPermission)) {
        res.status(403).json({ message: 'User not authorized to perform this action.', err: err });
        return;
      } 
    
      if (decoded && decoded.hasPermission) {
        var UserEvents = new EventEmitter();
        var user = req.body;

        UserEvents.once('createUser', (err, result) => {
          if (err) {
            res.status(500).json({ message: 'Could not create user', err: err });
          }

          if (result) {
            res.status(200).json(result);
          }
        });

        UserModel.createUser(UserEvents, user);
      }
    });
  });

Router.route('/search/:find?')
  .get((req, res, next) => {
    Token.verifyThen(req.get('authorization'), 'super', (err, decoded) => {
      if (err || (decoded && !decoded.hasPermission)) {
        res.status(403).json({ message: 'User not authorized to perform this action.', err: err });
        return;
      } 
    
      if (decoded && decoded.hasPermission) {
        var UserEvents = new EventEmitter();

        // Process parameters
        var find = req.params.find ? decodeURIComponent(req.params.find) : false;

        if (find) {
          find = {
            'userName': new RegExp(find, 'i'),
            'name.last': new RegExp(find, 'i'),
            'name.first': new RegExp(find, 'i'),
            'email': new RegExp(find, 'i')
          };
        }

        // Setup query object
        var query = {
          find: find || (req.query.find ? JSON.parse(decodeURIComponent(req.query.find)) : {}),
          select: req.query.select ? decodeURIComponent(req.query.select) : null,
          options: {
            limit: req.query.limit ? parseInt(req.query.limit) : 0,
            skip: req.query.ski ? parseInt(req.query.skip) : 0,
            sort: req.query.sort ? JSON.parse(decodeURIComponent(req.query.sort)) : { 'userName': 1 }
          }
        };

        UserEvents.once('getUsers', (err, result) => {
          if (err) {
            res.status(500).json({ message: 'There was an error performing the user search', err: err });
          }

          if (result) {
            res.status(200).json(result);
          }
        });

        UserModel.getUsers(UserEvents, query);
      }
    });
  });

Router.route('/validate/:username?')
  .get((req, res) => {
    Token.verifyThen(req.get('authorization'), 'view', (err, decoded) => {
      if (err || (decoded && !decoded.hasPermission)) {
        res.status(403).json({ message: 'User not authorized to perform this action.', err: err });
        return;
      } 
   
      if (decoded && decoded.hasPermission) {
        var UserEvents = new EventEmitter();
        var username = req.params.username || '';

        if (username && username.length >= 4) {
          UserEvents.once('isUserNameUnique', (err, result) => {
            if (err) {
              res.status(500).json({ message: 'Could not validate username: ' + username, err: err });
            }

            if (result) {
              res.status(200).json(result);
            }
          });

          UserModel.isUserNameUnique(UserEvents, username);
        } else {
          res.status(200).json({ unique: null, length: false });
        }
      }
    });
  });

Router.route('/force-password-reset/:id')
  .post( (req, res, next) => {
    Token.verifyThen(req.get('authorization'), 'super', (err, decoded) => {
      if (err || (decoded && !decoded.hasPermission)) {
        res.status(403).json({ message: 'User not authorized to perform this action.', err: err });
        return;
      } 
    
      if (decoded && decoded.hasPermission) {
        var UserEvents = new EventEmitter();
        var id = req.params.id;

        UserEvents.once('forcePasswordReset', (err, result) => {
          if (err) {
            res.status(500).json({ message: 'Could not force password reset for the user', err: err });
          }

          if (result) {
            res.status(200).json(result);
          }
        });

        UserModel.forcePasswordReset(UserEvents, id);
      }
    });
  });
  
Router.route('/:id/settings/:key?')
  .get( (req, res, next) => {
    Token.verifyThen(req.get('authorization'), 'view', (err, decoded) => {
      if (err || (decoded && !decoded.hasPermission)) {
        res.status(403).json({ message: 'User not authorized to perform this action.', err: err });
        return;
      } 
    
      if (decoded && decoded.hasPermission) {
        var UserEvents = new EventEmitter();
        var id = req.params.id;
        var key = req.params.key || false;
        var method = key ? 'getUserSetting' : 'getUserSettings';

        UserEvents.once(method, (err, result) => {
          if (err) {
            res.status(500).json({ message: 'Could not get setting' + (key ? ' key:' + key : 's') + ' for user ' + (id ? id : ''), err: err });
          }

          if (result) {
            res.status(200).json(result);
          }
        });

        UserModel[method](UserEvents, id, key);
      }
    });
  });

Router.route('/:userId/settings/:settingsId?')
  .patch( updateUserSetting )
  .post( (req, res, next) => {
    Token.verifyThen(req.get('authorization'), 'view', (err, decoded) => {
      if (err || (decoded && !decoded.hasPermission)) {
        res.status(403).json({ message: 'User not authorized to perform this action.', err: err });
        return;
      }
    
      if (decoded && decoded.hasPermission) {
        var UserEvents = new EventEmitter();
        var userId = req.params.userId;
        var data = req.body;

        UserEvents.once('createUserSetting', (err, result) => {
          if (err) {
            res.status(500).json({ message: 'Could not create setting' + (data.key ? ' key:' + data.key : 's') + ' for user ' + (userId ? userId : ''), err: err });
          }

          if (result) {
            res.status(200).json(result);
          }
        });

        UserModel.createUserSetting(UserEvents, userId, data);
      }
    });
  })
  .put( updateUserSetting );

Router.route('/:id?')
	.get( (req, res, next) => {
    Token.verifyThen(req.get('authorization'), 'manage', (err, decoded) => {
      if (err || (decoded && !decoded.hasPermission)) {
        res.status(403).json({ message: 'User not authorized to perform this action. ' + err, err: err });
        return;
      } 
    
      if (decoded && decoded.hasPermission) {
        var UserEvents = new EventEmitter();
        var id = req.params.id || false;
        var method = id ? 'getUser' : 'getUsers';

        if ((id === decoded.data.uid && method === 'getUser') || decoded.canElevate) {
          UserEvents.once(method, (err, result) => {
            if (err) {
              res.status(500).json({ message: 'Could not get user' + (id ? '' : 's'), err: err });
            }

            if (result) {
              res.status(200).json(result);
            }
          });

          UserModel[method](UserEvents, id || false, !decoded.canElevate);
        } else {
          res.status(403).json({ message: 'User not authorized to perform this action.' });
        }
      }
    });
	})
	.put( updateUser )
	.patch( updateUser )
	.delete( (req, res, next) => {
    Token.verifyThen(req.get('authorization'), 'manage', (err, decoded) => {
      if (err || (decoded && !decoded.hasPermission)) {
        res.status(403).json({ message: 'User not authorized to perform this action.', err: err });
        return;
      } 
    
      if (decoded && decoded.hasPermission) {
        var UserEvents = new EventEmitter();
        var id = req.params.id;

        if (id === decoded.data.uid) {
          res.status(403).json({ message: 'You cannot delete yourself. Surely it isn\'t that bad?!' });
          return;
        }

        UserEvents.once('deleteUser', (err, result) => {
          if (err) {
            res.status(500).json({message: 'Could not delete user id ' + id, err: err});
          }

          if (result) {
            res.status(204).json({});
          }
        });

        UserModel.deleteUser(UserEvents, id);
      }
    });
	});

module.exports = Router;
