package com.zzwtec.wechat.biz;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.zzwtec.wechat.common.oauth.SnsAccessTokenContext;
import com.zzwtec.wechat.config.WeChatConfig;
import com.zzwtec.wechat.rpc.APIResponse;
import com.zzwtec.wechat.rpc.api.APIService;
import com.zzwtec.wechat.rpc.inject.ProxyBuilder;
import com.zzwtec.wechat.sdk.api.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

/**
 * 获取微信用户信息
 *
 * @author 邓燎燕
 *         2016年4月28日
 */
public class WechatBiz {
    private static final APIService apiService = ProxyBuilder.build(APIService.class, WeChatConfig.weChatConfig);

    private static final Logger logger = LoggerFactory.getLogger(WechatBiz.class);

   public static SnsAccessToken getUserInfo() {
       SnsAccessToken snsAccessToken = SnsAccessTokenContext.getSnsAccessToken();


       if (snsAccessToken == null || !snsAccessToken.isAvailable() || snsAccessToken.getErrorCode() != null) {
           logger.info("拉取用户信息失败,{}",snsAccessToken == null ? "snsAccessToken为空" : snsAccessToken.getErrorMsg());
           return null;
       }
       if(snsAccessToken.getErrorCode() != null && snsAccessToken.getErrorCode() == 40163){//code已使用
           return snsAccessToken;
       }
       if (StringUtils.isEmpty(snsAccessToken.getOpenid())) {
           logger.error("拉取用户信息失败:{}", snsAccessToken.getErrorMsg());
           return snsAccessToken;
       }
       logger.debug("拉取用户信息:{}", snsAccessToken.getJson());
       updateWechatUserInfo(snsAccessToken.getOpenid(), snsAccessToken.getAccessToken());
       return snsAccessToken;
    }

    /**
     * 获取关注的用户信息
     * @param next_openid
     */
    private static void getWXPublicUser(String next_openid) {
        ApiConfigKit.setThreadLocalAppId(ApiConfigKit.getApiConfig().getAppId());
        ApiResult result = UserApi.getFollowers(next_openid);
        if (result != null) {
            JSONObject resultObj = JSONObject.parseObject(result.getJson());
            if (resultObj.containsKey("data")) {
                int total = resultObj.getIntValue("total");
                int count = resultObj.getIntValue("count");
                String data = resultObj.getString("data");
                JSONObject dataObj = JSONObject.parseObject(data);
                JSONArray openids = dataObj.getJSONArray("openid");
                next_openid = result.getStr("next_openid");
                for (int i = 0; i < openids.size(); i++) {
                    String openId = openids.getString(i);
                    updateWechatUserInfo(openId, null);
                }
                if (10000 < total && count >= 10000) {
                    getWXPublicUser(next_openid);
                } else {
                    return;
                }
            }
        }
    }

    // 如果微信用户信息不存在则保存
    private static void updateWechatUserInfo(String openid, String access_token) {
        // 从本地获取微信用户信息，如果查询失败或用户信息已存在则返回
        APIResponse response = apiService.queryWechatUserInfoByOpenid(openid);
        if (response.isFail()) {
            logger.error("获取微信用户信息失败:{}", response);
            return;
        }
        if (response.getData() != null) {
            return;
        }
        // 从微信查询用户信息，如果查询失败则返回
        ApiResult apiResult = access_token == null ? UserApi.getUserInfo(openid): SnsApi.getUserInfo(access_token, openid);
        if (!apiResult.isSucceed()) {
            return;
        }
        // 保存微信用户信息
        logger.debug("userStr:{}", apiResult.getJson());
        JSONObject userJson = JSONObject.parseObject(apiResult.getJson());
        if (userJson.containsKey("nickname")) {
            addKeyIfNotExist(userJson, "subscribeTime", System.currentTimeMillis());
            addKeyIfNotExist(userJson, "groupid", 0);
            response = apiService.saveWechatUserInfo(userJson);
            if (response.isFail()) {
                logger.error("保存微信用户信息失败:{}", response);
            }
        }
    }

    private static void addKeyIfNotExist(JSONObject json, String key, Object value) {
        if (!json.containsKey(key)) {
            json.put(key, value);
        }
    }
}
