package com.artfess.integrate.consts;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.xxpt.gateway.shared.api.request.OapiGettokenJsonRequest;
import com.alibaba.xxpt.gateway.shared.api.request.OapiRpcOauth2DingtalkAppUserJsonRequest;
import com.alibaba.xxpt.gateway.shared.api.response.OapiGettokenJsonResponse;
import com.alibaba.xxpt.gateway.shared.api.response.OapiRpcOauth2DingtalkAppUserJsonResponse;
import com.alibaba.xxpt.gateway.shared.client.http.ExecutableClient;
import com.alibaba.xxpt.gateway.shared.client.http.IntelligentGetClient;
import com.alibaba.xxpt.gateway.shared.client.http.IntelligentPostClient;
import com.artfess.base.conf.YkzDingConfig;
import com.artfess.base.util.JsonUtil;
import com.artfess.base.util.StringUtil;
import com.artfess.integrate.model.YkbTokenModel;
import com.artfess.integrate.model.YkbUser;

import com.dcqc.uc.oauth.sdk.util.JwtHelper;
import com.dcqc.uc.oauth.sdk.util.SM2ToolUtil;
import com.fasterxml.jackson.databind.JsonNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 阿里钉钉常量
 *
 * @author pangquan
 */
@Component
public class YyzDingConsts {

    protected static Logger log = LoggerFactory.getLogger(YyzDingConsts.class);

    @Autowired
    @Lazy
    private   ExecutableClient executableClient;

    @Autowired
    private  YkzDingConfig ykzDingConfig;


    private  YkbTokenModel model = new YkbTokenModel();

   @Autowired
    private JwtHelper jwtHelper;

    /**
     * 根据临时编码获取愉快政登录用户的信息
     *
     * @return
     */
    public  String getUserInfoByAuthCode(String authCode) throws IOException {
        String agentToken = this.getAgentToken();
        IntelligentPostClient intelligentPostClient  = executableClient.newIntelligentPostClient("/rpc/oauth2/dingtalk_app_user.json");

        OapiRpcOauth2DingtalkAppUserJsonRequest oapiRpcOauth2DingtalkAppUserJsonRequest = new OapiRpcOauth2DingtalkAppUserJsonRequest();
        //登录access_token
        oapiRpcOauth2DingtalkAppUserJsonRequest.setAccess_token(agentToken);
        //临时授权码
        oapiRpcOauth2DingtalkAppUserJsonRequest.setAuth_code(authCode);
        //获取结果
        OapiRpcOauth2DingtalkAppUserJsonResponse apiResult  = intelligentPostClient.post(oapiRpcOauth2DingtalkAppUserJsonRequest);

        if(apiResult.getSuccess()){
            JsonNode jsonNode =JsonUtil.toJsonNode(apiResult.getContent());
            JsonNode content =jsonNode.get("content");
            if(content.get("success").asText().equals("true")){
                JsonNode userJson = content.get("data");
                String user = userJson.toString();
                return user;
            }else{
                String msg = content.get("responseMessage").asText();
                String msgCode = content.get("responseCode").asText();
                Map<String,Object> msgMap = new HashMap<>();
                msgMap.put("message",msg);
                msgMap.put("code",msgCode);
                log.error("获取愉快政用户错误："+msg);
                JsonNode j = JsonUtil.toJsonNode(msgMap);
                return  j.toString();
            }
        }else{
            String msg = apiResult.getMessage();
            String eizErrorCode = apiResult.getBizErrorCode();
            Map<String,Object> msgMap = new HashMap<>();
            msgMap.put("message",msg);
            msgMap.put("code",eizErrorCode);
            log.error("获取愉快政用户错误："+msg);
            JsonNode j = JsonUtil.toJsonNode(msgMap);
            return  j.toString();
        }
    }

    public  synchronized String getAgentToken() throws IOException {
        //没有初始化直接获取。
        if (!model.isAgentInit()) {
            String agentToken = requestAgentToken();
            return agentToken;
        } else {
            //如果token要过期则重新获取。
            if (model.isExpire(model.getAgentTokenlastUpdTime(), model.getExprieIn())) {
                String agentToken = requestAgentToken();
                return agentToken;
            } else {
                //从缓存中获取。
                return model.getAgentToken();
            }
        }
    }


    /**
     * https请求钉钉api获取token。
     *
     * @return
     */
    public  String requestAgentToken() throws IOException {
        executableClient.init();
        IntelligentGetClient intelligentGetClient = executableClient.newIntelligentGetClient("/gettoken.json");
        OapiGettokenJsonRequest oapiGettokenJsonRequest = new OapiGettokenJsonRequest();
        //应用的唯一标识key
        oapiGettokenJsonRequest.setAppkey(ykzDingConfig.getWebAppKey());
        //应用的密钥
        oapiGettokenJsonRequest.setAppsecret(ykzDingConfig.getWebAppSecret());
        //获取结果
        OapiGettokenJsonResponse apiResult = intelligentGetClient.get(oapiGettokenJsonRequest);
        if(apiResult.getSuccess()){
            String result = apiResult.getContent().getData();
            if(StringUtil.isNotEmpty(result)) {
                JsonNode jsonNode = JsonUtil.toJsonNode(result);
                String token = jsonNode.get("accessToken").asText();
                int expiresIn = jsonNode.get("expiresIn").asInt();
                model.setAgentToken(token, expiresIn);
                return token;
            }else{
                model.setAgentInit(false);
                // String errMsg = jsonObj.get("errmsg").asText();
                log.error("获取应用token为空！");
                throw new RuntimeException("获取应用token为空!");

            }

        }else{
            String errMsg = apiResult.getMessage();
            throw new RuntimeException("获取accessToken失败:<br>" + errMsg);
        }

    }


    public  synchronized String getAccessToken() {
        //没有初始化直接获取。
        if (!model.isInit()) {
            String accessToken = requestAccessToken();
            return accessToken;
        } else {
            //如果token要过期则重新获取。
            if (model.isExpire(model.getLastUpdTime(), model.getExprieIn())) {
                String accessToken = requestAccessToken();
                return accessToken;
            } else {
                //从缓存中获取。
                return model.getToken();
            }
        }
    }

    /**
     * 请求愉快政统一用户的token。
     *
     * @return
     */
    public String requestAccessToken() {
        String appId = ykzDingConfig.getUcAppId();
        String appSecret = ykzDingConfig.getUcAppSecret();
        String appSecretEncode = SM2ToolUtil.sm2Encode(jwtHelper.getPublicKey(), appSecret);
        JSONObject jsonObject = new JSONObject()
                                   .fluentPut("data", new JSONObject()
                                                         .fluentPut("appId", appId)
                                                         .fluentPut("appSecret", appSecretEncode))
                                   .fluentPut("requestId", StrUtil.uuid());

        String resp = HttpUtil.post("https://uc-openplatform.bigdatacq.com:4403/ykz/access_token", jsonObject.toJSONString());
        log.info("请求统一用户Token，请求地址：https://uc-openplatform.bigdatacq.com:4403/ykz/access_token");
        log.info("请求统一用户Token，输入参数："+jsonObject.toJSONString());
        log.info("请求统一用户Token，返回数据："+resp);
        if(StringUtil.isNotEmpty(resp)){
            JSONObject jsonResp =JSONObject.parseObject(resp);
            if(jsonResp.getBoolean("success")){
                String accessToken = jsonResp.getJSONObject("data").getString("accessToken");
                Integer expiresIn = jsonResp.getJSONObject("data").getInteger("expiresIn");
                model.setCorpToken(accessToken, expiresIn);
                return  accessToken;
            }else{
                model.setInit(false);
                String errMsg = jsonResp.get("message").toString();
                log.error("获取accessToken失败:<br>" + errMsg);
                throw new RuntimeException("获取accessToken失败:<br>" + errMsg);
            }
        }else{
            log.error("获取accessToken失败:返回数据为空！");
            throw new RuntimeException("获取accessToken失败:返回数据为空！" );

        }
    }

    /**
     * 根据用户手机请求愉快政统一用户信息。
     * @param mobiles 手机集合
     * @return
     */
    public List<YkbUser> getUserByMobiles(List<String> mobiles) {
        String token = getAccessToken();
        JSONObject jsonObject = new JSONObject()
                .fluentPut("data", new JSONObject().fluentPut("mobiles", mobiles))
                .fluentPut("requestId", StrUtil.uuid());
        String resp = HttpRequest.post("https://uc-openplatform.bigdatacq.com:4403/ykz/user/listByMobiles")
                                 .header("Authorization","Bearer "+token)
                                 .timeout(-1).body(jsonObject.toJSONString()).execute().body();
        log.info("根据用户手机请求愉快政统一用户信息，请求地址：https://uc-openplatform.bigdatacq.com:4403/ykz/user/listByMobiles");
        log.info("根据用户手机请求愉快政统一用户信息，输入参数："+jsonObject.toJSONString());
        log.info("根据用户手机请求愉快政统一用户信息，输入header参数：Authorization：Bearer "+token);
        log.info("根据用户手机请求愉快政统一用户信息，返回数据："+resp);
        if(StringUtil.isNotEmpty(resp)){
            JSONObject jsonResp =JSONObject.parseObject(resp);
            if(jsonResp.getBoolean("success")){
                JSONArray dataList = jsonResp.getJSONArray("data");
                List<YkbUser> list = dataList.toJavaList(YkbUser.class);
                return  list;
            }else{
                model.setInit(false);
                String errMsg = jsonResp.get("message").toString();
                log.error("根据用户手机请求愉快政统一用户信息失败:<br>" + errMsg);
                throw new RuntimeException("根据用户手机请求愉快政统一用户信息失败:<br>" + errMsg);
            }
        }else{
            log.error("根据用户手机请求愉快政统一用户信息失败:返回数据为空！");
            throw new RuntimeException("根据用户手机请求愉快政统一用户信息失败:返回数据为空！" );
        }
    }

}
