package com.qmth.qrzk.web.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

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

import net.sf.json.JSONObject;

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.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.ModelAndView;

import com.qmth.qrzk.dao.repositories.BatchRepo;
import com.qmth.qrzk.dao.repositories.UserRepo;
import com.qmth.qrzk.repository.constants.WebConstants;
import com.qmth.qrzk.repository.user.model.PaperBatch;
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.user.service.SessionUser;
import com.qmth.qrzk.repository.utils.Consts;

@Controller("loginController")
@RequestMapping("/")
public class LoginController extends BaseAjaxController implements SessionUser{
	
	@Autowired
	@Qualifier("userServiceImpl")
	private IUserService userService;
	
	@Autowired private UserRepo userRepo;
	@Autowired private BatchRepo batchRepo;
	
	@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)
	{
		Authentication auth = SecurityContextHolder.getContext().getAuthentication();
		if (!(auth instanceof AnonymousAuthenticationToken)) {
			HttpSession session = request.getSession();
			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;
	}
	
	@SuppressWarnings("unchecked")
	@RequestMapping(value="/setRole")
	ModelAndView setRole(HttpServletRequest request)
	{
		String roleCode = request.getParameter("roleCode");

    	Authentication auth = SecurityContextHolder.getContext().getAuthentication();
    	List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
    	authorities.add(new SimpleGrantedAuthority(roleCode));
    	Authentication newAuth = new UsernamePasswordAuthenticationToken(auth.getPrincipal(),auth.getCredentials(),authorities);
    	SecurityContextHolder.getContext().setAuthentication(newAuth);
    	
    	List<Role> roles = (List<Role>)request.getSession().getAttribute(WebConstants.WEB_SESSION_ALLROLES);
    	Role setRole = null;
    	for(Role role : roles)
    	{
    		if(roleCode.equalsIgnoreCase(role.getCode()))
    		{
    			setRole = role;
    			break;
    		}
    	}
    	request.getSession().setAttribute(WebConstants.WEB_SESSION_ROLE, setRole);
    	request.getSession().setAttribute("headMenu", "user");
        request.getSession().setAttribute("subMenu", "info");
		return new ModelAndView("redirect:/user/info"); 
	}

	@RequestMapping(value="clientlogin",method=RequestMethod.POST)
	public @ResponseBody JSONObject clientLogin(@RequestParam String username,@RequestParam String password,HttpServletRequest request){
		JSONObject result = new JSONObject();
		List<User> users = userRepo.findByLoginName(username);
		if(users.size() == 0){
			result.accumulate("result", false);
			result.accumulate("error", "用户不存在");
		}
		else{
			User user = users.get(0);
			String pw = user.getPassword();
			List<Role> roles = user.getRoles();
			List<String> roleStrs = new ArrayList<String>();
			for(int i = 0 ; i < roles.size();i++){
				roleStrs.add(roles.get(i).getCode());
			}
			
			if(roleStrs.indexOf(Role.INPUT_ROLE_CODE) == -1){
				result.accumulate("result", false);
				result.accumulate("error", "该用户类型不允许登录");
			}
			else if(pw.equals(password)){
				result.accumulate("result", true);
				result.accumulate("userId",user.getId());
				Consts.ClientIpUserMap.put(request.getRemoteAddr(), user.getId());
				result.accumulate("name",user.getName());
				PaperBatch batch = batchRepo.findLastest().get(0);
				result.accumulate("batchId", batch.getId());
			}
			else{
				result.accumulate("result", false);
				result.accumulate("error", "用户名或密码错误");
				
			}
		}
		
		return result;
	}
	
	@Override
	public User getSessionUser() {
		HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest();
		User user = (User)request.getSession(true).getAttribute(WebConstants.WEB_SESSION_USER);	
		return user;
	}
}
