package com.cool.store.service.wechat;

import com.cool.store.builder.TemplateMessageBuilder;
import com.cool.store.config.weixin.WechatMpProperties;
import com.cool.store.dto.wechat.AccessTokenDTO;
import com.cool.store.dto.wechat.WechatTemplateMessageDTO;
import com.cool.store.dto.wechat.WechatUserInfoDTO;
import com.cool.store.enums.wechat.WechatTemplateEnum;
import com.cool.store.utils.OkHttpUtil;
import com.cool.store.utils.RedisUtilPool;
import com.cool.store.utils.poi.StringUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Map;

/**
 * @Author suzhuhong
 * @Date 2025/10/10 14:15
 * @Version 1.0
 */
@Slf4j
@Service
public class WechatTemplateService {


    private static final String ACCESS_TOKEN_KEY = "wechat_service_account_access_token";

    @Autowired
    private WechatMpProperties wechatMpProperties;

    @Autowired
    private TemplateMessageBuilder templateMessageBuilder;

    @Autowired
    private OkHttpUtil okHttpUtil;
    @Autowired
    private ObjectMapper objectMapper;
    @Resource
    private RedisUtilPool redisUtilPool;


    public String getAccessToken() {
        String cachedToken = redisUtilPool.getString(ACCESS_TOKEN_KEY);
        if (StringUtils.isNotEmpty(cachedToken)) {
            log.info("从 Redis 获取 access_token: {}", cachedToken);
            return cachedToken;
        }
        String url = String.format("%s?grant_type=client_credential&appid=%s&secret=%s",
                wechatMpProperties.getAccessTokenUrl(),
                wechatMpProperties.getAppId(),
                wechatMpProperties.getAppSecret());
        try {
            String result = okHttpUtil.doGet(url);
            log.info("获取access_token响应: {}", result);

            if (StringUtils.isNotEmpty( result)){
                AccessTokenDTO responseDTO = objectMapper.readValue(result, AccessTokenDTO.class);
                String accessToken = responseDTO.getAccess_token();

                // 将获取到的 token 存入 Redis，设置过期时间（微信 token 有效期 7200 秒，这里设置 7000 秒）
                if (StringUtils.isNotEmpty(accessToken)) {
                    redisUtilPool.setString(ACCESS_TOKEN_KEY, accessToken, 7000);
                    log.info("将 access_token 存入 Redis: {}", accessToken);
                }
                return accessToken;
            }
            return null;
        } catch (IOException e) {
            log.error("获取access_token失败", e);
        } catch (Exception e) {
            log.error("解析access_token响应失败", e);
        }
        return null;
    }

    public WechatUserInfoDTO getUserInfo(String openId, String lang) {
        String accessToken = getAccessToken();
        //默认中国
        lang = StringUtils.isEmpty(lang)?"zh_CN":lang;
        if (accessToken == null) {
            log.error("获取access_token失败");
            return null;
        }
        String url = String.format("https://api.weixin.qq.com/cgi-bin/user/info?access_token=%s&openid=%s",
                accessToken, openId);

        if (lang != null && !lang.trim().isEmpty()) {
            url += "&lang=" + lang;
        }
        try {
            String result = okHttpUtil.doGet(url);
            log.debug("获取用户信息响应: {}", result);
            WechatUserInfoDTO userInfo = objectMapper.readValue(result, WechatUserInfoDTO.class);
            return userInfo;
        } catch (IOException e) {
            log.error("获取用户信息失败", e);
            return null;
        } catch (Exception e) {
            log.error("解析用户信息响应失败", e);
            return null;
        }
    }

    public boolean sendNormalTemplate(String openId, WechatTemplateEnum template, Map<String, Object> data) {
        WechatTemplateMessageDTO messageDTO = templateMessageBuilder.buildNormalTemplate(openId, template, data);
        return sendTemplateMessage(messageDTO);
    }

    public boolean sendMiniAppTemplate(String openId, WechatTemplateEnum template,
                                       Map<String, Object> data, String miniAppPagePath) {
        WechatTemplateMessageDTO messageDTO = templateMessageBuilder.buildMiniappTemplate(
                openId, template, data, miniAppPagePath);
        return sendTemplateMessage(messageDTO);
    }

    public boolean sendMiniAppTemplateWithUrl(String openId, WechatTemplateEnum template,
                                              Map<String, Object> data, String miniAppPagePath, String backupUrl) {
        WechatTemplateMessageDTO messageDTO = templateMessageBuilder.buildMiniAppTemplateWithUrl(
                openId, template, data, miniAppPagePath, backupUrl);
        return sendTemplateMessage(messageDTO);
    }

    private boolean sendTemplateMessage(WechatTemplateMessageDTO messageDTO) {
        String accessToken = getAccessToken();
        if (accessToken == null) {
            log.error("获取access_token失败，无法发送模板消息");
            return false;
        }

        String url = String.format("%s?access_token=%s",
                wechatMpProperties.getSendTemplateMessageUrl(), accessToken);

        log.info("发送模板消息: {}", messageDTO);
        try {
            String result = okHttpUtil.doPostJson(url, messageDTO);
            log.info("发送模板消息响应: {}", result);

            return Boolean.TRUE;
        } catch (Exception e) {
            log.error("解析模板消息响应失败", e);
            return false;
        }
    }
}
