package com.mason.server.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.google.appengine.api.datastore.KeyFactory;
import com.mason.server.dao.jdo.LogDAO;
import com.mason.server.dao.jdo.ProjectAccessDAO;
import com.mason.server.dao.jdo.UserDAO;
import com.mason.server.model.DbUser;
import com.mason.server.model.Log;
import com.mason.server.validator.UserValidator;

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Controller
@RequestMapping("/user")
public class UserController {

	private static UserDAO userDAO = new UserDAO();
	private static LogDAO logDAO = new LogDAO();
	private static ProjectAccessDAO projectAccessDAO = new ProjectAccessDAO();

	BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

	@RequestMapping(value = "/login", method = RequestMethod.GET)
	public String getLoginPage(boolean error, ModelMap model) {
		return "user/userLogin";
	}

	@RequestMapping(value = "/register", method = RequestMethod.GET)
	public String getAddProjectPage(ModelMap model) {
		model.addAttribute("dbUser", new DbUser());
		return "user/userRegister";
	}

	@RequestMapping(value = "/{usernameSlug}", method = RequestMethod.GET)
	public String getUserPage(@PathVariable String usernameSlug, ModelMap model) {
		return "redirect:/" + usernameSlug;
	}

	@RequestMapping(value = "/{usernameSlug}/update", method = RequestMethod.GET)
	public String getUpdateUserPage(@PathVariable String usernameSlug,
			ModelMap model) {
		DbUser user = userDAO.getByUsername(usernameSlug);
		user.setPassword("");
		model.addAttribute(user);
		return "user/userUpdate";
	}

	@RequestMapping(value = "/{usernameSlug}/update", method = RequestMethod.POST)
	public String processUpdateUser(@PathVariable String usernameSlug, DbUser user,
			BindingResult result) {
		


		user.setId(KeyFactory.stringToKey(user.getGeneratedKey()).getId());
		user.setUsername(usernameSlug);

		UserValidator pv = new UserValidator();
		pv.validate(user, result);

		if (result.hasErrors()) {
			return "user/userUpdate";
		}
		
		user.setPassword(passwordEncoder.encode(user.getPassword()));

		user.setAccess(1);
		
		userDAO.update(user);
		logDAO.add(new Log(user.getId(), DbUser.class.getSimpleName(),
				Log.Action.UPDATE));

		return "redirect:/" + usernameSlug;
	}

	@RequestMapping(value = "/{usernameSlug}/delete", method = RequestMethod.GET)
	public String getdeleteUserPage(@PathVariable String usernameSlug,
			ModelMap model) {
		model.addAttribute(userDAO.getByUsername(usernameSlug));
		return "user/userDelete";
	}

	@RequestMapping(value = "/{usernameSlug}/delete", method = RequestMethod.POST)
	public String deleteUser(@PathVariable String usernameSlug, ModelMap model) {
		DbUser user = userDAO.getByUsername(usernameSlug);
		userDAO.deleteById(user.getId());
		logDAO.add(new Log(user.getId(), DbUser.class.getSimpleName(),
				Log.Action.DELETE));
		projectAccessDAO.deleteAllByUserId(user.getId());
		return "redirect:/welcome";
	}

	@RequestMapping(value = "/register", method = RequestMethod.POST)
	public String register(DbUser user, BindingResult result) {

		user.setPassword(passwordEncoder.encode(user.getPassword()));

		UserValidator pv = new UserValidator();
		pv.validate(user, result);

		if (result.hasErrors()) {
			return "user/userRegister";
		}

		user.setAccess(1);

		user = UserController.userDAO.add(user);
		logDAO.add(new Log(user.getId(), DbUser.class.getSimpleName(),
				Log.Action.CREATE));

		return "redirect:/" + user.getUsername();
	}
}
