package com.hfkj.common.utils;

import com.alibaba.fastjson.JSONObject;
import com.hfkj.common.exception.ErrorCode;
import com.hfkj.common.exception.ErrorHelp;
import com.hfkj.common.exception.SysCode;
import com.hfkj.config.CommonSysConst;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
import com.wechat.pay.contrib.apache.httpclient.exception.HttpCodeException;
import com.wechat.pay.contrib.apache.httpclient.exception.NotFoundException;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;

import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class WxUtils {
    // 微信请求地址
    private final static String REQ_URL = "https://api.mch.weixin.qq.com";
    // 商户号
    private final static String merchantId = "1614670195";
    // 商户证书编号
    private final static String merchantSerialNumber = "6E73923625A838DEA31C7BAA66938AD6281D698F";
    // APIv3密钥
    private final static String apiV3Key = "UXt3EGM5X6P71EXcNmszV1ONk7LX9IEj";

    /**
     * 获取请求
     * @return
     * @throws GeneralSecurityException
     * @throws IOException
     * @throws HttpCodeException
     * @throws NotFoundException
     */
    public static CloseableHttpClient getHttpClient() throws GeneralSecurityException, IOException, HttpCodeException, NotFoundException {
        // 私钥文件路径
        PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new FileInputStream("/home/project/oil/cert/wechat/1614670195/apiclient_key.pem"));
        CertificatesManager certificatesManager = CertificatesManager.getInstance();
        certificatesManager.putMerchant(merchantId, new WechatPay2Credentials(merchantId,
                        new PrivateKeySigner(merchantSerialNumber, merchantPrivateKey)),
                        apiV3Key.getBytes(StandardCharsets.UTF_8));
        Verifier verifier = certificatesManager.getVerifier(merchantId);
        WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
                .withMerchant(merchantId, merchantSerialNumber, merchantPrivateKey)
                .withValidator(new WechatPay2Validator(verifier));
        return builder.build();
    }

    /**
     * 商家转账
     * @param openId
     * @param transferAmount
     * @return
     * @throws GeneralSecurityException
     * @throws NotFoundException
     * @throws IOException
     * @throws HttpCodeException
     */
    public static JSONObject transferBills(String openId,String outBillNo, BigDecimal transferAmount, String transferRemark) throws GeneralSecurityException, NotFoundException, IOException, HttpCodeException {
        JSONObject body = new JSONObject();
        body.put("appid", CommonSysConst.getSysConfig().getWxMaAppId());
        body.put("out_bill_no", outBillNo);
        body.put("transfer_scene_id", "1000");
        body.put("openid", openId);
        body.put("transfer_amount", transferAmount.multiply(new BigDecimal("100")).intValue());
        // body.put("openid", "oUGn_4unIjp90MY-oEXluY4laDrQ");
        // body.put("transfer_amount", 1);
        body.put("transfer_remark", transferRemark);
        body.put("notify_url", CommonSysConst.getSysConfig().getDomainName()+"/crest/wexinNotify/withdraw");

        List<Map<String,Object>> transferSceneReportInfosList = new LinkedList<>();
        Map<String,Object> transferSceneReportInfos = new HashMap<>();
        transferSceneReportInfos.put("info_type","活动名称");
        transferSceneReportInfos.put("info_content","推广有礼");
        transferSceneReportInfosList.add(transferSceneReportInfos);
        Map<String,Object> transferSceneReportInfos2 = new HashMap<>();
        transferSceneReportInfos2.put("info_type","奖励说明");
        transferSceneReportInfos2.put("info_content","推广佣金");
        transferSceneReportInfosList.add(transferSceneReportInfos2);
        body.put("transfer_scene_report_infos", transferSceneReportInfosList);

        HttpPost httpPost = new HttpPost(REQ_URL+"/v3/fund-app/mch-transfer/transfer-bills");
        httpPost.setEntity(new StringEntity(body.toJSONString(), "utf-8"));
        httpPost.setHeader(HttpHeaders.ACCEPT, "application/json");
        httpPost.setHeader(HttpHeaders.CONTENT_TYPE, "application/json");

        CloseableHttpResponse httpResponse = WxUtils.getHttpClient().execute(httpPost);
        HttpEntity entity = httpResponse.getEntity();
        JSONObject responseData = JSONObject.parseObject(EntityUtils.toString(entity));
        if (httpResponse.getStatusLine().getStatusCode() != 200) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, responseData.getString("message"));
        }
        return responseData;
    }

    /**
     * 撤销转账
     * @param outBillNo
     * @return
     * @throws GeneralSecurityException
     * @throws NotFoundException
     * @throws IOException
     * @throws HttpCodeException
     */
    public static JSONObject cancelTransferBills(String outBillNo) throws GeneralSecurityException, NotFoundException, IOException, HttpCodeException {
        HttpPost httpPost = new HttpPost(REQ_URL+"/v3/fund-app/mch-transfer/transfer-bills/out-bill-no/"+outBillNo+"/cancel");
        httpPost.setHeader(HttpHeaders.ACCEPT, "application/json");
        httpPost.setHeader(HttpHeaders.CONTENT_TYPE, "application/json");

        httpPost.setEntity(new StringEntity("", "utf-8"));
        CloseableHttpResponse httpResponse = WxUtils.getHttpClient().execute(httpPost);
        HttpEntity entity = httpResponse.getEntity();
        JSONObject responseData = JSONObject.parseObject(EntityUtils.toString(entity));
        if (httpResponse.getStatusLine().getStatusCode() != 200) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, responseData.getString("message"));
        }
        return responseData;
    }


    /**
     * 查询转账详情
     * @param outBillNo
     * @return
     * @throws GeneralSecurityException
     * @throws NotFoundException
     * @throws IOException
     * @throws HttpCodeException
     */
    public static JSONObject queryTransferBills(String outBillNo) throws GeneralSecurityException, NotFoundException, IOException, HttpCodeException {
        HttpGet httpGet = new HttpGet(REQ_URL+"/v3/fund-app/mch-transfer/transfer-bills/out-bill-no/"+outBillNo);
        httpGet.setHeader(HttpHeaders.ACCEPT, "application/json");
        httpGet.setHeader(HttpHeaders.CONTENT_TYPE, "application/json");

        CloseableHttpResponse httpResponse = WxUtils.getHttpClient().execute(httpGet);
        HttpEntity entity = httpResponse.getEntity();
        JSONObject responseData = JSONObject.parseObject(EntityUtils.toString(entity));
        if (httpResponse.getStatusLine().getStatusCode() != 200) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, responseData.getString("message"));
        }
        return responseData;
    }
}
