package com.loan.system.service.Impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.loan.system.domain.pojo.TemplateMessage;
import com.loan.system.properties.WeChatProperties;
import com.loan.system.service.WxService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

@Service
public class WxServiceImpl implements WxService {

    /**
     * 微信公众号appid
     */
//    @Value("${wechat.appid}")
//    private String appId;
//    /**
//     * 微信公众号secret
//     */
//    @Value("${wechat.secret}")
//    private String appSecret;
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    WeChatProperties weChatProperties;

    @Override

    public String wxDecrypt(String encryptedData, String sessionId, String vi) throws Exception {
        // 开始解密
        String json = redisTemplate.opsForValue().get("wx_session_id_" + sessionId);
        JSONObject jsonObject = JSON.parseObject(json);
        String sessionKey = (String) jsonObject.get("session_key");

        byte[] encData = Base64.getDecoder().decode(encryptedData); // 使用 Java 标准库
        byte[] iv = Base64.getDecoder().decode(vi); // 使用 Java 标准库
        byte[] key = Base64.getDecoder().decode(sessionKey); // 使用 Java 标准库

        AlgorithmParameterSpec ivSpec = new IvParameterSpec(iv);
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);

        return new String(cipher.doFinal(encData), "UTF-8");
    }
    @Override

    public String getAccessToken() {
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+weChatProperties.getAppid()+"&secret="+weChatProperties.getSecret();

        RestTemplate restTemplate = new RestTemplate();
        Map<String, Object> response = restTemplate.getForObject(url, Map.class, weChatProperties.getAppid(), weChatProperties.getSecret());

        if (response != null && response.containsKey("access_token")) {
            return (String) response.get("access_token");
        } else {
            throw new RuntimeException("获取access_token失败: " + response);
        }
    }
    @Override
    public String getUserPhoneNumber(String accessToken, String code) {
        String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessToken;

        RestTemplate restTemplate = new RestTemplate();

        // 设置 POST body
        Map<String, String> requestBody = new HashMap<>();
        requestBody.put("code", code);

        // 发送 POST 请求
        Map<String, Object> response = restTemplate.postForObject(url, requestBody, Map.class);
        if (response != null && response.containsKey("phone_info")) {
            @SuppressWarnings("unchecked")
            Map<String, Object> phoneInfo = (Map<String, Object>) response.get("phone_info");
            return (String) phoneInfo.get("phoneNumber");
        } else {
            throw new RuntimeException("获取手机号失败: " + response);
        }
    }

    @Override
    public boolean sendTemplateMessage(String openid, TemplateMessage message) {
        String token = getAccessToken();
        String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + token;

        // 确保 message 中的 openid 一致
        message.setTouser(openid);
        RestTemplate restTemplate = new RestTemplate();
        Map<String, Object> result = restTemplate.postForObject(url, message, Map.class);

        if (result == null) return false;

        Integer errcode = (Integer) result.get("errcode");
        return errcode != null && errcode == 0;
    }


}
