package vip.xiaonuo.biz.api.wxapp.controller;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import vip.xiaonuo.biz.api.wxapp.param.AccessTokenParam;
import vip.xiaonuo.biz.api.wxapp.service.AccessTokenService;
import vip.xiaonuo.biz.core.Const.BizStr;
import vip.xiaonuo.biz.modular.user.service.BizUserService;
import vip.xiaonuo.biz.modular.user.service.UserWxOpenService;
import vip.xiaonuo.common.annotation.CommonLog;
import vip.xiaonuo.common.cache.CommonCacheOperator;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.common.pojo.CommonResult;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * @Author: wl
 * @Date: 2023/9/18 15:07
 * @Notes:
 */
@RestController
@Slf4j
public class WxSendController {


    /*@Resource
    private WxProcessApprovalPushService processAapprovalPushService;
    @Resource
    private OaWxAttentionLogService oaWxAttentionLogService;
    @Resource
    private RedisUtils redisUtils;*/
    @Resource
    BizUserService bizUserService;
    @Resource
    private CommonCacheOperator commonCacheOperator;
    @Resource
    private UserWxOpenService userWxOpenService;
    @Resource
    private AccessTokenService accessTokenService;


    /**
     * 公众号消息推送测试
     */
    /*@GetMapping(value = "/wx/process/send")
    public ResponseData send() {
        processAapprovalPushService.sendProcessApprovalMsg(
                null,
                "ogKD76bKcxbBrFoKTPvBpmXmzyAM",
                "测试申请",
                "华晓明",
                "待审核",
                "2023-5-25 10:41:40");
        return new SuccessResponseData();
    }*/
    @GetMapping("/cloudWxOpen/wxUser")
    public void get(HttpServletRequest request, HttpServletResponse response) {
        // 微信加密签名，signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
        String signature = request.getParameter("signature");
        // 时间戳
        String timestamp = request.getParameter("timestamp");
        // 随机数
        String nonce = request.getParameter("nonce");
        // 随机字符串
        String echostr = request.getParameter("echostr");
        PrintWriter out = null;
        try {
            out = response.getWriter();
            // 通过检验signature对请求进行校验，若校验成功则原样返回echostr，否则接入失败
            //if (SignUtil.checkSignature("jswhzl", signature, timestamp, nonce)) {
            out.print(echostr);
            //}
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                out.close();
            }
        }
    }

    /**
     * 微信用户_公众号关注信息回调
     *
     * @param request  request
     * @param response response
     */
    @PostMapping("/cloudWxOpen/wxUser")
    public void post(HttpServletRequest request, HttpServletResponse response) {
        // 响应消息
        PrintWriter out = null;
        try {
            request.setCharacterEncoding("UTF-8");
            response.setCharacterEncoding("UTF-8");
            //把微信返回的xml信息转义成map
            Map<String, Object> map = parseXML(request.getInputStream());
            bizUserService.edit("1701499594727940097", JSONUtil.toJsonStr(map));
            //消息来源用户标识
            String fromUserName = (String) map.get("FromUserName");
            //消息目的用户标识
            String toUserName = (String) map.get("ToUserName");
            //消息创建时间（整型）
            String createTime = (String) map.get("CreateTime");
            //消息类型
            String msgType = (String) map.get("MsgType");
            //事件类型：subscribe/unsubscribe
            String eventType = (String) map.get("Event");
            log.info("公众号订阅消息：" + map);
            log.info("eventType:" + eventType + ",fromUserName:" + fromUserName + ",toUserName:" + toUserName + ",msgType:" + msgType + ",createTime:" + createTime);
            //如果为事件类型
            if ("event".equals(msgType)) {
                //订阅
                if ("subscribe".equals(eventType)) {
                    JSONObject jsonObject = getUserInfo(fromUserName);
                    bizUserService.edit("1701759961190318082", jsonObject.toString());
                    if (jsonObject != null && StrUtil.isNotEmpty(jsonObject.getString("unionid"))) {
                        userWxOpenService.subscribe(jsonObject.getString("unionid"), fromUserName, "subscribe");
                    }
                }
                //取消订阅
                else if ("unsubscribe".equals(eventType)) {
                    userWxOpenService.unsubscribe(fromUserName);
                }
            }
            out = response.getWriter();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                out.close();
            }
        }
    }

    /**
     * 简单解析xml
     *
     * @param in InputStream
     * @return map
     */
    private Map<String, Object> parseXML(InputStream in) {
        Map<String, Object> map = new HashMap<>();
        try {
            SAXReader saxReader = new SAXReader();
            Document document = saxReader.read(in);
            Element root = document.getRootElement();
            Iterator iterator = root.elementIterator();
            while (iterator.hasNext()) {
                Element element = (Element) iterator.next();
                map.put(element.getName(), element.getStringValue());

            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }

        return map;
    }

    /**
     * 获取微信用户信息
     *
     * @param openId openId
     * @return JSONObject
     */
    private JSONObject getUserInfo(String openId) {
        JSONObject jsonObject = null;
        String accessToken = accessTokenService.getAccessToken(new AccessTokenParam());

        log.info("-------openId：" + openId + "-------");
        log.info("-------accessToken：" + accessToken + "-------");

        StringBuffer url = new StringBuffer("https://api.weixin.qq.com/cgi-bin/user/info");
        url.append("?access_token=").append(accessToken);
        url.append("&openid=").append(openId);
        url.append("&lang=zh_CN");

        String requestResult = HttpUtil.get(url.toString(), 15000);
        if (ObjectUtil.isNotEmpty(requestResult)) {
            jsonObject = JSON.parseObject(requestResult);
        }
        log.info("-------微信用户信息：" + requestResult + "-------");
        return jsonObject;
    }

    /**
     * 获取微信 accessToken
     */
    @GetMapping("/api/wxapp/accessToken")
    public CommonResult<Object> accessToken(AccessTokenParam param) {
        accessTokenService.getAccessToken(param);
        return CommonResult.data(param);
    }

}
