package cn.teammodel.manager.wx;

//import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.hutool.json.JSONObject;
import cn.teammodel.model.vo.WechatResponseMsgVo;
import com.alibaba.fastjson2.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
//import com.rabbitmq.client.Channel;
//import com.rabbitmq.client.Connection;
//import com.rabbitmq.client.ConnectionFactory;
//import com.rabbitmq.client.DeliverCallback;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.*;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.*;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class WechatUtilService {

    /**
    *  模板:职业测试报告通知
    */
    public static final String TEMPLATE_Vocational = "tmMsJJSh3bVhbCh34x15pTqNwPXIL52mk7r64Z8BnZs";
    /**
     *  模板:评价完成通知
     */
    public static final String TEMPLATE_Appraise = "VQTP-d1mH7yrcFd6pKCdsy8LJpYrYrFcedEfxY0QpaU";
    /**
     *  模板:评价完成通知
     */
    public static final String TEMPLATE_Report = "fkQA1Lz3Qx0RYWhtomLCiiu6EWJCMFIznU8SN2C_kFM";
    /**
     *  模板:考核成绩发布通知
     */
    public static final String TEMPLATE_Eexam = "0U5YXarjYpMRLiKwgSlHO48iotjIeXOTDh2dyJwR-_8";

    private static final String APP_ID = "wx5705da8747c77cfe";
    private static final String APP_SECRET = "d5adf260a866ca43e74fbb40cec00799";
    private static final String TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + APP_ID + "&secret=" + APP_SECRET;
    /**
     *   给用户发送消息
     */
    private static final String SEND_MSG_URL = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=";


    private final static String QUEUE_NAME = "test_queue";
    /**
     * 获取微信用户唯一标识OpenID
     */
    private static final String CODE2SESSION_GET = "https://api.weixin.qq.com/sns/jscode2session?";

    /**
     * 获取访问令牌  方法1
     * 获取接口调用凭据
     * 方案 一
     * @return
     */
    public String GetAccessToken() {
        CloseableHttpClient client = HttpClients.createDefault();
        HttpPost post = new HttpPost(TOKEN_URL);
        String token = null;

        try {
            String result = EntityUtils.toString(client.execute(post).getEntity());
            // 从响应中解析JSON，获取access_token
            JSONObject jsonResponse = new JSONObject(result);
            if (jsonResponse.containsKey("access_token")) {
                token = jsonResponse.getStr("access_token");
            }
            client.close();
        } catch (Exception e) {
            log.error("处理获取access_token请求时发生错误", e);
        }
        return token; // 返回结果中包含access_token，需要解析出来使用
    }

    /**
     * description: 获取token，返回结果为 JSON 自行转 map
     * 方案 二
     * create by: Mr.Fang     *
     *
     * @return: java.lang.String
     * @date: 2023/4/3 17:46
     */
    public String GetToken() {
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        Map<String, Object> params = new HashMap<>();
        params.put("appid", APP_ID);
        params.put("secret", APP_SECRET);
        params.put("grant_type", "client_credential");

        String url = HandleParams("https://api.weixin.qq.com/cgi-bin/token", params);
        HttpGet httpGet = new HttpGet(url);
        String token = null;
        try {
            CloseableHttpResponse response = httpClient.execute(httpGet);
            HttpEntity entity = response.getEntity(); // 响应结果
            String content = EntityUtils.toString(entity, "UTF-8");
            // 从响应中解析JSON，获取access_token
            JSONObject jsonResponse = new JSONObject(content);
            if (jsonResponse.containsKey("access_token")) {
                token = jsonResponse.getStr("access_token");
            }
        } catch (IOException e) {
            log.error("处理获取token 请求时发生错误", e);
        }
        return token;
    }

    /**
     * description: 获取 open id，返回结果为 JSON 自行转 map
     * create by: Mr.Fang
     * 方案一
     * @param: [code]
     * @return: java.lang.String
     * @date: 2023/4/3 17:46
     */
    public String GetOpenId(String code){
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        Map<String, Object> params = new HashMap<>();
        params.put("appid", APP_ID);
        params.put("secret", APP_SECRET);
        params.put("js_code", code);
        params.put("grant_type", "authorization_code");

        String url = HandleParams("https://api.weixin.qq.com/sns/jscode2session", params);
        HttpGet httpGet = new HttpGet(url);
        String openId = null;
        try {
            CloseableHttpResponse response = httpClient.execute(httpGet);
            HttpEntity entity = response.getEntity(); // 响应结果
            openId =  EntityUtils.toString(entity, "UTF-8");
        }catch (IOException e) {
            log.error("处理获取开放id请求时发生错误", e);
        }
        return openId;
    }


    /**
     * 获取用户id
     * 方案二
     * @param code
     * @return
     */
    public String GetOpenId1(String code)   {
        String openId = null;
        try {
            String urlString = "https://api.weixin.qq.com/sns/jscode2session?appid=" + APP_ID +
                    "&secret=" + APP_SECRET +
                    "&js_code=" + code +
                    "&grant_type=authorization_code";
            URL url = new URL(urlString);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.connect();
            int responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) { // 200 OK
                BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8));
                String inputLine;
                StringBuilder response = new StringBuilder();
                while ((inputLine = in.readLine()) != null) {
                    response.append(inputLine);
                }
                in.close();
                // 解析JSON响应来获取openID等数据
                // 这里可以使用如org.json等库来解析JSON字符串
                // 例如：JSONObject jsonObject = new JSONObject(response.toString());
                // return jsonObject.getString("openid");
                JSONObject jsonObject = new JSONObject(response.toString());
                openId = jsonObject.getStr("openid");
            } else {
                System.out.println("GET请求失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return openId;
    }

    /**
     * 发送订阅消息
     * 处理微信推送数据结构
     * JSONObject mapData = new JSONObject();
     * Map<String, Object> map1 = new HashMap<>();
     * map1.put("value", "用户-PL");
     * mapData.put("name1", map1);
     * Map<String, Object> map2 = new HashMap<>();
     * map2.put("value", "2022-04-03 10:00:00");
     * mapData.put("time2", map2);
     * Map<String, Object> map3 = new HashMap<>();
     * map3.put("value", "测评名称-标准能力测评");
     * mapData.put("thing3", map3);
     * Map<String, Object> map4 = new HashMap<>();
     * map4.put("value", 88);
     * mapData.put("number4", map4);
     *
     * @param data
     * @return
     */
    public String PushMsg(String templateId,String openId,Map<String, Object> data,String page)  {
        String token = GetToken();
        try {
            CloseableHttpClient httpClient = HttpClientBuilder.create().build();
            Map<String, Object> params = new HashMap<>();
            params.put("template_id", templateId);// 模板 id
            params.put("touser", openId); // open id
            params.put("data", data); // 数据
            params.put("page", page); // 点击模板卡片后的跳转页面，仅限本小程序内的页面。支持带参数,（示例index?foo=bar）。该字段不填则模板无跳转
            params.put("miniprogram_state", "trial"); //developer为开发版；trial为体验版；formal为正式版；默认为正式版
            params.put("lang", "zh_CN"); //

            HttpPost httpPost = new HttpPost(SEND_MSG_URL + token);
            httpPost.addHeader("ContentTyp", "application/json");

            // 参数转 JSON 格式
            String json = objToStr(params);
            StringEntity stringEntity = new StringEntity(json,"UTF-8");
            stringEntity.setContentEncoding("UTF-8");
            httpPost.setEntity(stringEntity);

            CloseableHttpResponse response = httpClient.execute(httpPost);
            HttpEntity entity = response.getEntity(); // 响应结果
            return EntityUtils.toString(entity, "UTF-8");
        }catch (Exception e){
            log.error("处理获取openId请求时发生错误", e);
            return  e.getMessage();
        }
    }

    /**
     * 发送订阅消息  返回实体类
     * @param templateId
     * @param openId
     * @param data
     * @param page
     * @return
     */
    public WechatResponseMsgVo PushMsgResponse(String templateId, String openId, Map<String, Object> data, String page)  {
        String token = GetToken();
        WechatResponseMsgVo wechatResponseMsgVo = null;
        try {
            CloseableHttpClient httpClient = HttpClientBuilder.create().build();
            Map<String, Object> params = new HashMap<>();
            params.put("template_id", templateId);// 模板 id
            params.put("touser", openId); // open id
            params.put("data", data); // 数据
            params.put("page", page); // 点击模板卡片后的跳转页面，仅限本小程序内的页面。支持带参数,（示例index?foo=bar）。该字段不填则模板无跳转
            params.put("miniprogram_state", "trial"); //developer为开发版；trial为体验版；formal为正式版；默认为正式版
            params.put("lang", "zh_CN"); //

            HttpPost httpPost = new HttpPost(SEND_MSG_URL + token);
            httpPost.addHeader("ContentTyp", "application/json");

            // 参数转 JSON 格式
            String json = objToStr(params);
            StringEntity stringEntity = new StringEntity(json,"UTF-8");
            stringEntity.setContentEncoding("UTF-8");
            httpPost.setEntity(stringEntity);

            CloseableHttpResponse response = httpClient.execute(httpPost);
            HttpEntity entity = response.getEntity(); // 响应结果
            wechatResponseMsgVo = JSON.parseObject(EntityUtils.toString(response.getEntity(), "UTF-8"), WechatResponseMsgVo.class);
        }catch (Exception e){
            log.error("处理获取openId请求时发生错误", e);
            wechatResponseMsgVo = new WechatResponseMsgVo(500, e.getMessage());
        }
        return  wechatResponseMsgVo;
    }





























//    /**
//     * 列队发送消息
//     *
//     * @param code
//     * @return
//     */
//    public String MessageSend(String code) {
//        ConnectionFactory factory = new ConnectionFactory();
//        factory.setHost("localhost");
//
//        try (Connection connection = factory.newConnection();
//             Channel channel = connection.createChannel()) {
//            channel.queueDeclare(QUEUE_NAME, false, false, false, null);
//            System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
//
//            DeliverCallback deliverCallback = (consumerTag, delivery) -> {
//                String message = new String(delivery.getBody(), "UTF-8");
//                System.out.println(" [x] Received '" + message + "'");
//            };
//            channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> {
//            });
//        } catch (Exception e) {
//            throw new RuntimeException(e);
//        }
//        return null;
//    }


//    /**
//     * description 1.获取用户的临时code
//     * param [appid, redirectUrl]
//     * return java.lang.String
//     * authorlgb
//     * createTime 2021/8/27 17:30
//     **/
//    public String getUserUathUrl(String redirectUrl) throws UnsupportedEncodingException {
//        StringBuffer getcodeUrl = new StringBuffer()
//                .append("https://open.weixin.qq.com/connect/oauth2/authorize")
//                .append("?appid=" + APP_ID)
//                .append("&redirect_uri=" + com.sun.deploy.net.URLEncoder.encode(redirectUrl, "utf-8"))
//                .append("&response_type=code")
//                .append("&scope=snsapi_userinfo")
//                .append("&state=" + System.currentTimeMillis())
//                .append("#wechat_redirect");
//
//        return getcodeUrl.toString();
//    }

    /**
     * description  3.根据openid 获取用户的信息
     * param [accessToken, openid]
     * return java.lang.String
     * author
     * createTime 2021/8/27 17:31
     **/
    public String getBaseUserInfoUrl(String openid) {
        StringBuffer baseUserInfoUrl = new StringBuffer()
                .append("https://api.weixin.qq.com/sns/userinfo")
                .append("?access_token=" + GetAccessToken())
                .append("&openid=" + openid)
                .append("&lang=zh_CN");
        return baseUserInfoUrl.toString();
    }

    /**
     * description 4检验授权凭证（access_token）是否有效
     * param [openid, accessToken]
     * return java.lang.String
     * author
     * createTime 2021/11/29 10:16
     **/
    public String checkAccessToken(String openid, String accessToken) {
        StringBuffer stringBuffer = new StringBuffer().append(" https://api.weixin.qq.com/sns/auth")
                .append("?access_token=" + accessToken)
                .append("&openid=" + openid);
        return stringBuffer.toString();
    }

    /**
     * description 微信小程序登录，通过code获取session_key和openid
     * param [appid, secret, code]
     * return java.lang.String
     * author
     * createTime 2021/8/30 10:15
     **/
    public String getCode2Session(String code) {
        StringBuffer code2Session = new StringBuffer()
                .append("ttps://api.weixin.qq.com/sns/jscode2session")
                .append("?appid=" + APP_ID)
                .append("&secret=" + APP_SECRET)
                .append("&js_code=" + code)
                .append("&grant_type=authorization_code");
        return code2Session.toString();
    }

    /**
     * description: map 转 URL 地址拼接
     * create by: Mr.Fang
     *
     * @param: [url, params]
     * @return: java.lang.String
     * @date: 2023/4/3 17:45
     */
    public String HandleParams(String url, Map<String, Object> params) {
        if (params.size() != 0) {
            Set<Map.Entry<String, Object>> entries = params.entrySet();
            String paramsString = entries.stream().map((e) -> {
                try {
                    StringBuilder sb = new StringBuilder();
                    sb.append(URLEncoder.encode(e.getKey(), "UTF-8"));
                    sb.append("=");
                    if (Objects.nonNull(e.getValue())) {
                        sb.append(URLEncoder.encode(e.getValue().toString(), "UTF-8"));
                    }

                    return sb.toString();
                } catch (UnsupportedEncodingException var2) {
                    var2.printStackTrace();
                    return null;
                }
            }).collect(Collectors.joining("&"));
            return url + "?" + paramsString;
        }
        return url;
    }
    /**
     * description: 对象转 字符串
     * create by: Mr.Fang
     *
     * @param: [obj]
     * @return: java.lang.String
     * @date: 2023/4/3 17:45
     */
    public String objToStr(Object obj) {

        ObjectMapper objectMapper = new ObjectMapper();
        if (Objects.nonNull(obj)) {
            try {
                String jsonStr = objectMapper.writeValueAsString(obj);
                return jsonStr;
            } catch (JsonProcessingException var2) {
                var2.printStackTrace();
            }
        }

        return null;
    }
}
