package com.qy.worksheetsystem.service.impl;


import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.qy.worksheetsystem.config.WeiXinUrlConfig;
import com.qy.worksheetsystem.model.mapper.EmployeeReportingMapper;
import com.qy.worksheetsystem.util.ExpiryMap;
import com.qy.worksheetsystem.util.JWTUtil;
import com.qy.worksheetsystem.util.ZcWeChatExUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;


import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;

/**
 * 企业微信
 * description: WeiXinAuthorizeService <br>
 * date: 2022/3/7 15:24 <br>
 * author: lhbj <br>
 * version: 1.0 <br>
 */
@Slf4j
@Service
public class WeiXinAuthorizeServiceImpl {

    private static final ExpiryMap<String, Object> expiryMap = new ExpiryMap<String, Object>();
    @Resource
    private EmployeeReportingMapper mapper;
    @Resource
    private EmployeeReportingServiceImpl service;
    /**
     * 报工小程序
     */
    @Value("${weixin.corpid}")
    private String corpid;
    /**
     * 报工小程序
     */
    @Value("${weixin.corpsecret}")
    private String corpsecret;
    /**
     * 审批快手
     */
    @Value("${weixin.ks.corpid}")
    private String ks_corpid;
    /**
     * 审批快手
     */
    @Value("${weixin.ks.corpsecret}")
    private String ks_corpsecret;
    @Value("${weixin.ks.AgentId}")
    private String ks_AgentId;
    @Value("${weixin.AgentId}")
    private String AgentId;

    public String getKs_corpid() {
        return ks_corpid;
    }

    public String getKs_corpsecret() {
        return ks_corpsecret;
    }

    public String getKs_AgentId() {
        return ks_AgentId;
    }


    /**
     * 构造网页授权链接
     *
     * @param redirect_uri
     * @param state
     * @return
     */
    public String authorize(String redirect_uri, String state) {
        try {
            redirect_uri = URLEncoder.encode(redirect_uri, "UTF-8");
            StringBuilder url = new StringBuilder(WeiXinUrlConfig.authorize_URL);
            url.append("&redirect_uri=" + redirect_uri);
            url.append("&appid=" + corpid);
            url.append("&state=" + state);
            url.append("#wechat_redirect");
            return url.toString();
        } catch (UnsupportedEncodingException e) {
            log.error(e.getMessage() + "redirect_uri编码异常：" + redirect_uri);
        }
        return "";
    }

    public synchronized String getAccessToken() {
        if (null != expiryMap.get("Token")) {
            return (String) expiryMap.get("Token");
        } else {
            try {
                String accessTokenResult = this.getToken();
                Map<String, Object> tokenMap = (Map) JSONUtil.parse(accessTokenResult);
                String errcode = tokenMap.get("errcode").toString();
                String access_token = tokenMap.get("access_token").toString();
                log.info(WeiXinAuthorizeServiceImpl.class.toString()+ "getAccessToken：" + access_token);
                expiryMap.put("Token", access_token, 7200 * 1000);
                log.info(WeiXinAuthorizeServiceImpl.class.toString()+ "expiryMap：" + expiryMap.toString());
                return (String) expiryMap.get("Token");
            } catch (Exception e) {
                log.error(e.getMessage());
            }
        }
        return "";
    }
    public synchronized String getAccessToken(String agentId,String corpid,String corpsecret) {
        if (null != expiryMap.get(agentId)) {
            return (String) expiryMap.get(agentId);
        } else {
            try {
                String accessTokenResult = this.getToken(corpid, corpsecret);
                Map<String, Object> tokenMap = (Map) JSONUtil.parse(accessTokenResult);
                String errcode = tokenMap.get("errcode").toString();
                String access_token = tokenMap.get("access_token").toString();
                log.info(WeiXinAuthorizeServiceImpl.class.toString()+ "getAccessToken：" + access_token);
                expiryMap.put(agentId, access_token, 7200 * 1000);
                log.info(WeiXinAuthorizeServiceImpl.class.toString()+ "expiryMap：" + expiryMap.toString());
                return (String) expiryMap.get(agentId);
            } catch (Exception e) {
                log.error(e.getMessage());
            }
        }
        return "";
    }

    public String sendMessage(String accessToken,Map<String,Object> map) throws Exception {
        return ZcWeChatExUtil.getInstance().sendMessage(accessToken,map);
    }

    public String sendKSMessage(Map<String,Object> map) throws Exception {
        String accessToken = this.getAccessToken(ks_AgentId,ks_corpid,ks_corpsecret);
        map.put("agentid",ks_AgentId);
        return ZcWeChatExUtil.getInstance().sendMessage(accessToken,map);
    }
    /**
     * 获取access_token
     *
     * @return {
     * "errcode": 0,
     * "errmsg": "ok",
     * "access_token": "accesstoken000001",
     * "expires_in": 7200
     * }
     */
    public String getToken() {
        StringBuilder url = new StringBuilder(WeiXinUrlConfig.gettoken_URL);
        url.append("?corpid=" + corpid);
        url.append("&corpsecret=" + corpsecret);
        log.info(url.toString());
        String result = HttpUtil.get(url.toString());
        log.info(WeiXinAuthorizeServiceImpl.class.toString()+ "getToken：" + result);
        return result;
    }
    /**
     * 获取access_token
     *
     * @return {
     * "errcode": 0,
     * "errmsg": "ok",
     * "access_token": "accesstoken000001",
     * "expires_in": 7200
     * }
     */
    public String getToken(String corpid,String corpsecret) {
        StringBuilder url = new StringBuilder(WeiXinUrlConfig.gettoken_URL);
        url.append("?corpid=" + corpid);
        url.append("&corpsecret=" + corpsecret);
        log.info(url.toString());
        String result = HttpUtil.get(url.toString());
        log.info(WeiXinAuthorizeServiceImpl.class.toString()+ "getToken：" + result);
        return result;
    }
    /**
     * 获取访问用户身份
     * {
     * "errcode": 0,
     * "errmsg": "ok",
     * "UserId":"USERID",
     * "DeviceId":"DEVICEID"
     * }
     * {
     * "errcode": 0,
     * "errmsg": "ok",
     * "OpenId":"OPENID",
     * "DeviceId":"DEVICEID",
     * "external_userid":"EXTERNAL_USERID"
     * }
     *
     * @param access_token
     * @param code
     * @return
     */
    public String getUserInfo(String access_token, String code) {
        StringBuilder url = new StringBuilder(WeiXinUrlConfig.getuserinfo_URL);
        url.append("?access_token=" + access_token);
        url.append("&code=" + code);
        String result = HttpUtil.get(url.toString());
        return result;
    }

    /**
     * openid转换成userid接口
     *
     * @param openid
     * @return {
     * "errcode": 0,
     * "errmsg": "ok",
     * "userid": "zhangsan"
     * }
     */
    public String convertToUserid(String access_token, String openid) {
        StringBuilder url = new StringBuilder(WeiXinUrlConfig.convert_to_userid_URL);
        url.append("?access_token=" + access_token);
        Map<String, Object> map = new HashMap<>();
        map.put("openid", openid);
        String result = HttpUtil.post(url.toString(), map);
        return result;
    }

    public Map<String, Object> getPersonInfo(String code) {
        Map<String, Object> resultMap = new HashMap<>();
        try {

            String access_token = this.getAccessToken();
            log.info(WeiXinAuthorizeServiceImpl.class.toString()+ "access_token：" + access_token);
            String UserResult = this.getUserInfo(access_token, code);
            log.info(WeiXinAuthorizeServiceImpl.class.toString() + "_UserResult:" + UserResult);
            Map<String, Object> userMap = (Map) JSONUtil.parse(UserResult);
            String userErrcode = userMap.get("errcode").toString();
            if (!userErrcode.equals("0")) {
                throw new Exception("getUserInfo:" + UserResult);
            }
            Object UserId = userMap.get("UserId");
            Object OpenId = userMap.get("OpenId");
            if (null == UserId && null != OpenId) {
                String OpenIdResult = this.convertToUserid(access_token, OpenId.toString());
                Map<String, Object> OpenIdMap = (Map) JSONUtil.parse(OpenIdResult);
                String OpenIdErrcode = OpenIdMap.get("errcode").toString();
                if (!OpenIdErrcode.equals("0")) {
                    throw new Exception("convertToUserid:" + OpenIdResult);
                }
                UserId = OpenIdMap.get("userid").toString();
            }
            log.info(WeiXinAuthorizeServiceImpl.class.toString() + "UserId:" + UserId);
            if (null != UserId) {
                resultMap.put("userid", UserId);
                String userDetail = this.getUserDetails(access_token, UserId.toString());
                log.info(WeiXinAuthorizeServiceImpl.class.toString() + "userDetail:" + userDetail);
                Map<String, Object> userDetailMap = (Map) JSONUtil.parse(userDetail);
                String userName = (String) userDetailMap.get("name");
                resultMap.put("name", userName);
                Map<String, Object> extattr = (Map<String, Object>) userDetailMap.get("extattr");
                List<Map<String, Object>> attrs = (List<Map<String, Object>>) extattr.get("attrs");
                if (null == extattr || null == attrs || extattr.isEmpty() || attrs.isEmpty()) {
                    resultMap.put("number", "");
                }
                for (Map<String, Object> attr : attrs) {
                    String attrName = (String) attr.get("name");
                    String attrValue = (String) attr.get("value");
                    if (attrName.equals("工号")) {
                        resultMap.put("number", attrValue);
                        Map<String, Object> person = service.getShrPersonInfo(attrValue);
                       // resultMap.putAll(person);
                        resultMap.put("hiredate",person.get("hiredate"));
                        resultMap.put("isAuditor",person.get("isAuditor"));
                    }
                }
                String token = JWTUtil.createToken((String) resultMap.get("number"),UserId.toString());
                resultMap.put("token", token);
                Calendar c = Calendar.getInstance();
                c.add(Calendar.DAY_OF_MONTH,1);
                resultMap.put("expire", c.getTimeInMillis());
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
        }
        return resultMap;
    }



    /**
     * 读取成员
     *
     * @param access_token
     * @param userid
     * @return
     */
    public String getUserDetails(String access_token, String userid) {
        StringBuilder url = new StringBuilder(WeiXinUrlConfig.userGet_URL);
        url.append("?access_token=" + access_token);
        url.append("&userid=" + userid);
        String result = HttpUtil.get(url.toString());
        return result;
    }
}
