package com.yifu.cloud.plus.v1.yifu.auth.config;

import cn.hutool.core.text.StrBuilder;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CacheConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.SecurityConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.exception.CheckedException;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import com.yifu.cloud.plus.v1.yifu.common.core.util.EncryptUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Author: fxj
 * @Date: 2025-01-07
 * @Description:
 * @return: 企业微信配置
 **/
@Configuration
@Data
@Slf4j
public class WxConfig {
    @Value("${wx.corpid}")
    private String corpid;
    @Value("${wx.corpsecret}")
    private String corpsecret;
    @Value("${wx.agentid}")
    private String agentid;
    @Value("${wx.authUrl}")
    private String authUrl;

    private static Map<String,String> corpsecretMap = new HashMap<>();

    //未授权
    private String accossTokenInvliad = "40014";

    //请求成功
    private String accossTokenSuccess = "0";


    //错误吗
    private String errcode = "errcode";

    @Autowired
    private RedisTemplate redisTemplate;

    static{
        //合同审批（生产）
        corpsecretMap.put("1000010","16kqEL_eU-ARwYyqLgEBWHgxm8gXVnkzv_eJMLy9NpU");
		corpsecretMap.put("1000009","R0nKkvsY-oF41fuQvUXZ-kFG3_g_Ce0bpZt6mByx524");
	}

    /**
     * @param
	 * @Author: fxj
	 * @Date: 2025-01-07
     * @Description: 获取微信accos_token
     * @return: java.lang.String
     **/
    public String getAccessToken(RestTemplate restTemplate) {
        if (Common.isNotNull(agentid)) {
            return this.getToken(restTemplate, CacheConstants.WX_ACCOSS_TOKEN.concat(agentid), corpsecret);
        }
        return this.getToken(restTemplate, CacheConstants.WX_ACCOSS_TOKEN, corpsecret);
    }

    public String getAccessToken(RestTemplate restTemplate,String agentId)throws AuthenticationServiceException {
        if(corpsecretMap.isEmpty()){
            throw  new AuthenticationServiceException("corpsecretMap为空请联系管理员配置");
        }
        String thisCorpsecret = corpsecretMap.get(agentId);
        if(Common.isEmpty(thisCorpsecret)){
            throw new AuthenticationServiceException("未找到对应的corpsecret请联系管理员配置");
        }
        return this.getToken(restTemplate, CacheConstants.WX_ACCOSS_TOKEN.concat(agentId), thisCorpsecret);
    }
    /**
     * @param restTemplate
     * @param tokenKey
     * @param corpsecretKey
     * @Description: 获取token
     * @Author: hgw
     * @Date: 2021/3/24 14:43
     * @return: java.lang.String
     **/
    public String getToken(RestTemplate restTemplate,String tokenKey, String corpsecretKey) {
        Object wxToken = redisTemplate.opsForValue().get(tokenKey);
        if (wxToken != null) {
            return String.valueOf(wxToken);
        }
        String requestTokenUrl = String.format(SecurityConstants.WX_GET_ACCOSS_TOKEN, corpid, corpsecretKey);
        String result = restTemplate.getForObject(requestTokenUrl, String.class);
        if (Common.isEmpty(result)) {
            throw new CheckedException("微信授权失败");
        }
        String token = JSON.parseObject(result).getString("access_token");
        if (Common.isEmpty(token)) {
            log.info(result);
            throw new CheckedException("获取微信token失败");
        }
        redisTemplate.opsForValue().set(tokenKey, token);
        redisTemplate.expire(tokenKey, 3600, TimeUnit.SECONDS);
        return token;
    }

    /**
     * @param
	 * @Author: fxj
	 * @Date: 2025-01-07
     * @Description: 移除微信accossToken
     * @return: java.lang.String
     **/
    public void removeAccessToken() {
        redisTemplate.delete(CacheConstants.WX_ACCOSS_TOKEN);
    }
    /**
     * 移除微信accossToken
	 * @Author: fxj
	 * @Date: 2025-01-07
     * @param agentId
     * @return
     **/
    public void removeAccessToken(String agentId) {
        if(Common.isNotNull(agentId)){
            redisTemplate.delete( CacheConstants.WX_ACCOSS_TOKEN.concat(agentId));
        }else{
            removeAccessToken();
        }
    }

    /**
     * @param
	 * @Author: fxj
	 * @Date: 2025-01-07
     * @Description: 移除微信accossToken
     * @return: java.lang.String
     **/
    public void removeJsapiTicket() {
        redisTemplate.delete(CacheConstants.WX_JSAPI_TICKET);
    }

    /**
     * @param restTemplate
     * @param access_token
     * @param timeMillis   时间戳
     * @param random       随机数
     * @param url          网页url
	 * @Author: fxj
	 * @Date: 2025-01-07
     * @Description: 微信jsapi签名
     * @return: java.lang.String
     **/
    public String getSign(RestTemplate restTemplate, String access_token, long timeMillis, String random, String url) {
        Object wxJsapiTicket = redisTemplate.opsForValue().get(CacheConstants.WX_JSAPI_TICKET);
        log.info("wxJsapiTicket="+JSON.toJSONString(wxJsapiTicket));
        String ticket = null;
        if (wxJsapiTicket != null) {
            log.info("wxJsapiTicket222="+JSON.toJSONString(wxJsapiTicket));
            ticket = String.valueOf(wxJsapiTicket);
        } else {
            String getJsapiTicket = String.format(SecurityConstants.WX_JSAPI_TICKET_URL, access_token);
            log.info("wxJsapiTicket111="+JSON.toJSONString(wxJsapiTicket));
            String jsapiTicketresult = restTemplate.getForObject(getJsapiTicket, String.class);
            if (Common.isEmpty(jsapiTicketresult)) {
                throw new CheckedException("获取微信JsapiTicket失败");
            }
            JSONObject jsonObject = JSON.parseObject(jsapiTicketresult);
            if (StringUtils.equals(accossTokenInvliad, jsonObject.getString("errcode"))) {
                log.info(jsonObject.toJSONString());
                removeAccessToken();
                throw new CheckedException("accoss_token失效");
            }
            ticket = jsonObject.getString("ticket");
            if (Common.isEmpty(ticket)) {
                log.info(jsonObject.toJSONString());
                removeJsapiTicket();
                throw new CheckedException("获取微信ticket失败");
            }
            redisTemplate.opsForValue().set(CacheConstants.WX_JSAPI_TICKET, ticket);
            redisTemplate.expire(CacheConstants.WX_JSAPI_TICKET, 3600, TimeUnit.SECONDS);
        }
        //拼接字符串并用sha1加密

        String signString = new StrBuilder("jsapi_ticket=").append(ticket).append("&noncestr=").append(random).append("&timestamp=")
                .append(timeMillis).append("&url=").append(url).toString();
        String sign = EncryptUtil.getSha1(signString);
        log.info("signString=" + signString);
        log.info("sign=" + sign);
        if (Common.isEmpty(sign)) {
            log.info("signString=" + signString);
            throw new CheckedException("加密失败");
        }
        return sign;
    }


    /**
     * @param restTemplate
     * @param requestMap   请求内容
	 * @Author: fxj
	 * @Date: 2025-01-07
     * @Description: 发送卡片消息
     * @return: java.lang.String
     **/
    public boolean sendTextCard(RestTemplate restTemplate, Map<String, Object> requestMap) {
        // 必须加上header说明
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        Gson gson = new Gson();
        log.info(gson.toJson(requestMap));
        HttpEntity<String> requestEntity = new HttpEntity<>(gson.toJson(requestMap), headers);
        String accessToken = getAccessToken(restTemplate);
        ResponseEntity<String> responseEntity = restTemplate.postForEntity(String.format(SecurityConstants.WX_SEND_MESSAGE, accessToken), requestEntity, String.class);
        log.info(JSON.toJSONString(responseEntity));
        JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(responseEntity));
        JSONObject jsonBody = jsonObject.getJSONObject("body");
        if (jsonBody != null) {
            String errcode = jsonBody.getString("errcode");
            if (StringUtils.equals(accossTokenInvliad, errcode)) {
                //删除accossToken缓存
                removeAccessToken();
                return false;
            }
            if (!StringUtils.equals(CommonConstants.ZERO_STRING, errcode)) { //非正常，则打印错误日志
                log.info(jsonObject.toJSONString());
            }
        } else {
            log.info(jsonObject.toJSONString());
        }
        return true;
    }

    /**
     * @param restTemplate
     * @param requestMap   请求内容
     * @Author: wangan
     * @Date: 2020/7/30
     * @Description: 发送卡片消息
     * @return: java.lang.String
     **/
    /*public boolean sendAppTextCard(RestTemplate restTemplate, Map<String, Object> requestMap) {
        // 必须加上header说明
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        Gson gson = new Gson();
        log.info("发企业微信===请求：{}", gson.toJson(requestMap));
        HttpEntity<String> requestEntity = new HttpEntity<>(gson.toJson(requestMap), headers);
        String accessToken = getAppAccessToken(restTemplate);
        ResponseEntity<String> responseEntity = restTemplate.postForEntity(String.format(SecurityConstants.WX_SEND_MESSAGE, accessToken), requestEntity, String.class);
        log.info("发企业微信===返回：{}",JSON.toJSONString(responseEntity));
        JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(responseEntity));
        JSONObject jsonBody = jsonObject.getJSONObject("body");
        if (jsonBody != null) {
            String errcode = jsonBody.getString("errcode");
            if (StringUtils.equals(accossTokenInvliad, errcode)) {
                //删除accossToken缓存
                removeAccessToken();
                return false;
            }
            if (!StringUtils.equals(CommonConstants.ZERO_STRING, errcode)) { //非正常，则打印错误日志
                log.info(jsonObject.toJSONString());
            }
        } else {
            log.info(jsonObject.toJSONString());
        }
        return true;
    }*/

    /**
     * 功能描述: 获取微信accos_token
     * @Param: [restTemplate]
     * @Return: java.lang.String
     * @Author: zhouyang
     * @Date: 2021/10/12 15:27
     */
    /*public String getAppAccessToken(RestTemplate restTemplate) {
        return this.getToken(restTemplate, CacheConstants.WX_ACCOSS_TOKEN, appcorpsecret);
    }*/

    /**
     * 功能描述: 获取token
     * @Param: [restTemplate, tokenKey, corpsecretKey]
     * @Return: java.lang.String
     * @Author: zhouyang
     * @Date: 2021/10/12 15:25
     */
    /*public String getAppToken(RestTemplate restTemplate,String tokenKey, String corpsecretKey) {
        Object wxToken = redisTemplate.opsForValue().get(tokenKey);
        if (wxToken != null) {
            return String.valueOf(wxToken);
        }
        String requestTokenUrl = String.format(SecurityConstants.WX_GET_ACCOSS_TOKEN, appCorpid, corpsecretKey);
        String result = restTemplate.getForObject(requestTokenUrl, String.class);
        if (Common.isEmpty(result)) {
            throw new CheckedException("微信授权失败");
        }
        String token = JSON.parseObject(result).getString("access_token");
        if (Common.isEmpty(token)) {
            log.info(result);
            throw new CheckedException("获取微信token失败");
        }
        redisTemplate.opsForValue().set(tokenKey, token);
        redisTemplate.expire(tokenKey, 3600, TimeUnit.SECONDS);
        return token;
    }*/

    /**
     * 功能描述: 获取token
     * @Param: [restTemplate, tokenKey, corpsecretKey]
     * @Return: java.lang.String
     * @Author: zhouyang
     * @Date: 2021/10/12 15:25
     */
    /*public String isInVisibleRange(String account) {
        RestTemplate restTemplate = new RestTemplate();
        log.info("查询用户是否在可见范围内===请求：{}");
        String accessToken = getAppAccessToken(restTemplate);
        ResponseEntity<String> responseEntity = restTemplate.getForEntity(String.format(SecurityConstants.WX_IS_IN_VISIBLE_RANGE, accessToken,account), String.class);
        log.info("查询用户是否在可见范围内===返回：{}",JSON.toJSONString(responseEntity));
        JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(responseEntity));
        JSONObject jsonBody = jsonObject.getJSONObject("body");
        String errcode ="";
        if (jsonBody != null) {
            errcode = jsonBody.getString("errcode");
            if (!StringUtils.equals(CommonConstants.ZERO_STRING, errcode)) { //非正常，则打印错误日志
                log.info(jsonObject.toJSONString());
            }
        } else {
            log.info(jsonObject.toJSONString());
        }
        return errcode;
    }*/
}
