package com.xhpc.order.intella;

import cn.hutool.core.date.DateUtil;
import co.intella.crypto.AesCryptoUtil;
import co.intella.crypto.KeyReader;
import co.intella.crypto.RsaCryptoUtil;
import co.intella.model.IntegratedRequestBody;
import co.intella.model.RequestHeader;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import org.testng.annotations.Test;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.SecretKey;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;

import static co.intella.net.HttpRequestUtil.getEncryptRequestJson;


public class IntellaTest {

    final static int publicKeyResId = 1;//R.raw.stage_pub;
    final static String ServiceType = "Payment";//credit card "OLPay";//消費者主掃
    final static String API_URL = "https://a.intella.co/allpaypass/api/general";   // for test server
    final static String Method = "20000";//信用卡
    final static String MchId = "SLGtest";   // your MchId (login account)
    final static String RefundKey = "13b7994fae9387c2e1b598524ba1204ae404d02fa67016ed86c74183ab1aabcd";    // SHA256 encoded
    final static String DeviceId = "01300123"; // for EasyCard API
    final static String DeviceInfo = "skb0001";


    public static String SHA256(String data) throws NoSuchAlgorithmException {
        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        byte[] encodedhash = digest.digest(data.getBytes(StandardCharsets.UTF_8));
        return bytesToHex(encodedhash);
    }

    private static String bytesToHex(byte[] hash) {
        StringBuilder hexString = new StringBuilder(2 * hash.length);
        for (int i = 0; i < hash.length; i++) {
            String hex = Integer.toHexString(0xff & hash[i]);
            if(hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex);
        }
        return hexString.toString();
    }


    final static String orderNo = "20222061515350342327";
    final static String fee = "1";

    @Test
    public void paymentTest() throws Exception {

        File der = new File("D:\\intella\\pub.der");
        InputStream is = new FileInputStream(der);
        Map<String, String> rm = new HashMap<>();
        rm.put("MchId", MchId);
        rm.put("Method", Method);
        rm.put("ServiceType", ServiceType);
        String TradeKey = SHA256("0000").toLowerCase(Locale.ROOT);     // SHA256 encoded
        rm.put("TradeKey", TradeKey);
        Date date = Calendar.getInstance().getTime();
        String format = DateUtil.format(date, "yyyyMMddHHmmss");
        rm.put("CreateTime", format);
        rm.put("DeviceInfo", DeviceInfo);
        rm.put("StoreOrderNo", orderNo);
        rm.put("Body","ChargingFee");
        rm.put("TotalFee", fee);
        rm.put("CardId","4477578739678291");
        rm.put("ExtenNo","879");
        rm.put("ExpireDate","2703");
//        rm.put("Data", "{\"DeviceInfo\":\"skb0001\",\"StoreOrderNo\":\"PO-20180715-001\",\"Body\":\"Chicken Rice\",\"TotalFee\":\"1\"}");//消費者主掃
        PublicKey rsaPubKey = KeyReader.loadPublicKeyFromDER(der);
        SecretKey aesKey = AesCryptoUtil.generateSecreteKey();
        System.out.println(getEncryptRequestJson(rm, rsaPubKey, aesKey));
        String rawJson = (new Gson()).toJson(rm);
        RequestHeader header = (RequestHeader)(new Gson()).fromJson(rawJson, RequestHeader.class);
        Map<String, String> dataMap = new HashMap();
        ArrayList<String> ignoreList = new ArrayList<String>() {
            {
                this.add("Method");
                this.add("ServiceType");
                this.add("MchId");
                this.add("CreateTime");
                this.add("TradeKey");
            }
        };
        Iterator var10 = rm.keySet().iterator();

        String key;
        while(var10.hasNext()) {
            key = (String)var10.next();
            if (!ignoreList.contains(key)) {
                dataMap.put(key, rm.get(key));
            }
        }
        IntegratedRequestBody body = new IntegratedRequestBody();
        body.setRequestData((new Gson()).toJson(dataMap));
        body.setRequestHeader(header);
        String json = (new Gson()).toJson(body);
        System.out.println(json);
        System.out.println("--");
        String resp = Utility.doRequest(API_URL, is, rm);
        System.out.println(resp);
        System.out.println("--");
    }



    @Test
    private void refundTest() throws Exception {
        File der = new File("D:\\intella\\pub.der");
        InputStream is = new FileInputStream(der);
        Map<String, String> rm = new HashMap<>();
        rm.put("MchId", MchId);
        rm.put("Method", "00000");
        rm.put("ServiceType", "Refund");
        String TradeKey = SHA256("0000").toLowerCase(Locale.ROOT);     // SHA256 encoded
        rm.put("TradeKey", TradeKey);
        Date date = Calendar.getInstance().getTime();
        String format = DateUtil.format(date, "yyyyMMddHHmmss");
        rm.put("CreateTime", format);
        rm.put("DeviceInfo", DeviceInfo);
        rm.put("StoreOrderNo", orderNo);

        rm.put("StoreRefundNo", "RF202206151441003712");        // 长度必须20位
        rm.put("RefundKey", TradeKey.toLowerCase(Locale.ROOT));
        rm.put("RefundFee", fee);
        rm.put("RefundedMsg", "退费");
//        rm.put("Data", "{\"DeviceInfo\":\"skb0001\",\"StoreOrderNo\":\"PO-20180715-001\",\"Body\":\"Chicken Rice\",\"TotalFee\":\"1\"}");//消費者主掃
        PublicKey rsaPubKey = KeyReader.loadPublicKeyFromDER(der);
        SecretKey aesKey = AesCryptoUtil.generateSecreteKey();
        System.out.println(getEncryptRequestJson(rm, rsaPubKey, aesKey));
        String rawJson = (new Gson()).toJson(rm);
        RequestHeader header = (RequestHeader)(new Gson()).fromJson(rawJson, RequestHeader.class);
        Map<String, String> dataMap = new HashMap();
        ArrayList<String> ignoreList = new ArrayList<String>() {
            {
                this.add("Method");
                this.add("ServiceType");
                this.add("MchId");
                this.add("CreateTime");
                this.add("TradeKey");
            }
        };
        Iterator var10 = rm.keySet().iterator();

        String key;
        while(var10.hasNext()) {
            key = (String)var10.next();
            if (!ignoreList.contains(key)) {
                dataMap.put(key, rm.get(key));
            }
        }
        IntegratedRequestBody body = new IntegratedRequestBody();
        body.setRequestData((new Gson()).toJson(dataMap));
        body.setRequestHeader(header);
        String json = (new Gson()).toJson(body);
        System.out.println(json);
        System.out.println("--");
        String resp = Utility.doRequest(API_URL, is, rm);
        System.out.println(resp);
        System.out.println("--");
    }


    @Test
    private void check() throws Exception {
        String resp = "{\"MchId\":\"SLGtest\",\"MethodName\":\"支付寶(上海)\",\"Result\":\"0000\",\"StoreOrderNo\":\"99M5O22062800001\",\"TotalFee\":\"1\",\"Sign\":\"svfaNrblrL6MdoqdjLiNZTgYjC7C1WO1IKZAexvBwV0JzJvyFq5+gJ4ysZtvlopsQX0YSC1wFtWVW+jwzd0ltCBrmN/k/+VOOA5i1qdJZ3fGzCGaGto2TliVFhYuZrXLj3xA/z/kggCqQ5drsZu6Y4ss5AkRrsdpNAuX6EXjhIuwHVXz9j/TBKxLIHJG++DuhJiIyJf1osKsGU+YUsl9Ejf3mXmKXqPQomhyJNiBf6bOfK6ZObT1jwKVXfbKmcGDzRf9HSwuwRvJAaCQu+BVN7sc2O8Su5vsWVv/Ms6n1Uno44YES1jg7bqDxqoQghlAKoRs8/YhM3cxQqmgJiqOiw\\u003d\\u003d\"}";


        String sss = "{\"MchId\":\"SLGtest\",\"MethodName\":\"支付寶(上海)\",\"Result\":\"0000\",\"StoreOrderNo\":\"99M5O22062800001\",\"TotalFee\":\"1\"}";
        JSONObject respObject = JSON.parseObject(resp);
        String signStr = respObject.getString("Sign").replaceAll("\\u003d", "=");

        Object object1 = respObject.remove("Sign");
        System.out.println(respObject);
        File der = new File("C:\\intella\\pub.der");
        InputStream is = new FileInputStream(der);
        PublicKey rsaPubKey = KeyReader.loadPublicKeyFromDER(is);
        boolean flag= RsaCryptoUtil.verify(Base64.decodeBase64(signStr), sss.getBytes(StandardCharsets.UTF_8), rsaPubKey);
        System.out.println(flag);
    }

}
