package com.bonus.boot.manager.manager.config;

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

import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.bonus.boot.manager.manager.controller.JwtUtils;
import com.bonus.boot.manager.manager.controller.SecurityConstants;
import com.bonus.boot.manager.manager.dao.PermissionDao;
import com.bonus.boot.manager.manager.model.Permission;
import com.bonus.boot.manager.manager.model.SysUser;
import com.bonus.boot.manager.manager.service.PermissionService;
import com.bonus.boot.manager.manager.service.TokenService;
import com.bonus.boot.manager.manager.service.impl.UserServiceImpl;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.MalformedJwtException;
import lombok.val;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;

import com.bonus.boot.manager.manager.entity.LoginUser;
import com.bonus.boot.manager.manager.entity.ResponseInfo;
import com.bonus.boot.manager.manager.entity.Token;
import com.bonus.boot.manager.manager.filter.TokenFilter;
import com.bonus.boot.manager.manager.utils.ResponseUtil;

/**
 * spring security处理器
 * 
 */
@Configuration
public class SecurityHandlerConfig {

	@Autowired
	private TokenService tokenService;

	@Resource
	private UserServiceImpl userService;

	@Resource
	private PermissionDao permissionDao;

	/**
	 * 登陆成功，返回Token
	 * 
	 * @return
	 */
	@Bean
	public AuthenticationSuccessHandler loginSuccessHandler() {
		return new AuthenticationSuccessHandler() {

			@Override
			public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
					Authentication authentication) throws IOException, ServletException {
				LoginUser loginUser = (LoginUser) authentication.getPrincipal();

				Token token = tokenService.saveToken(loginUser);
				ResponseUtil.responseJson(response, HttpStatus.OK.value(), token);
			}
		};
	}

	/**
	 * 登陆失败
	 * 
	 * @return
	 */
	@Bean
	public AuthenticationFailureHandler loginFailureHandler() {
		return new AuthenticationFailureHandler() {

			@Override
			public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
					AuthenticationException exception) throws IOException, ServletException {
				String msg = null;
				if (exception instanceof BadCredentialsException) {
					msg = "密码错误";
				} else {
					msg = exception.getMessage();
				}
				System.err.println("loginFailureHandler="+msg);
				String userName = request.getParameter("username");
				String jwtToken = request.getParameter("jwtToken");
				try {
					Claims claims = JwtUtils.parseToken(jwtToken);
					String newUserName = (String) claims.get(SecurityConstants.DETAILS_USERNAME);
					if(userName !=null && userName !="" && userName.equals(newUserName) && jwtToken !=null && jwtToken !=""){
						LoginUser loginUser  =  new LoginUser();
						SysUser user = userService.getUser(userName);
						List<Permission> permissionList = permissionDao.listByRoleId(Long.valueOf(user.getRoleId()));
						loginUser.setPermissions(permissionList);
						loginUser.setUsername(user.getUsername());
						loginUser.setDepartment(user.getDepartment());
						loginUser.setPassword(user.getPassword());
						loginUser.setPhone(user.getPhone());
						loginUser.setId(user.getId());
						loginUser.setHospitalId(user.getHospitalId());
						loginUser.setOrgId(user.getOrgId());
						Map<String,Object> map = new HashMap<>();
						Token token = tokenService.saveToken(loginUser);
						map.put("token",token.getToken());
						map.put("hospitalId",user.getHospitalId());
						ResponseUtil.responseJson(response, HttpStatus.OK.value(), map);
					}else{
						ResponseInfo info = new ResponseInfo(HttpStatus.UNAUTHORIZED.value() + "", msg);
						ResponseUtil.responseJson(response, HttpStatus.UNAUTHORIZED.value(), info);
					}
				}catch (MalformedJwtException e){
					msg = "token解析错误";
					ResponseInfo info = new ResponseInfo(HttpStatus.UNAUTHORIZED.value() + "", msg);
					ResponseUtil.responseJson(response, HttpStatus.UNAUTHORIZED.value(), info);
				}

			}
		};

	}

	/**
	 * 未登录，返回401
	 * 
	 * @return
	 */
	@Bean
	public AuthenticationEntryPoint authenticationEntryPoint() {
		return new AuthenticationEntryPoint() {

			@Override
			public void commence(HttpServletRequest request, HttpServletResponse response,
					AuthenticationException authException) throws IOException, ServletException {
				ResponseInfo info = new ResponseInfo(HttpStatus.UNAUTHORIZED.value() + "", "请先登录");
				ResponseUtil.responseJson(response, HttpStatus.UNAUTHORIZED.value(), info);
			}
		};
	}

	/**
	 * 退出处理
	 * 
	 * @return
	 */
	@Bean
	public LogoutSuccessHandler logoutSussHandler() {
		return new LogoutSuccessHandler() {

			@Override
			public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
					Authentication authentication) throws IOException, ServletException {
				ResponseInfo info = new ResponseInfo(HttpStatus.OK.value() + "", "退出成功");

				String token = TokenFilter.getToken(request);
				tokenService.deleteToken(token);

				ResponseUtil.responseJson(response, HttpStatus.OK.value(), info);
			}
		};

	}

}
