package com.boco.nbd.wios.wx.utils;

import com.boco.nbd.wios.wx.call.WeChatApi;
import com.ihidea.component.cache.redis.RedisClient;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;

/**
 * 微信小程序工具类
 *
 * @author Administrator
 *
 */
public class WeChatSessionKeyUtils {
	private final static Logger logger = LoggerFactory.getLogger(WeChatSessionKeyUtils.class);

	/**
	 * 小程序session_key
	 */
	private final static String xcx_session_key = "wxapp:session_key:";

	private final static String xcx_union_id = "wxapp:unionid:";

	private final static String xcx_access_token = "cams:xcx:access:token";

	/**
	 * 根据code获取openId及session_key
	 *
	 * @param code
	 * @return
	 */
	public static String getOpenIdForWxInstant(String code) {
		// 获取openId及sessionkey
		Map<String, String> jsonObject = WeChatApi.getXcxOpenIdOrSessionKey(code);

		// 获取openId
		String openid = jsonObject.get("openid");
		// 将session_key存放值redis
		setXcxSessionKey(openid, jsonObject.get("session_key"));
		if (StringUtils.isNotBlank(jsonObject.get("unionid"))) {
			setXcxUnionId(openid, jsonObject.get("unionid"));
		}
		return openid;
	}

	/**
	 * 解密用户信息
	 *
	 * @param encryptedData 用户信息,加密数据
	 * @param iv 加密算法的初始向量
	 * @param code 用户允许登录后,回调内容会带上
	 *            code(有效期五分钟),开发者需要将 code 发送到开发者服务器后台,使用code 换取 session_key
	 *            api,将 code 换成 openid 和session_key
	 * @param openId
	 * @return
	 * @author lvpeng
	 * @date 2017年11月6日
	 */
	public static Map<String, Object> decodeUserInfo(String encryptedData, String iv, String code, String openId) {

		String session_key = "";
		// 如果openId存在直接获取sessionKey
		// 如果不存在则根据code获取sessKey
		// 以上处理兼容老版本
		if (StringUtils.isNotBlank(openId)) {
			session_key = getXcxSessionKey(openId);
		}
		logger.error("sessionKey:{},openId:{},encryptedData:{},iv:{}",
				new String[] { session_key, openId, encryptedData, iv });
		try {
			Map<String, Object> map = WeChatDecryptUtils.decode(session_key, encryptedData, iv);
			return map;
		} catch (Exception e) {
			// TODO: handle exception

			logger.error("解密失败!");
		}
		return null;
	}

	/**
	 * 缓存sesskey
	 *
	 * @param openId
	 * @param sessionKey
	 */
	public static void setXcxSessionKey(String openId, String sessionKey) {
		RedisClient.put(xcx_session_key + openId, sessionKey);
	}

	/**
	 * 缓存sesskey
	 *
	 * @param openId
	 */
	public static String getXcxSessionKey(String openId) {
		return RedisClient.get(xcx_session_key + openId, String.class);
	}

	/**
	 * 缓存unionId
	 *
	 * @param openId
	 */
	public static void setXcxUnionId(String openId, String unionId) {
		RedisClient.put(xcx_union_id + openId, unionId);
	}

	/**
	 * 获取unionId
	 *
	 * @param openId
	 * @return
	 * @author lvpeng
	 * @date 2018年3月12日
	 */
	public static String getXcxUnionId(String openId) {
		return RedisClient.get(xcx_union_id + openId, String.class);
	}

	/**
	 * 获取AccessToken
	 * @return
	 */
	public static String getXcxAccessToken() {
		String accessToken = RedisClient.get(xcx_access_token, String.class);
		if(StringUtils.isNotBlank(accessToken)){
			return accessToken;
		}else{
			Map<String, Object> jsonObject = WeChatApi.getXCXAccessToken();
			if(jsonObject!=null && jsonObject.get("access_token")!=null && jsonObject.get("expires_in")!=null){
				// 获取openId
				accessToken =  jsonObject.get("access_token").toString();
				Integer expiresIn  = Integer.valueOf(jsonObject.get("expires_in").toString());
				RedisClient.put(xcx_access_token, accessToken, expiresIn);
			}
		}
		return accessToken;
	}

	/**
	 * 刷新缓存Token
	 * @return
	 */
	public static void refreshXcxAccessToken() {
		RedisClient.remove(xcx_access_token);
		getXcxAccessToken();
	}
}