package com.saye.hospitalgd.controller.system;

import com.saye.hospitalgd.commons.date.DateDUtil;
import com.saye.hospitalgd.commons.log.ExceptionDUtil;
import com.saye.hospitalgd.commons.log.LogUtil;
import com.saye.hospitalgd.commons.string.StringDUtil;
import com.saye.hospitalgd.model.ResourceInfo;
import com.saye.hospitalgd.model.Users;
import com.saye.hospitalgd.service.UnilateralService;
import com.saye.hospitalgd.service.system.MenuService;
import com.saye.hospitalgd.service.system.ServiceParamsService;
import com.saye.hospitalgd.service.system.UsersService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.ExpiredCredentialsException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

@Controller
public class LoginController {

	@Autowired
	private MenuService menuService;
	@Autowired
	private UsersService usersService;
	@Autowired
	private ServiceParamsService serviceParamsService;


	/**
	 * @description 去登录页面
	 * @author dqzhang       
	 * @created 2019年11月13日 下午4:22:48 
	 * @param map
	 * @return
	 */
	@RequestMapping("/toLogin")
	public String toLogin(ModelMap map) {

		List<HashMap<Object, Object>> list = serviceParamsService.findParamValByParamCode("prj_name");
		map.addAttribute("prj_name",list.get(0).get("PARAM_VAL"));
		return "login";
	}
	
	/**
	 * @description 登录
	 * @author dqzhang       
	 * @created 2019年11月13日 下午5:03:11 
	 * @return
	 */
	@RequestMapping("/login")
	@ResponseBody
	public HashMap<Object,Object> signin(@RequestBody Map map) {
		
		String key = StringDUtil.removeSpaces(map.get("key"));
		String username = StringDUtil.removeSpaces(map.get("username"));
		String password = StringDUtil.removeSpaces(map.get("password"));
		String vercode = StringDUtil.removeSpaces(map.get("vercode"));
		String initVector = StringDUtil.removeSpaces(map.get("initVector"));
		
		String errCode = "0";
		String errMsg = "";
		Subject subject = SecurityUtils.getSubject();
		
        try {
			String code = (String) subject.getSession().getAttribute("verify_code");
			if(!code.equalsIgnoreCase(vercode)) {
				errCode = "CodeError";
				errMsg = "验证码不正确！";
			}
			if("0".equals(errCode)) {
				UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username, password);
				subject.login(usernamePasswordToken);
				LogUtil.info(getClass(), "用户："+username+"登录系统");
			}
		} catch (ExcessiveAttemptsException e) {
			errCode = "ExcessiveAttempts";
		    errMsg =  "账户已锁定，请稍后再试！";
		    LogUtil.error(this.getClass(), "登录失败，原因:"+errMsg);
		} catch (ExpiredCredentialsException e) {
			errCode = "ExpiredCredentials";
		    errMsg =  "账号已过期！";
		    LogUtil.error(this.getClass(), "登录失败，原因:"+errMsg);
		} catch (AuthenticationException e) {
			errCode = "Authentication";
		    errMsg =  "账号或密码错误！";
		    LogUtil.error(this.getClass(), "登录失败，原因:"+errMsg);
		} catch (Exception e) {
			 errCode = e.getLocalizedMessage();
		     errMsg =  "未知异常！";
		     LogUtil.error(this.getClass(), "登录失败，原因:"+ExceptionDUtil.getDetailExceptionMsg(e));
		}
        HashMap<Object,Object> resultMap = new HashMap<Object,Object>();
        resultMap.put("errCode", errCode);
        resultMap.put("errMsg", errMsg);
        return resultMap;
	}
	
	/**
	 * @description 首页
	 * @author dqzhang       
	 * @created 2019年11月13日 下午5:10:21 
	 * @param modelMap
	 * @return
	 */
	@RequestMapping("/index")
	public String index(ModelMap modelMap) {
		
		HashMap<Object,Object> map = new HashMap<Object,Object>();
		Subject subject = SecurityUtils.getSubject();
		Users user = (Users) subject.getPrincipal();
		String user_id = user.getUserId();
		map.put("user_id", user_id); 
		ResourceInfo resourceInfo=null;
		modelMap.addAttribute("expired",false);
		try {
			//上次密码修改时间
	        String modifyTime = user.getModifyTime();
	        String modifyDate = modifyTime.substring(0, 10);
	        String today = DateDUtil.getCurrentDate("yyyy-MM-dd");
	        long differDay = DateDUtil.getDaysOfTowDiffDate(modifyDate, today);
	        if(differDay>90) { //密码90天过期
	        	modelMap.addAttribute("expired",true);
	        }
			resourceInfo = this.menuService.getMenuByRole(map);
			String userTrueName = user.getTrueName();
			String userName = user.getUserName();
			modelMap.addAttribute("userTrueName",userTrueName);
			modelMap.addAttribute("userName",userName);
			modelMap.addAttribute("userId",user_id);

			List<HashMap<Object, Object>> list = serviceParamsService.findParamValByParamCode("prj_name");
			modelMap.addAttribute("prj_name",list.get(0).get("PARAM_VAL"));
		} catch (Exception e) {
			e.printStackTrace();
			LogUtil.error(this.getClass(), "跳转首页失败，原因:"+ExceptionDUtil.getDetailExceptionMsg(e));
		}
		modelMap.addAttribute("resourceInfo", resourceInfo.getChildren());


		return "index";
	}
	

	/**
	 * @description 查询菜单
	 * @author thuang       
	 * @created 2019年11月6日 下午3:55:20 
	 * @return
	 */
	@RequestMapping("/menu")
	@ResponseBody
	public ResourceInfo findMenu(){
		HashMap<Object,Object> map = new HashMap<Object,Object>();
		map.put("user_id", "admin");
		map.put("firstNode", "0");
		ResourceInfo resourceInfo=null;
		try {
			resourceInfo = this.menuService.getMenuByRole(map);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			LogUtil.error(this.getClass(), "查询菜单失败，原因:"+ExceptionDUtil.getDetailExceptionMsg(e));
		}
		return resourceInfo;
	}
	
	@RequestMapping("/logout")
	public void logout(HttpServletResponse response) throws IOException {
		
		Subject subject = SecurityUtils.getSubject();
		if(subject.isAuthenticated()) {
			subject.logout();
		}
		response.sendRedirect("/toLogin");
	}
	
	/**
	 * @description 获取验证码
	 * @author dqzhang       
	 * @created 2019年11月27日 下午3:15:32 
	 * @param reuqest
	 * @param response
	 * @throws Exception
	 */
	@RequestMapping("/getCode")
	public void verify(HttpServletRequest reuqest,HttpServletResponse response) throws Exception {
		
		String name = reuqest.getParameter("name");
		
		response.setContentType("image/jpeg");
		response.setHeader("Pragma", "No-cache");
		response.setHeader("Cache-Control", "no-cache");
		response.setDateHeader("Expires", 0L);
		Subject subject = SecurityUtils.getSubject();
		Session session = subject.getSession();

		try {
			int width = 73;
			int height = 27;
			BufferedImage image = new BufferedImage(width, height, 1);

			Graphics g = image.getGraphics();

			Random random = new Random();

			g.setColor(getRandColor(200, 250));
			g.fillRect(0, 0, width, height);

			g.setFont(new Font("Times New Roman", 0, 24));

			g.setColor(getRandColor(160, 200));
			for (int i = 0; i < 155; i++) {
				int x = random.nextInt(width);
				int y = random.nextInt(height);
				int xl = random.nextInt(12);
				int yl = random.nextInt(12);
				g.drawLine(x, y, x + xl, y + yl);
			}

			String sRand = "";
			for (int i = 0; i < 4; i++) {
				String rand = randomInt(1).toUpperCase();
				sRand = sRand + rand;

				g.setColor(new Color(20 + random.nextInt(110), 20 + random
						.nextInt(110), 20 + random.nextInt(110)));
				g.drawString(rand, 13 * i + 6, 24);
			}
			if (StringDUtil.changeNullToEmpty(name).equals(""))
				session.setAttribute("verify_code", sRand);
			else {
				session.setAttribute(name, sRand);
			}

			g.dispose();
			ServletOutputStream responseOutputStream = response.getOutputStream();

			ImageIO.write(image, "JPEG", responseOutputStream);

			responseOutputStream.flush();
			responseOutputStream.close();
		}catch (Exception e){
			e.printStackTrace();
		}

	}

	private Color getRandColor(int fc, int bc) {
		Random random = new Random();
		if (fc > 255)
			fc = 255;
		if (bc > 255)
			bc = 255;
		int r = fc + random.nextInt(bc - fc);
		int g = fc + random.nextInt(bc - fc);
		int b = fc + random.nextInt(bc - fc);
		return new Color(r, g, b);
	}
	
	public static final String randomInt(int length) {
		if (length < 1) {
			return null;
		}
		Random randGen = new Random();
//		char[] numbersAndLetters = "0123456789abcdefghijklmnopqrstuvwxyz".toCharArray();
		char[] numbersAndLetters = "0123456789".toCharArray();
		char[] randBuffer = new char[length];
		for (int i = 0; i < randBuffer.length; i++) {
//			randBuffer[i] = numbersAndLetters[randGen.nextInt(36)];
			randBuffer[i] = numbersAndLetters[randGen.nextInt(10)];
		}
		return new String(randBuffer);
	}
	

	
	@RequestMapping("/toNoAuthority")
	public String toNoAuthority(ModelMap modelMap) {
		
		return "/noAuthority";
	}


}
