package com.ruoyi.common.weiXin;

import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ImgUpload;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.common.weiXin.domain.WxMessageDto;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.io.BufferedInputStream;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;

import static java.util.concurrent.TimeUnit.SECONDS;

/**
 * 微信授权工具类
 */
@Component
public class WeiXinUtils {

    //日志
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private RedisCache redisCache;

    /**
     * 获取openid与session_key
     * @param code
     * @return
     */
    public JSONObject getWebAuthorizeInfo(String code){
        try {
            String url = "https://api.weixin.qq.com/sns/jscode2session?" +
                    "appid=" + WeiXinParamConfig.APP_ID + "&" +
                    "secret=" + WeiXinParamConfig.APP_SECRET + "&" +
                    "js_code=" + code + "&" +
                    "grant_type=authorization_code";
            String result = HttpUtils.sendGet(url);

            return JSONUtil.parseObj(result);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     *获取access_token
     */
    public String getToken(){
        JSONObject jsonObject = new JSONObject();
        String access_token = "";
        Integer expires_in = 0;//有效期
        try {
            if (redisCache.hasKey("xcx:access_token")){
                return redisCache.getCacheObject("xcx:access_token").toString();
            }
            String url = "https://api.weixin.qq.com/cgi-bin/token";
            String result = HttpUtils.sendGet(url,"grant_type=client_credential&" +
                    "appid="+WeiXinParamConfig.APP_ID+"&" +
                    "secret="+WeiXinParamConfig.APP_SECRET);
            jsonObject = JSONUtil.parseObj(result);
            if (ObjectUtils.isNotEmpty(jsonObject)){
                access_token = jsonObject.getStr("access_token");
                expires_in = jsonObject.getInt("expires_in");
            }
            redisCache.setCacheObject("xcx:access_token", access_token, expires_in, SECONDS);

            return access_token;
        }catch (Exception e){
            e.printStackTrace();
            return access_token;
        }
    }
    /**
     * 测试本地 获取接口调用凭证
     * @return
     */
    private String postTypeForAccessToken(){
        String requestUrl = "https://api.weixin.qq.com/cgi-bin/stable_token";
        cn.hutool.json.JSONObject body = JSONUtil.createObj();
        body.put("grant_type","client_credential");
        body.put("appid", WeiXinParamConfig.APP_ID);
        body.put("secret", WeiXinParamConfig.APP_SECRET);
        body.put("force_refresh",true);
        String result = HttpUtil.post(requestUrl,body.toString());
        logger.info("{} 小程序获取access_token结果 -> {}", DateUtils.getTime(), result);
        return result;
    }


    /** 连接超时时间，默认10秒 */
    private  static int socketTimeout = 10000;
    // 传输超时时间，默认30秒
    private  static int connectTimeout = 30000;

    /**
     * 小程序订阅消息发送
     * @param templateId 模板id
     * @param openId 接收者（用户）的 openid
     * @param data 模板内容
     * @param page 跳转页面
     * @return
     */
    public int sendSubscribeMessage(String templateId, String openId, Map<String, Object> data, String page){
        RestTemplate restTemplate = new RestTemplate();
        //这里简单起见我们每次都获取最新的access_token（应该在access_token快过期时再重新获取）
        String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + this.getToken();
        //拼接推送的模版
        WxMessageDto weiXinMessageDto = new WxMessageDto();
        // 所需下发的订阅模板id
        weiXinMessageDto.setTemplate_id(templateId);
        // 点击模板卡片后的跳转页面
        if (StringUtils.isNotBlank(page)){
            weiXinMessageDto.setPage(page);
        }
        // 接收者（用户）的 openid
        weiXinMessageDto.setTouser(openId);
        // 模板内容
        weiXinMessageDto.setData(data);
        weiXinMessageDto.setMiniprogram_state("formal");

        System.out.println("========发送订阅消息内容====" + weiXinMessageDto.toString());
        ResponseEntity<String> responseEntity =
                restTemplate.postForEntity(url, weiXinMessageDto, String.class);
        String body = responseEntity.getBody();
        logger.error("推送消息返回结果:" + body);
        com.alibaba.fastjson.JSONObject jsonObject = com.alibaba.fastjson.JSONObject.parseObject(body);
        if (ObjectUtils.isNotEmpty(jsonObject)){
            String errcode = jsonObject.getString("errcode");
            if (errcode.equals("0")){
                return  0;
            }

        }
        return  1;
    }

    /**
     *  小程序录入发货信息
     * @param paySn 支付单号(订单号)
     * @param openId 支付人openid
     * @return 结果
     */
    public String deliveryInfo(String paySn, String openId){
        try {
            //获取token
            String accessToken = this.getToken();
            String url = "https://api.weixin.qq.com/wxa/sec/order/upload_shipping_info?access_token=" + accessToken;

            // post参数
            JSONObject jsonObject = new JSONObject();
            HashMap<Object, Object> orderKey = new HashMap<>();
            orderKey.put("order_number_type" , 1);  // 1.使用下单商户号和商户侧单号；枚举值2.使用微信支付单号
            orderKey.put("mchid", "1671247339"); // 商户号
            orderKey.put("out_trade_no", paySn);  // 内部订单支付单号
            jsonObject.put("order_key", orderKey);
            jsonObject.put("logistics_type", 2); // 1.物流配送,2.同城配送,3.虚拟商品,4.用户自提
            jsonObject.put("delivery_mode", 1); // 1.同意发货,2.分拆发货
             List<Map<String, Object>> shippingList = new ArrayList<>();
            // 物流信息
             Map<String, Object> shipping = new HashMap<>();
            // shipping.put("tracking_no", expressCode ); // 物流单号
            // shipping.put("express_company", companyCode);  // 物流公司编码
             shipping.put("item_desc", "商品配送中");  // 商品信息描述
             shippingList.add(shipping);
            // HashMap<Object, Object> contact = new HashMap<>();
            // //contact.put("consignor_contact"); // 寄件人电话
            // contact.put("receiver_contact", receivePhone );  // 收件人电话
            // shipping.put("contact", contact );
             jsonObject.put("shipping_list", shippingList);

            jsonObject.put("upload_time", DateUtil.format(DateUtils.getNowDate(), "yyyy-MM-dd'T'HH:mm:ss.SSS'+08:00'"));

            HashMap<Object, Object> payer = new HashMap<>();
            payer.put("openid", openId);
            jsonObject.put("payer", payer);

            // 结果
            String res = HttpUtil.createPost(url).
                    body(jsonObject.toString()).execute().body();
            com.alibaba.fastjson.JSONObject result = com.alibaba.fastjson.JSONObject.parseObject(res);
            logger.info("小程序发货信息录入结果: {}", res);
            if ("0".equals(result.getString("errcode"))){
                return "SUCCESS";
            }else{
                return "FAIL";
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return  "FAIL";
    }

    /**
     * 获取业务员小程序码
     *
     * @param salesmanId 业务员ID
     * @param key key
     * @return 图片链接
     */
    public String getQRCode(String salesmanId, String key){
        String qrCodeUrl = "";
        try {
            //获取token
            String accessToken = this.getToken();
            String codeUrl = "https://api.weixin.qq.com/wxa/getwxacode?access_token="+ accessToken;
            String path = WeiXinParamConfig.SALESMAN_BINDING_PATH+salesmanId;
            //post参数
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("path", path);

            Map<String, Object> lineColor = new HashMap<>();
            lineColor.put("r", 4);
            lineColor.put("g", 157);
            lineColor.put("b", 150);
            jsonObject.put("line_color", lineColor);
            jsonObject.put("env_version", "release");// 正式版为 "release"，体验版为 "trial"，开发版为 "develop"
            String params = jsonObject.toString();

            URL url = new URL(codeUrl);
            HttpURLConnection httpUrlConnection = (HttpURLConnection) url.openConnection();
            // 提交模式
            httpUrlConnection.setRequestMethod("POST");
            // 发送POST请求必须设置如下两行
            httpUrlConnection.setDoOutput(true);
            httpUrlConnection.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            PrintWriter printWriter = new PrintWriter(httpUrlConnection.getOutputStream());
            printWriter.write(params);
            printWriter.flush();
            //获取数据
            BufferedInputStream bis = new BufferedInputStream(httpUrlConnection.getInputStream());
            //文件上传,返回小程序码url

            qrCodeUrl = new ImgUpload().upload(bis,
                    key);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return qrCodeUrl;
    }
}
