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

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 lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Hex;
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.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Author: huyc
 * @Date: 2023/7/28
 * @Description:
 * @return: 企业微信配置
 **/
@Configuration
@Data
@Slf4j
public class WxConfig {

	@Value("${wx.corpid}")
	private String corpid;
	@Value("${wx.corpsecret}")
	private String corpsecret;
	// 项目报销获取token专用
	@Value("${wx.reimbursementCorpsecret}")
	private String reimbursementCorpsecret;
	@Value("${wx.agentid}")
	private String agentid;
	@Value("${wx.authUrl}")
	private String authUrl;

	// 获取HCM相关信息
	@Value("${hcm.appId}")
	private String hcmAppId;
	@Value("${hcm.appSecret}")
	private String hcmAppSecret;
	@Value("${hcm.appUrl}")
	private String hcmAppUrl;

	@Autowired
	private RedisTemplate redisTemplate;

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

	/**
	 * @Description: 获取HCM出差的sign
	 * @Author: hgw
	 * @Date: 2024-4-29 15:34:54
	 * @return: java.lang.String
	 **/
	public String getHcmSign() {
		String sign = null;
		Object wxToken = redisTemplate.opsForValue().get(CacheConstants.HCM_CHU_CHAI_SIGN);
		if (null != wxToken) {
			return String.valueOf(wxToken);
		}
		try {
			byte[] a = (hcmAppId + hcmAppSecret).getBytes(StandardCharsets.UTF_8);
			sign = Hex.encodeHexString(MessageDigest.getInstance("SHA-256").digest(a));
		} catch (Exception e) {
			e.printStackTrace();
			log.error("2拉取HCM出差数据sign出错=" + e.getMessage());
		}
		redisTemplate.opsForValue().set(CacheConstants.HCM_CHU_CHAI_SIGN, sign);
		redisTemplate.expire(CacheConstants.HCM_CHU_CHAI_SIGN, 3600, TimeUnit.SECONDS);
		return sign;
	}

	/**
	 * @Description: 获取HCM出差的url
	 * @Author: hgw
	 * @Date: 2024-4-29 15:34:54
	 * @return: java.lang.String
	 **/
	public String getHcmChuChaiUrl() {
		return hcmAppUrl;
	}

	/**
	 * @param restTemplate
	 * @Description: 获取项目报销的token
	 * @Author: hgw
	 * @Date: 2021/3/24 14:42
	 * @return: java.lang.String
	 **/
	public String getReimbursementToken(RestTemplate restTemplate) {
		return this.getToken(restTemplate, CacheConstants.WX_REIMBURSEMENT_TOKEN, reimbursementCorpsecret);
	}

	/**
	 * @param
	 * @Author: huyc
	 * @Date: 2023/7/28
	 * @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 corpsecret) throws AuthenticationServiceException {
		if (Common.isEmpty(corpsecret)) {
			throw new AuthenticationServiceException("未找到对应的corpsecret请联系管理员配置");
		}
		return this.getToken(restTemplate, CacheConstants.WX_ACCOSS_TOKEN.concat(agentid), corpsecret);
	}

	/**
	 * @param restTemplate
	 * @param tokenKey
	 * @param corpsecretKey
	 * @Description: 获取token
	 * @Author: huyc
	 * @Date: 2023/7/28 14:46
	 * @return: java.lang.String
	 **/
	public String getToken(RestTemplate restTemplate, String tokenKey, String corpsecretKey) {
		Object wxToken = redisTemplate.opsForValue().get(tokenKey);
		if (null != wxToken) {
			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: huyc
	 * @Date: 2023/7/28 14:43
	 * @Description: 移除微信accossToken
	 * @return: java.lang.String
	 **/
	public void removeAccessToken() {
		redisTemplate.delete(CacheConstants.WX_ACCOSS_TOKEN);
	}

	/**
	 * @param restTemplate
	 * @param requestMap   请求内容
	 * @Author: huyc
	 * @Date: 2023/7/28 14:48
	 * @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 (accossTokenInvliad.equals(errcode)) {
				//删除accossToken缓存
				removeAccessToken();
				return false;
			}
			if (!CommonConstants.ZERO_STRING.equals(errcode)) { //非正常，则打印错误日志
				log.info(jsonObject.toJSONString());
			}
		} else {
			log.info(jsonObject.toJSONString());
		}
		return true;
	}

	/**
	 * @param restTemplate
	 * @param requestMap   请求内容
	 * @Author: huyc
	 * @Date: 2023/7/28 14:50
	 * @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 (accossTokenInvliad.equals(errcode)) {
				//删除accossToken缓存
				removeAccessToken();
				return false;
			}
			if (!CommonConstants.ZERO_STRING.equals(errcode)) { //非正常，则打印错误日志
				log.info(jsonObject.toJSONString());
			}
		} else {
			log.info(jsonObject.toJSONString());
		}
		return true;
	}

	/**
	 * 功能描述: 获取微信accos_token
	 *
	 * @Author: huyc
	 * @Date: 2023/7/28 14:50
	 * @return: java.lang.String
	 */
	public String getAppAccessToken(RestTemplate restTemplate) {
		return this.getToken(restTemplate, CacheConstants.WX_ACCOSS_TOKEN, corpsecret);
	}
}
