package com.xinelu.mobile.controller.wechatofficialaccountcallback;

import com.xinelu.common.config.WeChatOfficialAccountConfig;
import com.xinelu.common.enums.OfficialAccountEventEnum;
import com.xinelu.common.utils.aes.AesException;
import com.xinelu.common.utils.aes.WXBizMsgCrypt;
import com.xinelu.mobile.dto.wechatappletcallback.MessageSignDTO;
import com.xinelu.mobile.service.wechatofficialaccountcallback.WeChatOfficialAccountCallbackService;
import com.xinelu.mobile.utils.XmlUtil;
import com.xinelu.mobile.vo.wechatofficialaccountcallback.WeChatOfficialAccountEventPushVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Objects;

/**
 * @Description 院后微信公众号事件回调控制器
 * @Author 纪寒
 * @Date 2024-03-21 14:26:56
 * @Version 1.0
 */
@Slf4j
@RestController
@RequestMapping("/postDischarge/officialAccountCallback")
public class WeChatOfficialAccountCallbackController {
    @Resource
    private WeChatOfficialAccountConfig weChatOfficialAccountConfig;
    @Resource
    private WeChatOfficialAccountCallbackService weChatOfficialAccountCallbackService;

    /**
     * 院后微信公众号回调验证方法
     *
     * @param messageSignDTO 微信输入参数
     * @return 解密后的字符串
     * @throws AesException 异常信息
     */
    @GetMapping
    public String getWeChatOfficialAccountCallBack(MessageSignDTO messageSignDTO) throws AesException {
        //解密微信报文信息并验证微信公众号与服务器之间是否正常通信
        WXBizMsgCrypt wxCpt = new WXBizMsgCrypt(weChatOfficialAccountConfig.getOfficialAccountToken(), weChatOfficialAccountConfig.getOfficialAccountEncodingAesKey(), weChatOfficialAccountConfig.getOfficialAccountAppId());
        String verifyMessage = wxCpt.verifyUrl(messageSignDTO.getSignature(), messageSignDTO.getTimestamp(), messageSignDTO.getNonce(), messageSignDTO.getEchostr());
        log.info("院后微信公众号回调设置验证URL成功，验证信息：verifyMessage = [{}]", verifyMessage);
        return verifyMessage;
    }

    /**
     * 院后微信公众号模板消息事件回调处理
     *
     * @param signature 签名
     * @param timestamp 时间戳
     * @param nonce     随机字符串
     * @param postData  事件报文内容
     * @throws AesException 异常信息
     */
    @PostMapping
    public void handleWeChatOfficialAccountCallBack(@RequestParam("signature") String signature,
                                                    @RequestParam("timestamp") String timestamp,
                                                    @RequestParam("nonce") String nonce,
                                                    @RequestBody String postData) throws AesException {
        //解密微信报文信息并验证微信公众号与服务器之间是否正常通信
        WXBizMsgCrypt wxCpt = new WXBizMsgCrypt(weChatOfficialAccountConfig.getOfficialAccountToken(), weChatOfficialAccountConfig.getOfficialAccountEncodingAesKey(), weChatOfficialAccountConfig.getOfficialAccountAppId());
        String verifyMessage = wxCpt.verifyUrl(signature, timestamp, nonce, postData);
        WeChatOfficialAccountEventPushVO eventPush = (WeChatOfficialAccountEventPushVO) XmlUtil.fromXml(verifyMessage, WeChatOfficialAccountEventPushVO.class);
        if (Objects.isNull(eventPush)) {
            log.info("院后微信公众号模板消息事件xml数据转换失败，请求信息为： [{}]", verifyMessage);
            return;
        }
        if (StringUtils.isBlank(eventPush.getToUserName()) || StringUtils.isBlank(eventPush.getEvent()) || StringUtils.isBlank(eventPush.getMsgType())) {
            log.info("院后微信公众号模板消息事件解析事件数据为空！");
            return;
        }
        //微信模板公众号消息事件
        if (OfficialAccountEventEnum.TEMPLATESENDJOBFINISH.getInfo().equals(eventPush.getEvent())) {
            weChatOfficialAccountCallbackService.handleOfficialAccountTemplateEvent(eventPush);
        }
        //微信公众号关注和取消事件
        if (OfficialAccountEventEnum.SUBSCRIBE.getInfo().equals(eventPush.getEvent()) ||
                OfficialAccountEventEnum.UNSUBSCRIBE.getInfo().equals(eventPush.getEvent())) {
            weChatOfficialAccountCallbackService.handleOfficialAccountSubscribeEvent(eventPush);
        }
    }
}

