package com.xxfc.platform.summit.service;



import com.xxfc.platform.summit.model.AccessToken;
import com.alibaba.fastjson.JSONObject;
import com.xxfc.platform.summit.util.HttpRequestUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;


/**
 * 认证并获取 access_token API
 * http://mp.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96access_token
 * 
 * AccessToken默认存储于内存中，可设置存储于redis或者实现IAccessTokenCache到数据库中实现分布式可用
 * 
 * 具体配置：
 * <pre>
 * ApiConfigKit.setAccessTokenCache(new RedisAccessTokenCache());
 * </pre>
 */
@Service
@Slf4j
public class AccessTokenService {
	
	 @Autowired
	 private RedisTemplate summbitRedisTemplate;
	// "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
	private static String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential";
		//"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential";

	@Value("${wx.appid}")
	private String wy_appid;
	@Value("${wx.appSercet}")
	private String  wy_secret;
	

	/**
	 * 从缓存中获取 access token，如果未取到或者 access token 不可用则先更新再获取
	 */
	public  AccessToken getAccessToken() {
		//从缓存中读取出accessToken
		//RedisUtil redisUtil = new RedisUtil(ConstantConfig.REDIS_IP,ConstantConfig.REDIS_PORT);
		//创建一个jedis的对象。
		String accessTokenRedis = summbitRedisTemplate.opsForValue().get(wy_appid) == null ? "" : summbitRedisTemplate.opsForValue().get(wy_appid).toString();
		log.info("---accessTokenRedis===="+accessTokenRedis);
		if (StringUtils.isNotBlank(accessTokenRedis))
		{
			JSONObject  obj = JSONObject.parseObject(accessTokenRedis).getJSONObject(wy_appid);
			AccessToken accessToken = new AccessToken(obj.getString("json"),obj.getString("accessToken"),obj.getInteger("expiresIn"),obj.getLong("expiredTime"));
			if(accessToken.isAvailable()){
				return accessToken;
			}
			summbitRedisTemplate.delete(wy_appid);
		}

		refreshAccessToken();
		accessTokenRedis = summbitRedisTemplate.opsForValue().get(wy_appid) == null ? "" : summbitRedisTemplate.opsForValue().get(wy_appid).toString();
		JSONObject  obj = JSONObject.parseObject(accessTokenRedis).getJSONObject(wy_appid);
		AccessToken accessToken = new AccessToken(obj.getString("json"),obj.getString("accessToken"),obj.getInteger("expiresIn"),obj.getLong("expiredTime"));
		return accessToken;
		//return (AccessToken) ehcache.get(SystemConfig.WINXIN_AppID).getObjectValue();
	}
	
	private  AccessToken AccessToken(String string, String string2,
			Integer integer) {
		// TODO Auto-generated method stub
		return null;
	}

	/**
	 * 直接获取 accessToken 字符串，方便使用
	 * @return String accessToken
	 */
	public  String getAccessTokenStr() {
		return getAccessToken().getAccessToken();
	}
	
	/**
	 * 强制更新 access token 值
	 */
	public  void refreshAccessToken() {
		//RedisUtil redisUtil = new RedisUtil(ConstantConfig.REDIS_IP,ConstantConfig.REDIS_PORT);
		AccessToken result = null;
		for (int i=0; i<3; i++) {	// 最多三次请求
			String json =  HttpRequestUtil.httpGet(url+"&appid="+wy_appid+"&secret="+wy_secret);
			log.info("---json===="+json);
			result = new AccessToken(json);
			if (result.isAvailable())
				break;
		}
		// 三次请求如果仍然返回了不可用的 access token 仍然 put 进去，便于上层通过 AccessToken 中的属性判断底层的情况
		JSONObject obj = new JSONObject();
		obj.put(wy_appid, result);
		Boolean suc=summbitRedisTemplate.opsForValue().setIfAbsent(wy_appid,  obj.toJSONString());
		if (suc) {
			summbitRedisTemplate.expire(wy_appid, result.getExpiresIn(), TimeUnit.MINUTES);
		}
	}
}