package com.seer.teach.mp.app.service;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.seer.teach.mp.app.controller.req.MpOpenCheckSignatureReq;
import com.seer.teach.mp.app.controller.req.MpOpenHandleMessageReq;
import com.seer.teach.mp.entity.MpAccountEntity;
import com.seer.teach.mp.factory.MpServiceFactory;
import com.seer.teach.mp.service.IMpAccountService;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PathVariable;

import jakarta.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Slf4j
@Service
public class AppMpNotificationService {

    @Resource
    private MpServiceFactory mpServiceFactory;

    @Resource
    private IMpAccountService mpAccountService;


    /**
     * 接收微信公众号的消息
     */
    public String handleMessage(String appId, String content,MpOpenHandleMessageReq reqVO) {
        MpAccountEntity account = mpAccountService.getOneByAppId(appId);
        Assert.notNull(account, "公众号 appId({}) 不存在", appId);
        // 校验请求签名
        WxMpService mppService = mpServiceFactory.getRequiredMpService(appId);
        Assert.isTrue(mppService.checkSignature(reqVO.getTimestamp(), reqVO.getNonce(), reqVO.getSignature()),
                "非法请求");

        // 第一步，解析消息
        WxMpXmlMessage inMessage = null;
        // 明文模式
        if (StrUtil.isBlank(reqVO.getEncrypt_type())) {
            inMessage = WxMpXmlMessage.fromXml(content);
        }
        // AES 加密模式
        if (Objects.equals(reqVO.getEncrypt_type(), MpOpenHandleMessageReq.ENCRYPT_TYPE_AES)) {
            inMessage = WxMpXmlMessage.fromEncryptedXml(content, mppService.getWxMpConfigStorage(),
                    reqVO.getTimestamp(), reqVO.getNonce(), reqVO.getMsg_signature());
        }
        Assert.notNull(inMessage, "消息解析失败，原因：消息为空");

        // 第二步，处理消息
        WxMpMessageRouter mpMessageRouter = mpServiceFactory.getRequiredMpMessageRouter(appId);
        Map<String, Object> context = new HashMap<>();
        context.put("appId", appId);
        context.put("account", account);
        WxMpXmlOutMessage outMessage = mpMessageRouter.route(inMessage,context, mppService);
        if (outMessage == null) {
            return "";
        }

        // 第三步，返回消息
        if (StrUtil.isBlank(reqVO.getEncrypt_type())) { // 明文模式
            return outMessage.toXml();
        } else if (Objects.equals(reqVO.getEncrypt_type(), MpOpenHandleMessageReq.ENCRYPT_TYPE_AES)) { // AES 加密模式
            return outMessage.toEncryptedXml(mppService.getWxMpConfigStorage());
        }
        return "";
    }

    /**
     * 接收微信公众号的校验签名
     */
    public String checkSignature(@PathVariable("appId") String appId,
                                 MpOpenCheckSignatureReq reqVO) {
        // 校验请求签名
        WxMpService wxMpService = mpServiceFactory.getRequiredMpService(appId);
        // 校验通过
        if (wxMpService.checkSignature(reqVO.getTimestamp(), reqVO.getNonce(), reqVO.getSignature())) {
            return reqVO.getEchostr();
        }
        return "error";
    }

}