package com.qmth.qrzk.web.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import com.qmth.qrzk.repository.constants.WebConstants;
import com.qmth.qrzk.repository.user.model.OLUser;
import com.qmth.qrzk.repository.user.model.Role;
import com.qmth.qrzk.repository.user.model.User;
import com.qmth.qrzk.repository.user.service.IRoleService;
import com.qmth.qrzk.repository.user.service.IUserService;
import com.qmth.qrzk.repository.utils.Consts;
import com.qmth.qrzk.repository.utils.General;

@Controller("loginController")
@RequestMapping("/")
public class LoginController extends BaseAjaxController{
	
	@Autowired
	@Qualifier("userServiceImpl")
	private IUserService userService;
	
	@Autowired
	@Qualifier("roleServiceImpl")
	private IRoleService roleService;
	
	@RequestMapping("")
	public ModelAndView index(){
		return new ModelAndView("redirect:/login");
	}
	
	@RequestMapping("/index")
	public ModelAndView goIndex(){
		return new ModelAndView("redirect:/login");
	}
	
	@RequestMapping("/main")
	public ModelAndView main(HttpSession session){
		User user = (User) session.getAttribute(WebConstants.WEB_SESSION_USER);
    	Role role = (Role)session.getAttribute(WebConstants.WEB_SESSION_ROLE);
    	Date lastLoginDate = (Date)session.getAttribute(WebConstants.WEB_SESSION_USER_LAST_LOGIN_DATE);
    	ModelAndView view = new ModelAndView("index");
        view.addObject("user", user);
        view.addObject("role", role);
        view.addObject("lastLoginDate", lastLoginDate);
        return view;
	}
	
	@RequestMapping(value="/login",method=RequestMethod.GET)
	ModelAndView login(HttpServletRequest request,HttpSession session){
		Authentication auth = SecurityContextHolder.getContext().getAuthentication();
		if (!(auth instanceof AnonymousAuthenticationToken)) {
			User user = (User) session.getAttribute(WebConstants.WEB_SESSION_USER);
	    	Role role = (Role)session.getAttribute(WebConstants.WEB_SESSION_ROLE);
	    	Date lastLoginDate = (Date)session.getAttribute(WebConstants.WEB_SESSION_USER_LAST_LOGIN_DATE);
	    	
	    	ModelAndView view = new ModelAndView("index");
	        view.addObject("user", user);
	        view.addObject("role", role);
	        view.addObject("lastLoginDate", lastLoginDate);
	        return view;
		}
		else
		{
			ModelAndView view = new ModelAndView("login/login"); 
			String error = request.getParameter("error");
			view.addObject("error",error);
			return view;
		}
	}
	
	//for 403 access denied page
	@RequestMapping(value = "/403", method = RequestMethod.GET)
	public ModelAndView accesssDenied() {
 
	  ModelAndView model = new ModelAndView();
 
	  //check if user is login
	  Authentication auth = SecurityContextHolder.getContext().getAuthentication();
	  if (!(auth instanceof AnonymousAuthenticationToken)) {
		UserDetails userDetail = (UserDetails) auth.getPrincipal();	
		model.addObject("username", userDetail.getUsername());
	  }
 
	  model.setViewName("/login/403");
	  return model;
	}
	
	@RequestMapping(value="/selectRole")
	ModelAndView selectRole(HttpServletRequest request)
	{
		@SuppressWarnings("unchecked")
		List<Role> roles = (List<Role>)request.getSession().getAttribute(WebConstants.WEB_SESSION_ALLROLES);
		ModelAndView view = new ModelAndView("login/selectRole"); 
		view.addObject("roles", roles);
		return view;
	}
	
	@RequestMapping(value="/setRole")
	void setRole(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException
	{
		String roleCode = request.getParameter("roleCode");

    	Authentication auth = SecurityContextHolder.getContext().getAuthentication();
    	List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
    	authorities.add(new SimpleGrantedAuthority(roleCode));
    	if(roleService.isQuesAuditor(this.getCurUser(session).getId())){
    		authorities.add(new SimpleGrantedAuthority(Consts.UserRoleCodes.QUES_AUDITOR));
    	}
    	if(roleService.isQuesInputer(this.getCurUser(session).getId())){
    		authorities.add(new SimpleGrantedAuthority(Consts.UserRoleCodes.QUES_INPUTER));
    	}
    	Authentication newAuth = new UsernamePasswordAuthenticationToken(auth.getPrincipal(),auth.getCredentials(),authorities);
    	SecurityContextHolder.getContext().setAuthentication(newAuth);
    	
    	List<Role> roles = this.getAllRole(session);
    	Role setRole = null;
    	for(Role role : roles)
    	{
    		if(roleCode.equalsIgnoreCase(role.getCode()))
    		{
    			setRole = role;
    			break;
    		}
    	}
    	session.setAttribute(WebConstants.WEB_SESSION_ROLE, setRole);
    	response.sendRedirect(General.getBasePath(request) + "/main");
	}
}
