package com.fjhx.controller;

import cn.hutool.core.io.IoUtil;
import com.fjhx.constants.WeChatConstants;
import com.fjhx.utils.aes.AesException;
import com.fjhx.utils.aes.WXBizMsgCrypt;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.redis.cache.BladeRedis;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;

@Slf4j
@RestController
@RequestMapping("/callback")
public class TestController {

    @Autowired
    private BladeRedis bladeRedis;


    @RequestMapping(value = "/test")
    public String test() {
        return "hello";
    }

    /**
     * 验证通用开发参数及应用回调
     *
     * @link { https://developer.work.weixin.qq.com/tutorial/detail/38 }
     * @link { https://article.itxueyuan.com/BJ3rrG }
     * @link { https://developer.work.weixin.qq.com/document/10982#%E6%8E%A8%E9%80%81suite_ticket }
     */
    @GetMapping(value = "/data")
    public void data(HttpServletRequest request, HttpServletResponse response) {

        // 微信加密签名
        String msgSignature = request.getParameter("msg_signature");
        // 时间戳
        String timestamp = request.getParameter("timestamp");
        // 随机数
        String nonce = request.getParameter("nonce");
        // 随机字符串
        String echoStr = request.getParameter("echostr");

        log.error("data:   msg_signature:{}; timestamp:{}; nonce:{}; echostr:{}", msgSignature, timestamp, nonce, echoStr);

        try {
            WXBizMsgCrypt wxBizMsgCrypt = new WXBizMsgCrypt(WeChatConstants.TOKEN, WeChatConstants.ENCODING_AES_KEY, WeChatConstants.CORP_ID);
            String echostr = wxBizMsgCrypt.VerifyURL(msgSignature, timestamp, nonce, echoStr);

            log.error("dataEchostr:  " + echostr);

            // 验证URL成功，将sEchoStr返回
            response.getWriter().print(echostr);

        } catch (Exception e) {
            //验证URL失败，错误原因请查看异常
            log.error("验证失败", e);
        }
    }

    /**
     * 验证通用开发参数及应用回调
     *
     * @link { https://developer.work.weixin.qq.com/tutorial/detail/38 }
     */
    @PostMapping(value = "/data")
    public String data(HttpServletRequest request) {
        // 微信加密签名
        String sReqMsgSig = request.getParameter("msg_signature");
        // 时间戳
        String sReqTimeStamp = request.getParameter("timestamp");
        // 随机数
        String sReqNonce = request.getParameter("nonce");

        // 密文，对应POST请求的数据
        StringBuilder sReqData = new StringBuilder();

        BufferedReader reader = null;
        try {
            ServletInputStream in = request.getInputStream();
            reader = new BufferedReader(new InputStreamReader(in));

            String tempStr;
            while (null != (tempStr = reader.readLine())) {
                sReqData.append(tempStr);
            }

            WXBizMsgCrypt wxBizMsgCrypt = new WXBizMsgCrypt(WeChatConstants.TOKEN, WeChatConstants.ENCODING_AES_KEY, WeChatConstants.CORP_ID);

            // 刷新ticket，AuthCode
            String sMsg = wxBizMsgCrypt.DecryptMsg(sReqMsgSig, sReqTimeStamp, sReqNonce, sReqData.toString());

            log.error("command:" + sMsg);

            // TODO: 解析出明文xml标签的内容进行处理
            // For example:
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            StringReader sr = new StringReader(sMsg);
            InputSource is = new InputSource(sr);
            Document document = db.parse(is);

            Element root = document.getDocumentElement();
            NodeList nodelist = root.getElementsByTagName("Content");

            for (int i = 0; i < nodelist.getLength(); i++) {
                String Content = nodelist.item(i).getTextContent();
                System.out.println("Content" + i + ": " + Content);
            }
        } catch (IOException | SAXException | ParserConfigurationException | AesException e) {
            e.printStackTrace();
            return "error";
        } finally {
            IoUtil.close(reader);
        }

        return "success";
    }

}
