package com.dgtly.wxportal.utils.qywxutils;

import com.alibaba.fastjson.JSONObject;
import com.dgtly.common.exception.BusinessException;
import com.dgtly.common.utils.StringUtils;
import com.dgtly.wxportal.exception.QyWeixinException;
import com.dgtly.common.utils.http.HttpUtils;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.Date;

/**
 * 企业微信 accessToken相关
 */
@Component
public class QyWxAccessTokenUtil {

    private static final Logger log = LoggerFactory.getLogger(QyWxAccessTokenUtil.class);

    private String accessToken;
    /**
     * 创建时间
     */
    private long createTime;

    /**
     * 过期时间
     */
    private long expires;

    private String jsapiTicket;

    private long jsapiCreateTime;

    private long jsapiExpires;

    private String jsapiAgentTicket;

    private long jsapiAgentCreateTime;

    private long jsapiAgentExpires;

    @Value(value = "${qiyeweixin.corpid:none}")
    private String corpid;



    @Value(value = "${qiyeweixin.corpsecret:none}")
    private String corpsecret;

    @Value(value = "${qiyeweixin.agentId:none}")
    private String agentId;



    /**
     * 获取access_token
     * @return
     */
    public String getAccessToken() {
        JSONObject json;
        String url;

        try {
            //token未过期使用缓存的token
            long currentTiem = new Date().getTime();
            if(this.accessToken!=null &&(currentTiem-createTime)<(expires*1000)){
                log.info("本身的token为{}",this.accessToken);
                return this.accessToken;
            }
            //获取请求地址
            url = QyWxServiceUrl.ACCESS_TOKEN_URL.getformatUrl(corpid, corpsecret);
            json = JSONObject.parseObject(HttpUtils.sendGet(url));
        }catch (Exception e){
            this.accessToken=null;
            log.error("获取企业微信accesstoken错误",e);
            throw e;
        }
        Integer errcode = json.getInteger("errcode");
        if(errcode!=0){
            this.accessToken=null;
            throw new QyWeixinException(errcode,url);
        }
        String token = json.getString("access_token");
        long expires = json.getLong("expires_in");
        this.createTime = new Date().getTime();
        this.accessToken = token;
        this.expires = expires;
        log.info("请求获得的token为{}",token);
        return token;
    }

    public String getWXSign(String url, String agent) {
        long timeStampSec = System.currentTimeMillis() / 1000;
        String timestamp = String.format("%010d", timeStampSec);
        String nonceStr = RandomStringUtils.randomAlphanumeric(8);
        String[] urls = url.split("#");
        String newUrl = urls[0];
        JSONObject respJson = new JSONObject();
        String ticket;
        if("1".equals(agent)){
            ticket = getWXJsapiTicketAgent();
        }else{
            ticket = getWXJsapiTicket();
        }

        String[] signArr = new String[]{"url=" + newUrl, "jsapi_ticket=" + ticket, "noncestr=" + nonceStr, "timestamp=" + timestamp};
        Arrays.sort(signArr);
        String signStr = StringUtils.join(signArr, "&");
        String resSign = DigestUtils.sha1Hex(signStr);
        respJson.put("appId", this.corpid);
        respJson.put("timestamp", timestamp);
        respJson.put("nonceStr", nonceStr);
        respJson.put("signature", resSign);
        if ("1".equals(agent)) {
            respJson.put("agentId", this.agentId);
        }

        return respJson.toJSONString();
    }

    private String getWXJsapiTicket() {

        //token未过期使用缓存的token
        long currentTiem = new Date().getTime();
        log.info("jsapiTicket线程id{}", Thread.currentThread().getId());
        log.info("jsapiTicket过期时间为{}", this.jsapiCreateTime + this.jsapiExpires * 1000);
        log.info("jsapiTicket当前时间为{}", currentTiem);
        if (this.jsapiTicket != null && (currentTiem - jsapiCreateTime) < (this.jsapiExpires - 10) * 1000) {
            log.info("jsapiTicket{}", this.jsapiTicket);
            return this.jsapiTicket;
        }


        String url = QyWxServiceUrl.JSAPI_TICKET_URL.getformatUrl(getAccessToken());
        log.info("getWXJsapiTicket url ", url);
        String resp = HttpUtils.sendSSLGet(url);
        log.info("getWXJsapiTicket resp ", resp);
        JSONObject resJson = JSONObject.parseObject(resp);
        jsapiCreateTime = new Date().getTime();
        jsapiExpires = resJson.getInteger("expires_in");
        jsapiTicket = resJson.getString("ticket");
        return jsapiTicket;

    }

    private String getWXJsapiTicketAgent() {

        //token未过期使用缓存的token
        long currentTiem = new Date().getTime();
        log.info("agentTicket线程id{}", Thread.currentThread().getId());
        log.info("agentTicket过期时间为{}", this.jsapiAgentTicket + this.jsapiAgentExpires * 1000);
        log.info("agentTicket当前时间为{}", currentTiem);
        if (this.jsapiAgentTicket != null && (currentTiem - jsapiAgentCreateTime) < (this.jsapiAgentExpires - 10) * 1000) {
            log.info("agentTicket{}", this.jsapiAgentTicket);
            return this.jsapiAgentTicket;
        }


        String url = QyWxServiceUrl.JSAPI_TICKET_AGENT_URL.getformatUrl(getAccessToken());
        log.info("getAgentTicket url ", url);
        String resp = HttpUtils.sendSSLGet(url);
        log.info("getAgentTicket resp ", resp);
        JSONObject resJson = JSONObject.parseObject(resp);
        jsapiAgentCreateTime = new Date().getTime();
        jsapiAgentExpires = resJson.getInteger("expires_in");
        jsapiAgentTicket = resJson.getString("ticket");
        return jsapiAgentTicket;
    }

    public String getCorpid() {
        return corpid;
    }


    public String getCorpsecret() {
        return corpsecret;
    }

    public String getAgentId() {
        return agentId;
    }

    public void setAgentId(String agentId) {
        this.agentId = agentId;
    }

}
