package com.hai.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hai.common.exception.ErrorCode;
import com.hai.common.exception.ErrorHelp;
import com.hai.common.exception.SysCode;
import com.hai.common.utils.HttpsUtils;
import com.hai.common.utils.MD5Util;
import com.hai.common.utils.RedisUtil;
import com.hai.dao.HighGasOrderPushMapper;
import com.hai.entity.HighCouponCodeOther;
import com.hai.entity.HighGasOrderPush;
import com.hai.entity.HighUserCoupon;
import com.hai.enum_type.OrderPushType;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.annotation.Resource;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.*;

/**
 * @author hurui
 * @version 1.0
 * @ClassName QianZhuConfig
 * @description: 汇联通接口配置
 * @date 2021/7/5 14:18
 */
@Component
public class HuiLianTongConfig {

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private HighGasOrderPushMapper highGasOrderPushMapper;

    /**
     * 获取电子券类型列表
     * @return
     * @throws Exception
     */
    public static JSONObject getHltFuelCoupList() throws Exception {
        Map<String,Object> map = new HashMap<>();
        map.put("serviceType", "01");
        map.put("distributorId", CommonSysConst.getSysConfig().getHuiliantongDistributorId());
        return HuiLianTongUnionCardConfig.request(CommonSysConst.getSysConfig().getHuiliantongSinopecUrl() + "/getHltFuelCoupList", map);
    }

    /**
     * 下单购买加油券
     * @param orderNo
     * @param distCouCount
     * @param couTypeCode
     * @param phone
     * @return
     * @throws Exception
     */
    public static JSONObject recharge(String orderNo, Integer distCouCount, String couTypeCode, String phone) throws Exception {
        Map<String,Object> map = new HashMap<>();
        map.put("orderNo", orderNo);
        map.put("distCouCount", distCouCount);
        map.put("couTypeCode", couTypeCode);
        map.put("phone", phone);
        map.put("distributorId", CommonSysConst.getSysConfig().getHuiliantongDistributorId());
        return HuiLianTongUnionCardConfig.request(CommonSysConst.getSysConfig().getHuiliantongSinopecUrl()+"/recharge", map);
    }

    /**
     * 购买加油券充值订单
     * @param couNo  订单号
     * @return
     * @throws Exception
     */
    public static JSONObject getPayOrderByCouNo(String couNo) throws Exception {
        Map<String,Object> map = new HashMap<>();
        map.put("couNo", couNo);
        map.put("distributorId", CommonSysConst.getSysConfig().getHuiliantongDistributorId());
        return HuiLianTongUnionCardConfig.request(CommonSysConst.getSysConfig().getHuiliantongSinopecUrl()+"/getPayOrderByCouNo", map);
    }

    /**
     * 购买加油券充值订单
     * @param rechargeOrderId  订单号
     * @return
     * @throws Exception
     */
    public static JSONObject costRechargeOrder(String rechargeOrderId) throws Exception {
        Map<String,Object> map = new HashMap<>();
        map.put("rechargeOrderId", rechargeOrderId);
        map.put("distributorId", CommonSysConst.getSysConfig().getHuiliantongDistributorId());
        return HuiLianTongUnionCardConfig.request(CommonSysConst.getSysConfig().getHuiliantongSinopecUrl()+"/costRechargeOrder", map);
    }

    /**
     * 获取token
     * @return
     * @throws Exception
     */
    public String getToken() throws Exception {
        Object token = redisUtil.get(CommonSysConst.getSysConfig().getHuiliantongAppNo());
        if (token != null) {
            return token.toString();
        }

        Map<String,Object> map = new HashMap<>();
        map.put("appNo",CommonSysConst.getSysConfig().getHuiliantongAppNo());
        map.put("appKey", MD5Util.encode(CommonSysConst.getSysConfig().getHuiliantongAppkey().getBytes()));

        // 获取token
        JSONObject tokenObject = HttpsUtils.doPost(CommonSysConst.getSysConfig().getHuiliantongUrl()+"/api/api/auth/getAccessToken", JSON.toJSONString(map));
        if (tokenObject.getString("result").equals("success")) {
            // 缓存到redis  有效期30分钟
            redisUtil.set(CommonSysConst.getSysConfig().getHuiliantongAppNo(),tokenObject.getString("data"),60*30);
            return tokenObject.getString("data");
        }

        throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "获取token失败");
    }

    /**
     * 获取电子券类型列表
     * @param token
     * @return
     * @throws Exception
     */
    public static JSONObject getCorpCouTypes(String token) {
        Map<String,Object> param = new HashMap<>();
        Map<String,Object> map = new HashMap<>();
        map.put("token", token);
       /* map.put("jsonData", get3DESEncryptECB(JSON.toJSONString(param), CommonSysConst.getSysConfig().getHuiliantongAppsecret()));
        StringJoiner urlParamStr = new StringJoiner("&");
        urlParamStr.add(String.format("jsonData=%s", param));
        urlParamStr.add(String.format("secretKey=%s",CommonSysConst.getSysConfig().getHuiliantongAppsecret()));
        map.put("sign", md5Capital(urlParamStr.toString()));*/
        return HttpsUtils.doPost(CommonSysConst.getSysConfig().getHuiliantongUrl()+"/coupon/api/coupon_corp/getCorpCouTypes", JSON.toJSONString(map));
    }

    /**
     * 获取电子券类型列表
     * @param token
     * @return
     * @throws Exception
     */
    public static JSONObject getCouState(String token,String couNo) {
        Map<String,Object> map = new HashMap<>();
        map.put("token", token);
        map.put("couNo", couNo);
        return HttpsUtils.doPost(CommonSysConst.getSysConfig().getHuiliantongUrl()+"/coupon/api/coupon_corp/getCouState", JSON.toJSONString(map));
    }


    /**
     * 商户派发电子券
     * @param token
     * @param couTypeCode 电子卡券类型
     * @param distCouCount 分配数量
     * @param userPhone    用户手机号
     * @param thirdUserId  用户编号
     * @return
     * @throws Exception
     */
    public static JSONObject couJointDist(String token,String orderNo,String couTypeCode,Integer distCouCount,String userPhone,String thirdUserId) throws Exception {
        // 券列表
        List<Map<String,Object>> objectList = new ArrayList<>();
        Map<String,Object> object = new HashMap<>();
        object.put("couTypeCode", couTypeCode);
        object.put("distCouCount", distCouCount);
        objectList.add(object);
        // 参数
        Map<String,Object> param = new HashMap<>();
        param.put("coupons", objectList);
        param.put("phone", userPhone);
        param.put("thirdUserId", thirdUserId);
        param.put("orderNo", orderNo);
        param.put("distOuCode", "guizhouhltcs");

        Map<String,Object> map = new HashMap<>();
        map.put("token", token);
        map.put("jsonData", get3DESEncryptECB(JSON.toJSONString(param), CommonSysConst.getSysConfig().getHuiliantongAppkey()));
        StringJoiner joiner = new StringJoiner("&");
        joiner.add("jsonData=" + JSON.toJSONString(param));
        joiner.add("secretKey=" + CommonSysConst.getSysConfig().getHuiliantongAppsecret());
        map.put("sign", md5Capital(joiner.toString()));

        String paramStr = "token="+MapUtils.getString(map, "token")+"&sign=" + MapUtils.getString(map, "sign")+"&jsonData=" + URLEncoder.encode(MapUtils.getString(map, "jsonData"),"UTF-8");
        JSONObject object1 = HttpsUtils.doHuiLianTongPost(CommonSysConst.getSysConfig().getHuiliantongUrl() + "/coupon/api/coupon_corp/couJointDist?" + paramStr);

        new Thread(() -> {
            try {
                if (object1 != null && object1.getString("result").equals("success")) {
                    JSONArray dataArray = object1.getJSONArray("data");
                    for (Object data : dataArray) {
                        JSONObject dataObject = (JSONObject) data;
                        Map<String, Object> mapPost = new HashMap<>();
                        mapPost.put("orderNo" , orderNo);
                        mapPost.put("distCouCount" , "1");
                        mapPost.put("phone" , userPhone);
                        mapPost.put("distributorId" , "1JnL8YMV");
                        mapPost.put("couNo" , dataObject.getString("couNo"));
                        mapPost.put("status" , "20");
                        mapPost.put("couTypeCode" , dataObject.getString("couTypeCode"));
                        mapPost.put("validStartDate" , dataObject.getString("validStartDate"));
                        mapPost.put("validEndDate" , dataObject.getString("validEndDate"));
                        JSONObject o = HuiLianTongUnionCardConfig.syncPayOrder(mapPost);
                        System.out.println("订单同步请求参数---------" + mapPost);
                        System.out.println("订单同步请求结果---------" + o);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();

        return  object1;
    }

    /**
     * 商户派发电子券
     * @return
     * @throws Exception
     */
    public static JSONObject test (JSONObject object1) throws Exception {

        new Thread(() -> {
            try {
                if (object1 != null && object1.getString("result").equals("success")) {
                    JSONArray dataArray = object1.getJSONArray("data");
                    for (Object data : dataArray) {
                        JSONObject dataObject = (JSONObject) data;
                        Map<String, Object> mapPost = new HashMap<>();
                        mapPost.put("orderNo" , "HF2022080308340632509");
                        mapPost.put("distCouCount" , "1");
                        mapPost.put("phone" , "18096074536");
                        mapPost.put("distributorId" , "1JnL8YMV");
                        mapPost.put("couNo" , dataObject.getString("couNo"));
                        mapPost.put("status" , "20");
                        mapPost.put("couTypeCode" , dataObject.getString("couTypeCode"));
                        mapPost.put("validStartDate" , dataObject.getString("validStartDate"));
                        mapPost.put("validEndDate" , dataObject.getString("validEndDate"));
                        JSONObject o = HuiLianTongUnionCardConfig.syncPayOrder(mapPost);
                        System.out.println("订单同步请求参数---------" + mapPost);
                        System.out.println("订单同步请求结果---------" + o);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();

        return  object1;
    }


    public static String get3DESEncryptECB(String src,String secretKey) {
        try {
            Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(build3DesKey(secretKey), "DESede"));
            String base64Encode = getBase64Encode(cipher.doFinal(src.getBytes("UTF-8")));
            return filter(base64Encode);
        } catch (Exception ex) {
            //加密失败，打日志
//       //logger.error(ex,ex);
        }
        return null;
    }

    public static String get3DESDecryptECB(String src,String secretKey){
        try {
            Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(build3DesKey(secretKey), "DESede"));
            byte[] base64DValue = getBase64Decode(src);
            byte ciphertext[] = cipher.doFinal(base64DValue);
            return new String(ciphertext, "UTF-8");
        } catch (Exception e) {
            //解密失败，打日志
//       //logger.error(e,e);
        }
        return null;
    }

    /*
     * 根据字符串生成密钥字节数组
     * @param keyStr 密钥字符串
     * @return
     * @throws UnsupportedEncodingException
     */
    public static byte[] build3DesKey(String keyStr) throws UnsupportedEncodingException {
        byte[] key = new byte[24];    //声明一个24位的字节数组，默认里面都是0
        byte[] temp = keyStr.getBytes("UTF-8");    //将字符串转成字节数组

        /*
         * 执行数组拷贝
         * System.arraycopy(源数组，从源数组哪里开始拷贝，目标数组，拷贝多少位)
         */
        if(key.length > temp.length){
            //如果temp不够24位，则拷贝temp数组整个长度的内容到key数组中
            System.arraycopy(temp, 0, key, 0, temp.length);
        }else{
            //如果temp大于24位，则拷贝temp数组24个长度的内容到key数组中
            System.arraycopy(temp, 0, key, 0, key.length);
        }
        return key;
    }
    /**
     * 对字符串进行Base64编码
     *
     *
     * @return String 进行编码后的字符串
     */

    public static String getBase64Encode(byte[] src) {
        String requestValue = "";
        try {
            BASE64Encoder base64en = new BASE64Encoder();
            requestValue = filter(base64en.encode(src));
            // //logger.debug(requestValue);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return requestValue;
    }

    public static byte[] getBase64Decode(String str) {
        byte[] src = null;

        try {
            BASE64Decoder base64de = new BASE64Decoder();
            src = base64de.decodeBuffer(str);
        } catch (Exception var3) {
            var3.printStackTrace();
        }

        return src;
    }

    private static String filter(String str) {
        String output = null;
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < str.length(); i++) {
            int asc = str.charAt(i);
            if (asc != 10 && asc != 13)
                sb.append(str.subSequence(i, i + 1));
        }
        output = new String(sb);
        return output;
    }

    /**
     * 大写
     * @param s
     * @return
     */
    public static String md5Capital(String s){
        char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
        try {
            byte[] strTemp = s.getBytes();
            //使用MD5创建MessageDigest对象
            MessageDigest mdTemp = MessageDigest.getInstance("MD5");
            mdTemp.update(strTemp);
            byte[] md = mdTemp.digest();
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte b = md[i];
                ////logger.debug((int)b);
                //将没个数(int)b进行双字节加密
                str[k++] = hexDigits[b >> 4 & 0xf];
                str[k++] = hexDigits[b & 0xf];
            }
            return new String(str);
        } catch (Exception e) {return null;}
    }
/*
    测试实例：
    String appkey = "q[*^%]#%675f";
    String param = "{\"phone\":\"18550231381\"}";
    String secretKey = "7EFD6D5D7052E29B4FBC4AD75CA737ED";
    String jsonData = Coder.get3DESEncryptECB(param, appkey);
System.out.println("jsonData:" + jsonData);

    StringJoiner joiner = new StringJoiner("&");
joiner.add("jsonData=" + param);
joiner.add("secretKey=" + secretKey);
    String sign = Coder.md5Capital(joiner.toString());
System.out.println("sign:" + sign);

    jsonData:aOF3MZAENbJE/t+r4P0+RQGfhSEa5Hyq
    sign:835A267FCA8D36C6F79E308F18AECEE8*/
}
