package com.tzld.piaoquan.api.controller.wecom;

import com.alibaba.fastjson.JSONObject;
import com.tzld.piaoquan.api.service.wecom.WeComAutoReply;
import com.tzld.piaoquan.growth.common.common.constant.WeComServerConstant;
import com.tzld.piaoquan.growth.common.component.HttpPoolClient;
import com.tzld.piaoquan.growth.common.model.vo.SendRequestParam;
import com.tzld.piaoquan.growth.common.service.WeComUserService;
import com.tzld.piaoquan.growth.common.utils.wecom.WXBizMsgCrypt;
import com.tzld.piaoquan.growth.common.utils.wecom.WxUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.Map;
import java.util.UUID;

import static com.tzld.piaoquan.growth.common.common.enums.CorpEnum.*;

@Slf4j
@RestController
@RequestMapping("/wecom/server")
public class TencentWeComController {


    @Autowired
    private WeComUserService weComUserService;

    @Autowired
    private WeComAutoReply weComAutoReply;

    @Autowired
    private HttpPoolClient httpPoolClient;

    @GetMapping("/verify")
    public void verifyGet(HttpServletRequest request, HttpServletResponse response) {
        try {
            // 微信加密签名
            String msgSignature = request.getParameter("msg_signature");
            // 时间戳
            String timestamp = request.getParameter("timestamp");
            // 随机数
            String nonce = request.getParameter("nonce");
            // 随机字符串
            // 如果是刷新，需返回原echostr
            String echoStr = request.getParameter("echostr");
            // 微信加密签名
            WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(WeComServerConstant.TOKEN,
                    WeComServerConstant.ENCODING_AES_KEY,
                    WeComServerConstant.CORP_ID);

            String sEchoStr = ""; //需要返回的明文
            PrintWriter out;

            sEchoStr = wxcpt.VerifyURL(msgSignature, timestamp,
                    nonce, echoStr);
            log.info("verifyurl echostr: " + sEchoStr);

            // 验证URL成功，将sEchoStr返回
            out = response.getWriter();
            out.print(sEchoStr);
        } catch (Exception e) {
            //验证URL失败，错误原因请查看异常
            log.error("verifyGet error", e);
        }

    }

    /**
     * 刷新 ticket
     */
    @PostMapping(value = "/verify")
    public String verifyPost(HttpServletRequest request) {

        try {
            // 微信加密签名
            String msg_signature = request.getParameter("msg_signature");
            // 时间戳
            String timestamp = request.getParameter("timestamp");
            // 随机数
            String nonce = request.getParameter("nonce");

            String id = WeComServerConstant.CORP_ID;

            WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(WeComServerConstant.TOKEN, WeComServerConstant.ENCODING_AES_KEY, id);

            StringBuilder postData = new StringBuilder();   // 密文，对应POST请求的数据
            //1.获取加密的请求消息：使用输入流获得加密请求消息postData
            ServletInputStream in = request.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));

            String tempStr = "";   //作为输出字符串的临时串，用于判断是否读取完毕
            while (null != (tempStr = reader.readLine())) {
                postData.append(tempStr);
            }

            String suiteXml = wxcpt.DecryptMsg(msg_signature, timestamp, nonce, postData.toString());
            log.info("suiteXml: " + suiteXml);

            Map suiteMap = WxUtil.transferXmlToMap(suiteXml);
            log.info("suiteMap = {}", JSONObject.toJSONString(suiteMap));
            if (suiteMap != null) {
                String changeType = (String) suiteMap.get("ChangeType");
                if (StringUtils.isNotEmpty(changeType) && changeType.equals("add_external_contact")) {
                    String userId = (String) suiteMap.get("UserID");
                    String externalUserId = (String) suiteMap.get("ExternalUserID");
                    String welcomeCode = (String) suiteMap.get("WelcomeCode");
                    log.info("addStaffWithUser userId={} externalUserId={}", userId, externalUserId);
                    weComUserService.addStaffWithUser(externalUserId, userId, HNWQ.getId());
                    weComAutoReply.AutoReplyMessage(welcomeCode, externalUserId, userId, HNWQ.getId());
                }

                if (StringUtils.isNotEmpty(changeType) && changeType.equals("del_follow_user")) {
                    String userId = (String) suiteMap.get("UserID");
                    String externalUserId = (String) suiteMap.get("ExternalUserID");
                    log.info("delStaffWithUser userId={} externalUserId={}", userId, externalUserId);
                    weComUserService.delStaffWithUser(externalUserId, userId, HNWQ.getId(), System.currentTimeMillis());
                }
            }
        } catch (Exception e) {
            log.error("verifyPost error", e);
        }
        String success = "success";
        return success;
    }


    //优量圈验证接口
    @GetMapping("/ylq/verify")
    public void ylqVerifyGet(HttpServletRequest request, HttpServletResponse response) {
        try {
            // 微信加密签名
            String msgSignature = request.getParameter("msg_signature");
            // 时间戳
            String timestamp = request.getParameter("timestamp");
            // 随机数
            String nonce = request.getParameter("nonce");
            // 随机字符串
            // 如果是刷新，需返回原echostr
            String echoStr = request.getParameter("echostr");
            // 微信加密签名
            WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(WeComServerConstant.YLQ_TOKEN,
                    WeComServerConstant.YLQ_ENCODING_AES_KEY,
                    WeComServerConstant.YLQ_CORP_ID);

            String sEchoStr = ""; //需要返回的明文
            PrintWriter out;

            sEchoStr = wxcpt.VerifyURL(msgSignature, timestamp,
                    nonce, echoStr);
            log.info("verifyurl echostr: " + sEchoStr);

            // 验证URL成功，将sEchoStr返回
            out = response.getWriter();
            out.print(sEchoStr);
        } catch (Exception e) {
            //验证URL失败，错误原因请查看异常
            log.error("verifyGet error", e);
        }

    }

    //优量圈回调消息接口
    @PostMapping(value = "/ylq/verify")
    public String ylqVerifyPost(HttpServletRequest request) {
        try {
            // 微信加密签名
            String msg_signature = request.getParameter("msg_signature");
            // 时间戳
            String timestamp = request.getParameter("timestamp");
            // 随机数
            String nonce = request.getParameter("nonce");

            String id = WeComServerConstant.YLQ_CORP_ID;

            WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(WeComServerConstant.YLQ_TOKEN, WeComServerConstant.YLQ_ENCODING_AES_KEY, id);

            StringBuilder postData = new StringBuilder();   // 密文，对应POST请求的数据
            //1.获取加密的请求消息：使用输入流获得加密请求消息postData
            ServletInputStream in = request.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));

            String tempStr = "";   //作为输出字符串的临时串，用于判断是否读取完毕
            while (null != (tempStr = reader.readLine())) {
                postData.append(tempStr);
            }

            String suiteXml = wxcpt.DecryptMsg(msg_signature, timestamp, nonce, postData.toString());
            log.info("suiteXml: " + suiteXml);

            Map suiteMap = WxUtil.transferXmlToMap(suiteXml);
            log.info("suiteMap = {}", JSONObject.toJSONString(suiteMap));
            if (suiteMap != null) {
                String changeType = (String) suiteMap.get("ChangeType");
                if (StringUtils.isNotEmpty(changeType) && changeType.equals("add_external_contact")) {
                    String userId = (String) suiteMap.get("UserID");
                    String externalUserId = (String) suiteMap.get("ExternalUserID");
                    String welcomeCode = (String) suiteMap.get("WelcomeCode");
                    log.info("YLQ addStaffWithUser userId={} externalUserId={}", userId, externalUserId);
                    weComUserService.addStaffWithUser(externalUserId, userId, YLQ.getId());
                    weComAutoReply.AutoReplyMessage(welcomeCode, externalUserId, userId, YLQ.getId());
                }

                if (StringUtils.isNotEmpty(changeType) && changeType.equals("del_follow_user")) {
                    String userId = (String) suiteMap.get("UserID");
                    String externalUserId = (String) suiteMap.get("ExternalUserID");
                    log.info("YLQ delStaffWithUser userId={} externalUserId={}", userId, externalUserId);
                    weComUserService.delStaffWithUser(externalUserId, userId, YLQ.getId(), System.currentTimeMillis());
                }
            }
        } catch (Exception e) {
            log.error("verifyPost error", e);
        }
        String success = "success";
        return success;
    }

    //赛博成行验证接口
    @GetMapping("/sbcx/verify")
    public void sbcxVerifyGet(HttpServletRequest request, HttpServletResponse response) {
        try {
            // 微信加密签名
            String msgSignature = request.getParameter("msg_signature");
            // 时间戳
            String timestamp = request.getParameter("timestamp");
            // 随机数
            String nonce = request.getParameter("nonce");
            // 随机字符串
            // 如果是刷新，需返回原echostr
            String echoStr = request.getParameter("echostr");
            // 微信加密签名
            WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(WeComServerConstant.SBCX_TOKEN,
                    WeComServerConstant.SBCX_ENCODING_AES_KEY,
                    WeComServerConstant.SBCX_CORP_ID);

            String sEchoStr = ""; //需要返回的明文
            PrintWriter out;

            sEchoStr = wxcpt.VerifyURL(msgSignature, timestamp,
                    nonce, echoStr);
            log.info("verifyurl echostr: " + sEchoStr);

            // 验证URL成功，将sEchoStr返回
            out = response.getWriter();
            out.print(sEchoStr);
        } catch (Exception e) {
            //验证URL失败，错误原因请查看异常
            log.error("verifyGet error", e);
        }

    }

    //优量圈回调消息接口
    @PostMapping(value = "/sbcx/verify")
    public String sbcxVerifyPost(HttpServletRequest request) {
        try {
            // 微信加密签名
            String msg_signature = request.getParameter("msg_signature");
            // 时间戳
            String timestamp = request.getParameter("timestamp");
            // 随机数
            String nonce = request.getParameter("nonce");

            String id = WeComServerConstant.SBCX_CORP_ID;

            WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(WeComServerConstant.SBCX_TOKEN, WeComServerConstant.SBCX_ENCODING_AES_KEY, id);

            StringBuilder postData = new StringBuilder();   // 密文，对应POST请求的数据
            //1.获取加密的请求消息：使用输入流获得加密请求消息postData
            ServletInputStream in = request.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));

            String tempStr = "";   //作为输出字符串的临时串，用于判断是否读取完毕
            while (null != (tempStr = reader.readLine())) {
                postData.append(tempStr);
            }

            String suiteXml = wxcpt.DecryptMsg(msg_signature, timestamp, nonce, postData.toString());
            log.info("suiteXml: " + suiteXml);

            Map suiteMap = WxUtil.transferXmlToMap(suiteXml);
            log.info("suiteMap = {}", JSONObject.toJSONString(suiteMap));
            if (suiteMap != null) {
                String changeType = (String) suiteMap.get("ChangeType");
                if (StringUtils.isNotEmpty(changeType) && changeType.equals("add_external_contact")) {
                    String userId = (String) suiteMap.get("UserID");
                    String externalUserId = (String) suiteMap.get("ExternalUserID");
                    String welcomeCode = (String) suiteMap.get("WelcomeCode");
                    log.info("SBCX addStaffWithUser userId={} externalUserId={}", userId, externalUserId);
                    weComUserService.addStaffWithUser(externalUserId, userId, SBCX.getId());
                    weComAutoReply.AutoReplyMessage(welcomeCode, externalUserId, userId, SBCX.getId());
                }

                if (StringUtils.isNotEmpty(changeType) && changeType.equals("del_follow_user")) {
                    String userId = (String) suiteMap.get("UserID");
                    String externalUserId = (String) suiteMap.get("ExternalUserID");
                    log.info("SBCX delStaffWithUser userId={} externalUserId={}", userId, externalUserId);
                    weComUserService.delStaffWithUser(externalUserId, userId, SBCX.getId(), System.currentTimeMillis());
                }
            }
        } catch (Exception e) {
            log.error("verifyPost error", e);
        }
        String success = "success";
        return success;
    }


    @PostMapping("/send/post")
    public String sendPost(@RequestBody SendRequestParam sendRequestParam) throws IOException {
        log.info("sendPost sendRequestParam={}", sendRequestParam);
        String res = httpPoolClient.post(sendRequestParam.getUrl(), sendRequestParam.getParam());
        log.info("sendPost sendRequestParam={}, res={}", sendRequestParam, res);
        return res;
    }

    @GetMapping("/send/post/file")
    public String sendPostFile(@RequestParam String url, @RequestParam() String cover) throws IOException {
        byte[] decodedBytes = Base64.getDecoder().decode(url);
        String targetUrl = new String(decodedBytes);

        byte[] coverDecodedBytes = Base64.getDecoder().decode(cover);
        String targetCover = new String(coverDecodedBytes);

        log.info("sendPostFile url={},cover={}", targetUrl, targetCover);
        String filePath = UUID.randomUUID() + ".jpg"; // 临时文件路径
        HttpURLConnection httpUrl = (HttpURLConnection) new URL(targetCover).openConnection();
        httpUrl.connect();
        InputStream inputStream = httpUrl.getInputStream();

        // 将文件内容写入临时文件
        try (OutputStream outputStream = Files.newOutputStream(Paths.get(filePath))) {
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
        }
        inputStream.close();
        httpUrl.disconnect();
        File file = new File(filePath);
        String res = httpPoolClient.post(targetUrl, file);
        log.info("sendPostFile url={},cover={},res={}", targetUrl, targetCover, res);
        return res;
    }

    @GetMapping("/send/get")
    public String sendGet(@RequestParam String url) throws IOException {
        byte[] decodedBytes = Base64.getDecoder().decode(url);
        String originalString = new String(decodedBytes);
        log.info("sendGet url={}", originalString);
        String res = httpPoolClient.get(originalString);
        log.info("sendGet url={} res={}", originalString, res);
        return res;
    }
}
