package com.nbclass.system.controller;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLEncoder;

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

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.alibaba.fastjson.JSONObject;
import com.nbclass.shiro.config.MyUsernamePasswordToken;
import com.nbclass.system.model.User;
import com.nbclass.system.service.UserService;
import com.nbclass.util.CommonUtils;
import com.nbclass.util.HttpUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * 企业微信扫码登录
 * @author Leon
 * @datetime 2020年6月2日 下午4:18:04
 */
@Slf4j
@Controller
@RequestMapping("/qywx")
public class QyWxLoginController {
	
	private static final int AgentId = 1000016; // 企业微信登录应用ID(信广龙广告)
	
	@Autowired
    private UserService userService;

	/**
	 * PC端网页授权(企业微信授权登录)
	 * @param code
	 * @param request
	 * @param response
	 * @throws IOException
	 */
	@RequestMapping("/qrLogin")
	public void qrLogin(String code, HttpServletRequest request, HttpServletResponse response) throws IOException{
		response.setHeader("Cache-Control", "no-store");
        String httpRequestFullURL =  URLEncoder.encode(getBaseUrl(request)+"/qywx/qrLogin", "UTF-8");
        String redirectUrl = "http://show.szxgl.cn/qywx/api/sso/login?agentid="+AgentId+"&redirect_uri=" + httpRequestFullURL;
        if(StringUtils.isBlank(code)){
        	response.sendRedirect(redirectUrl);
        	return;
        }
        
		String url = "http://show.szxgl.cn/qywx/api/sso/getUserInfo?agentid="+AgentId+"&code="+code;
		try {
			JSONObject json = HttpUtils.httpPost(url);
			if(json == null || json.getIntValue("errcode") == 40029 || json.getIntValue("errcode") == 40163){
                log.info("企业微信授权失败，将重新跳转授权......");
                redirectUrl = CommonUtils.removeParamValue(redirectUrl, "code");
				response.sendRedirect(redirectUrl);
				return;
			}
			log.info("企业微信扫码登录, 用户信息: "+json);
			String userid = json.getString("userid");
			if(StringUtils.isBlank(userid)){
				outPrintError(response, "该账号未经授权，请联系管理员授权后再试！");
				return;
			}
			
			// 企业微信登录成功，下一步进行系统shiro身份验证
			String username = userid;
	    	MyUsernamePasswordToken token = new MyUsernamePasswordToken(username); // 免密登录,用于扫码登录手机验证码登录等场景
	        try{
	            Subject subject = SecurityUtils.getSubject();
	            subject.login(token);
	        } catch (LockedAccountException e) {
	            token.clear();
	            outPrintError(response, "用户已经被锁定不能登录，请联系管理员！");
	            return;
	        } catch (AuthenticationException e) {
	            token.clear();
	            outPrintError(response, "账号异常，请联系管理员处理！");
	            return;
	        }
	        //更新最后登录时间
	        userService.updateLastLoginTime((User) SecurityUtils.getSubject().getPrincipal());
			
			response.sendRedirect(request.getContextPath()+"/admin");
		} catch (Exception e) {
			log.error("企业微信登录授权失败", e);
            outPrintError(response, "企业微信授权失败，请稍候再试！");
		}
	}
	
    /**
     * 输出错误信息到页面
     * @param response
     * @param result
     */
	public void outPrintError(HttpServletResponse response, String result) {
		response.setCharacterEncoding("UTF-8");
		response.setContentType("text/html; charset=UTF-8");
		PrintWriter out = null;
		try {
			String html = "<!DOCTYPE html><html><head>";
			html += "<title>鉴权错误</title>";
			html += "<meta charset=\"utf-8\">";
			html += "<meta name=\"viewport\" content=\"width=device-width, user-scalable=no, initial-scale=1\">";
			html += "</head><body>";
			html+="<center><div style=\"width:85%; text-align:center; font-size: 18px; line-height:35px; color: red; margin-top: 15px;\">";
			html += result;
			html+="</div></center></body></html>";
			out = response.getWriter();
			out.print(html);
		} catch (IOException e) {
			throw new RuntimeException("IO工作流出现异常!");
		} finally {
			if(out!=null){
				out.close();
				out = null;
			}
		}
    }
	
	private static String getBaseUrl(HttpServletRequest request){
		String result = null;
		int port = request.getServerPort();
		result = request.getScheme()+"://"+request.getServerName()+(port==80||port==443 ? "" : ":"+port)+request.getContextPath()+"/";
		return result;
	}
	
}
