package com.iamberry.wechat.core.entity;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Map;

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

import com.iamberry.app.tool.des.MD5;
import com.iamberry.jwt.TokenUtil;
import com.iamberry.jwt.UserNotLoginException;
import com.iamberry.jwt.WebJsonTokenUtil;
import com.iamberry.wechat.core.entity.member.Member;
import com.iamberry.wechat.tools.NameUtils;
import org.springframework.stereotype.Component;

/**
 * description ： 微信端用户工具类
 * @author 何秀刚
 * create date：2016年2月25日
 */
@Component
public class WechatUtils {

	/**
	 * 将用户信息保存到session中，并做安全设置, 注意，如果了安全，将token写入cookie后，应该在后台保存一份token的签名，前台 保存value，后台保存签名
	 * @param object
	 * @param request
	 * @throws Exception
	 */
	public static void saveUserToSession(Member object, HttpServletRequest request, HttpServletResponse response) throws Exception {
		// 判断当前是否存在
		Cookie[] cookies = request.getCookies();
		if (cookies != null) {
			for (Cookie cookie : cookies) {
				if ("WATERO_WEB_PF".equals(cookie.getName())) {
					continue;
				}
				// 如果cookie的name以cookie value的前8位口头，那么是用户token保存方式
				String cookieNmae = cookie.getName();
				String cookieValue = cookie.getValue().substring(0, 8);
				if (!cookieNmae.startsWith(cookieValue)) {
					continue;
				}
				// 无法准确获取key的值，只能遍历，所以系统应该尽量减少cookie,最后只是一个
				Map<String, Object>	userMap = WebJsonTokenUtil.verifier(cookie.getValue(), cookieNmae.substring(8));
				if ((Integer)userMap.get("status") == 2) {
					cookie.setMaxAge(0);
				}
			}
		}
		// 生成原始token
		String token = TokenUtil.getToken();
		// 截取8位作为key
		if (token.length() <= 13) {
			token = "1234567890ABC";
		}
		String secret = token.substring(0, 8);
		String userToken = WebJsonTokenUtil.getToken(object.getUserId(), object.getUserOpenid(), token.substring(8));
		// 保存cookie, 多项验证
		AdminUtils.createCookie(response, token, secret+userToken);
	}

	/**
	 * 1、获取当前用户，注意，前端系统完全弃用session,防止后端服务器宕机，导致用户业务异常终止 <br>
	 * 2、调用此方法，不存在返回为空，所以无需判断，但是此方法在运行时会抛出异常，调用时，不能捕获，让给系统统一处理
	 * @param request
	 * @return
	 * @throws Exception
	 * @author 献
	 * @Time   2016年11月24日
	 */
	public static Member getUserBySession(HttpServletRequest request) {
		//获取一个cookie数组
		Cookie[] cookies = request.getCookies();
		if (cookies == null) {
			throw new UserNotLoginException();
		}

		for (Cookie cookie : cookies) {
			if ("WATERO_WEB_PF".equals(cookie.getName())) {
				continue;
			}
			// 如果cookie的name以cookie value的前8位口头，那么是用户token保存方式
			String cookieNmae = cookie.getName();
			String cookieValue = cookie.getValue().substring(0, 8);
			if (!cookieNmae.startsWith(cookieValue)) {
				continue;
			}
			// 无法准确获取key的值, 只能遍历，所以系统应该尽量减少cookie数量, 最好只是一个
			Map<String, Object>	userMap = WebJsonTokenUtil.verifier(cookie.getValue(), cookieNmae.substring(8));
			if (Integer.parseInt(userMap.get("status").toString()) == 2) {
				Member member = new Member();
				member.setUserId(Integer.parseInt(userMap.get("userid").toString()));
				member.setUserOpenid(userMap.get("WC_OPENID").toString());
				return member;
			}
		}
		// 凡是没有登录的用户，都抛出异常
		throw new UserNotLoginException();
	}

	/**
	 * 微信授权获取openid
	 * @param tokenId
	 * @return
	 */
	public String getOpenIdFunction(String tokenId, boolean flag) {
		String urlTemp;
		if (flag) {
			urlTemp = NameUtils.getConfig("WECHAT_BACK_URL") + "?tokenId=" + tokenId;
		} else {
			urlTemp = tokenId;
		}
		try {
			return "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + NameUtils.getConfig("appId") +
					"&redirect_uri=" +
					URLEncoder.encode(urlTemp, "UTF-8") +
					"&response_type=code&scope=snsapi_base&state=iamberry#wechat_redirect";
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return null;
	}

	public static void main(String[] args) {
		String token = TokenUtil.getToken();;
		System.out.println(token);
		String sec = token.substring(8);
		System.out.println(sec);
	}

	private static MD5 md5 = new MD5("callback");

	public static String setCallback(String callback) throws Exception {
		return md5.encrypt(callback);
	}

	public static String getCallback(String temp) throws Exception {
		return md5.decrypt(temp);
	}

	/**
	 * 跳转链接
	 * @param callback		跳转链接
	 * @return
	 * @author 献
	 * @throws Exception
	 * @Time   2016年11月24日
	 */
	public static String getOpenIdFunction(String callback) throws Exception {
		String redirect_url = NameUtils.getConfig("WECHAT_BACK_URL");

		if (callback != null) {
			redirect_url = redirect_url + "?callback=" + setCallback(callback);
		}

		return "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + NameUtils.getConfig("appId") +
				"&redirect_uri=" +
				URLEncoder.encode(redirect_url, "UTF-8") +
				"&response_type=code&scope=snsapi_base&state=iamberry#wechat_redirect";
	}
}
