const asyncHandler = require("express-async-handler");
const moment = require('moment-timezone');
const { ObjectId } = require('mongodb');
const { UserDb } = require("../services/userDb");
const crypto = require('crypto');
const { error } = require("console");

function ClearUserData(user){
  delete user.salt;
  delete user.hashed_password;
  delete user.salt;
  delete user.isAgent;
  return user;
}

function ClearUserDataForAdmin(user){
  delete user.salt;
  delete user.hashed_password;
  delete user.salt;
  return user;
}

// DB
exports.get = asyncHandler(async (req, res, next) => {

  try{
      const userDb = await UserDb.init();
      const id = req.params.id;      
      let result = await userDb.get(id);
      if (req.user.isAdmin){      
        res.status(200).send(ClearUserDataForAdmin(result));
      }else{
        res.status(200).send(ClearUserData(result));
      }
  }catch(err){
      console.log(err);
      return res.status(500).send({error: err});
  }
  
});

exports.post = asyncHandler(async (req, res, next) => {

  try{
      const userDb = await UserDb.init();
      // check if double
      let User = await userDb.getByEmail(req.body.email);
      if(User){
        return res.status(500).send({error: "User already exists"});
      }
      
      // check password
      if(!req.body.password){
        return res.status(500).send({error: "Password not set"});
      }
      if(req.body.password != req.body.confirmPassword){
        return res.status(500).send({error: "Passwords do not match"});
      }
      if(req.body.password.length < 8){
        return res.status(500).send({error: "Password too short"});
      }

      if(req.body.isAdmin){
        if(req.user){
          if(!req.user.isAdmin){
            return res.status(500).send({error: "You are not allowed to create an admin user"});
          }
        }else{
          req.body.isAdmin = false
        }
      }

      if(req.body.isAgent){
        if(req.user){
          if(!req.user.isAgent){
            return res.status(500).send({error: "You are not allowed to create an agent user"});
          }          
        }else{
          req.body.isAgent = false
        }
      }

      let salt = crypto.randomBytes(16).toString('hex');
      let user = {                
        username: req.body.username,
        hashed_password: crypto.pbkdf2Sync(req.body.password, salt, 310000, 32, 'sha256').toString('hex'),
        salt: salt,
        email: req.body.email,
        isAdmin: req.body.isAdmin,
        isAgent: req.body.isAgent,
      }
    
      let createData = await userDb.post(user);
      
      res.status(204).send({message: "User created"});
  }catch(err){
      console.log(err);
      return res.status(500).send({error: err});
  }
  
});

exports.put = asyncHandler(async (req, res, next) => {

    try{
        const userDb = await UserDb.init();
        const id = req.params.id;

        const User = await userDb.get(id);
        if(!User){
          return res.status(500).send({error:"User not found"});
        }
        
        // check password
        let hashed_password = "";
        let salt = "";
        if(req.body.password){
          if(req.body.password != req.body.confirmPassword){
            return res.status(500).send({error:"Passwords do not match"});
          }
          if(req.body.password.length < 8){
            return res.status(500).send({error:"Password too short"});
          }
          salt = crypto.randomBytes(16).toString('hex');
          hashed_password = crypto.pbkdf2Sync(req.body.password, salt, 310000, 32, 'sha256').toString('hex');
        }else{
          salt = User.salt;
          hashed_password = User.hashed_password;
        }        

        if(req.body.isAdmin){
          if(!req.user.isAdmin){
            return res.status(500).send({error:"You are not allowed to create an admin user"});
          }
        }
        if(req.body.isAgent){
          if(!req.user.isAdmin){
            return res.status(500).send({error:"You are not allowed to create an agent user"});
          }
        }

        let user = {                
          username: req.body.username,
          hashed_password: hashed_password,
          salt: salt,
          email: req.body.email,
          isAdmin: req.body.isAdmin,
          isAgent: req.body.isAgent,
        }
        
        let result = await userDb.put(id, user);
        console.log(result);
        res.status(200).send(result);
    }catch(err){
        console.log(err);
        return res.status(500).send({error: err});
    }
    
});

exports.delete = asyncHandler(async (req, res, next) => {
  try{
      const userDb = await UserDb.init();
      const id = req.params.id;      

      // Remove the sale
      await userDb.remove(id);
            
      res.status(200).send({"message": "User deleted"});
  }catch(err){
      console.log(err);
      return res.status(500).send({error: err});
  }
  
});

// Functions
exports.current = asyncHandler(async (req, res, next) => {
  try{
      const user = ClearUserData(req.user);
      res.status(200).send(user);
  }catch(err){
      console.log(err);
      return res.status(500).send({error: err});
    }
    
});


exports.agentConnected = asyncHandler(async (req, res, next) => {
  try{      
      res.status(200).send({message: "Agent connected"});
  }catch(err){
      console.log(err);
      return res.status(500).send({error: err});
    }    
});

exports.getAllUsers = asyncHandler(async (req, res, next) => {
  try{
      const userDb = await UserDb.init();
      let result = await userDb.getAll();
      result = result.map(user => ClearUserDataForAdmin(user));
      res.status(200).send(result);
  }catch(err){
      console.log(err);
      return res.status(500).send({error: err});
  }
  
});