package cn.iocoder.yudao.module.system.controller;

import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.module.system.dal.dataobject.auth.AdminWxMpInfoDO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.framework.common.enums.SocialTypeEnum;
import cn.iocoder.yudao.module.system.service.auth.AdminOauthUserOtherInfoService;
import cn.iocoder.yudao.module.system.service.auth.AdminWxMpInfoService;
import cn.iocoder.yudao.module.system.service.social.SocialClientService;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Tag(name = "管理后台 - 微信公众号")
@RestController
@RequestMapping("/wei-xin")
@Slf4j
public class WeiXinController {
    @Resource
    private SocialClientService socialClientService;
    @Resource
    private AdminUserService adminUserService;
    @Resource
    private AdminWxMpInfoService adminWxMpInfoService;
    @Resource
    private AdminOauthUserOtherInfoService adminOauthUserOtherInfoService;


    @RequestMapping(value = "/monitor", method = {RequestMethod.POST, RequestMethod.GET})
    @PermitAll
    public void monitor(HttpServletRequest request, HttpServletResponse response) throws IOException {
        TenantContextHolder.setTenantId(1L);
        response.setContentType("text/html;charset=utf-8");
        response.setStatus(HttpServletResponse.SC_OK);
        String msgSignature = request.getParameter("msg_signature");
        String signature = request.getParameter("signature");
        String nonce = request.getParameter("nonce");
        String timestamp = request.getParameter("timestamp");
        String echostr = request.getParameter("echostr");
        log.info("微信公众号信息：signature={}, timestamp={}, nonce={}, echostr={},msgSignature={}", signature, timestamp, nonce, echostr, msgSignature);
        if (StringUtils.isNotBlank(echostr)) {
            if (!socialClientService.getWxMpService().checkSignature(timestamp, nonce, signature)) {
                // 消息签名不正确，说明不是公众平台发过来的消息
                response.getWriter().println("非法请求");
                return;
            }
            // 说明是一个仅仅用来验证的请求，回显echostr
            response.getWriter().println(echostr);
            return;
        }
        WxMpXmlMessage wxMpXmlMessage = WxMpXmlMessage.fromXml(request.getInputStream());
        try {
            WxMpUser wxMpUser = socialClientService.getWxMpService().getUserService().userInfo(wxMpXmlMessage.getFromUser());
            String unionId = wxMpUser.getUnionId();
            String event = wxMpXmlMessage.getEvent();
            String openId = wxMpXmlMessage.getFromUser();
            // - subscribe 订阅
            //   unsubscribe 取消订阅
            // ---- 先通过unionId获取用户信息 - 如果没有获取到的话 - 插入到表中记录 unionId和公众号openId信息 - 后续用户有unionId后再进行绑定
            AdminUserDO adminUserDO = adminUserService.getUserByUnionId(unionId);
            String appId = socialClientService.getWxMpService().getWxMpConfigStorage().getAppId();
            if ("subscribe".equals(event)) {
                if (adminUserDO == null) {
                    adminWxMpInfoService.save(new AdminWxMpInfoDO()
                            .setAppId(appId)
                            .setOpenId(openId)
                            .setUnionId(unionId));
                } else {
                    // ---- 检查 / 插入 公众号openId
                    adminOauthUserOtherInfoService.checkInsert(adminUserDO.getId(), appId, openId, SocialTypeEnum.WECHAT_MP.getType());
                }
            } else {
                //删除存贮的公众号openId - 这里不管他有没有存 - 先删再说
                adminWxMpInfoService.del(appId, unionId);
//                if (adminUserDO != null) {
//                    // -- 删除 关联的 公众号openId
//                    adminOauthUserOtherInfoService.delByCondition(adminUserDO.getId(), appId, openId, SocialTypeEnum.WECHAT_MP.getType());
//                }
            }
            log.info("微信信息用户信息：{}", wxMpUser);
        } catch (WxErrorException e) {
            throw new RuntimeException(e);
        }
        log.info("微信公众号信息：{}", wxMpXmlMessage);
    }
}
