package cn.iocoder.yudao.module.system.service.wx;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service
public class WechatBusinessService {


    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private WeChatTokenService tokenService;

    @Value("${wechat.mp.templateId}")
    private String templateId;

    @Value("${wechat.miniapp.appid}")
    private String appId;



    @Async
    public void handleUserSubscribe(String openId) {
        try {
            log.info("开始处理用户关注事件，OpenID: {}", openId);

            // 1. 获取access_token
            String accessToken = tokenService.getAccessToken();
            if (accessToken == null) {
                log.error("获取access_token失败");
                return;
            }

            // 2. 获取用户信息（包含UnionID）
            Map<String, Object> userInfo = getUserInfo(accessToken, openId);
            if (userInfo != null) {
                String unionId = (String) userInfo.get("unionid");
                String nickname = (String) userInfo.get("nickname");

                log.info("获取到用户信息 - OpenID: {}, UnionID: {}, 昵称: {}",
                        openId, unionId, nickname);

                sendWelcomeMessage(openId, nickname);

//                // 3. 保存用户信息到数据库
//                saveUserInfo(openId, unionId, userInfo);
//
//                // 4. 后续处理（例如发送欢迎消息、绑定用户账号等）
//                processAfterSubscribe(openId, unionId, userInfo);
            }

        } catch (Exception e) {
            log.error("处理用户关注事件异常", e);
        }
    }

    /**
     * 获取微信用户信息（包含UnionID）
     */
    private Map<String, Object> getUserInfo(String accessToken, String openId) {
        try {
            String url = String.format(
                    "https://api.weixin.qq.com/cgi-bin/user/info?access_token=%s&openid=%s&lang=zh_CN",
                    accessToken, openId
            );

            log.info("请求用户信息API: {}", url);
            String response = restTemplate.getForObject(url, String.class);
            log.info("用户信息API响应: {}", response);

            JSONObject json = JSONObject.parseObject(response);

            // 检查错误
            if (json.containsKey("errcode")) {
                int errcode = json.getIntValue("errcode");
                if (errcode != 0) {
                    log.error("获取用户信息失败: {}", json.getString("errmsg"));
                    return null;
                }
            }

            // 转换为Map返回
            Map<String, Object> result = new HashMap<>();
            result.put("openid", json.getString("openid"));
            result.put("unionid", json.getString("unionid")); // 可能为null
            result.put("nickname", json.getString("nickname"));
            result.put("sex", json.getIntValue("sex"));
            result.put("province", json.getString("province"));
            result.put("city", json.getString("city"));
            result.put("country", json.getString("country"));
            result.put("headimgurl", json.getString("headimgurl"));
            result.put("subscribe", json.getIntValue("subscribe"));
            result.put("subscribe_time", json.getLongValue("subscribe_time"));
            result.put("remark", json.getString("remark"));
            result.put("groupid", json.getIntValue("groupid"));

            return result;

        } catch (Exception e) {
            log.error("获取用户信息异常", e);
            return null;
        }
    }

    /**
     * 发送欢迎消息（使用客服消息接口）
     */
    private void sendWelcomeMessage(String openId, String nickname) {
        sendTextMessage(openId, "欢迎关注！");

        // 再发小程序卡片
        sendMiniProgramCard(openId);
    }

    private void sendMessage(JSONObject message) {
        try {
            String accessToken = tokenService.getAccessToken();
            if (accessToken == null) return;

            String url = String.format(
                    "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=%s",
                    accessToken
            );

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);

            HttpEntity<String> entity = new HttpEntity<>(message.toJSONString(), headers);

            ResponseEntity<String> stringResponseEntity = restTemplate.postForEntity(url, entity, String.class);
            if (stringResponseEntity.getStatusCode() != HttpStatus.OK) {
                log.error("发送消息失败，状态码：{}", stringResponseEntity.getStatusCode());
            }

        } catch (Exception e) {
            log.error("发送消息失败", e);
        }
    }


    /**
     * 发送小程序卡片
     */
    private void sendMiniProgramCard(String openId) {
        JSONObject msg = new JSONObject();
        msg.put("touser", openId);
        msg.put("msgtype", "miniprogrampage");
        JSONObject card = new JSONObject();
        card.put("title", "欢迎进入小程序\uD83D\uDC4B");
        card.put("appid", appId);
        card.put("pagepath", "pages/index/index?openid=" + openId);
        card.put("thumb_media_id", "wXpK3fjAbL80Ep5KkbFlKKTjaLgHoHzn8tY8G_PpV2XJJyQKQbC6o7qkVuDm1xpV"); // 需先上传图片
        msg.put("miniprogrampage", card);
        sendMessage(msg);
    }

    private void sendTextMessage(String openId, String content) {
        JSONObject msg = new JSONObject();
        msg.put("touser", openId);
        msg.put("msgtype", "text");
        JSONObject text = new JSONObject();
        text.put("content", content);
        msg.put("text", text);
        sendMessage(msg);
    }


    private Map<String, Object> buildBillTemplateParam(String openid,Long orderId) {
        Map<String, Object> param = new HashMap<>();
        param.put("touser", openid); // 接收用户openid
        param.put("template_id", templateId); // 模板ID
        param.put("topcolor", "#FF0000"); // 消息顶部颜色（可选）

        // ------------------------------ 核心修改：小程序跳转配置 ------------------------------
        Map<String, String> miniprogram = new HashMap<>();
        miniprogram.put("appid", appId); // 关联的小程序AppID
        // 页面路径+携带订单ID参数（格式：页面路径?key=value，多参数用&分隔）
        miniprogram.put("pagepath", "pages/index/index?orderId=" + orderId.toString());
        param.put("miniprogram", miniprogram); // 替换原url节点
        // ----------------------------------------------------------------------------------

        // 模板关键词参数（与模板一致）
        Map<String, Map<String, String>> data = new HashMap<>();
        data.put("thing2", buildParamValue("月度账单"));
        data.put("thing18", buildParamValue("张三"));
        data.put("amount13", buildParamValue("100.00"));
        data.put("time14", buildParamValue("2025-12-03"));
        data.put("thing12", buildParamValue("李四"));
        param.put("data", data);

        return param;
    }

    /**
     * 构建单个关键词的参数格式
     */
    private static Map<String, String> buildParamValue(String value) {
        Map<String, String> param = new HashMap<>();
        param.put("value", value);
        param.put("color", "#173177");
        return param;
    }


    /**
     * 推送账单模板消息
     *
     */
    public boolean pushBillMessage(String openId) {
        try {
            // 1. 获取Access Token (需缓存，避免频繁调用)
            String accessToken = tokenService.getAccessToken();

            // 2. 构建模板消息请求体 (关键！)
            Map<String, Object> map = buildBillTemplateParam(openId,21897L);

            // 3. 调用微信API发送
            String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken;
            ResponseEntity<String> response = restTemplate.postForEntity(url, map, String.class);

            // 4. 解析结果
            JSONObject result = JSONObject.parseObject(response.getBody());
            log.info("发送模板消息结果：{}", result);
            return result.getInteger("errcode") == 0;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

}


