package com.saye.hospitalgd.util;

import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.AutoUpdateCertificatesVerifier;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
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.util.PemUtil;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.PrivateKey;

/**
 * @author thuang
 * @version 1.0
 * @description:
 * 微信支付工具类 使用前先建立对象
 * @date 2021/8/10 9:53
 */
public class WxPayUtil {

    public CloseableHttpClient httpClient;
    public String mchId; //商户号
    public String privateKey; //商户私钥
    public String mchSerialNo; //商户证书序列号
    public String apiV3Key; //API v3密钥

    //
    public WxPayUtil(String mchId,String privateKey,String mchSerialNo,String apiV3Key) throws IOException {
        this.mchId=mchId;
        this.privateKey=privateKey;
        this.mchSerialNo=mchSerialNo;
        this.apiV3Key=apiV3Key;
        setup();
    }

    /**
     * @description:
     * 加载基础数据
     * @author thuang
     * @date 2021/8/10 10:42
     * @version 1.0
     */
    public void setup() throws IOException {
        // 加载商户私钥（privateKey：私钥字符串）
        PrivateKey merchantPrivateKey = PemUtil
                .loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));

        // 加载平台证书（mchId：商户号,mchSerialNo：商户证书序列号,apiV3Key：V3密钥）
        AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(
                new WechatPay2Credentials(mchId, new PrivateKeySigner(mchSerialNo, merchantPrivateKey)),apiV3Key.getBytes("utf-8"));

        // 初始化httpClient
        httpClient = WechatPayHttpClientBuilder.create()
                .withMerchant(mchId, mchSerialNo, merchantPrivateKey)
                .withValidator(new WechatPay2Validator(verifier)).build();
    }

    /**
     * @description:
     * 完成后关闭
     * @author thuang
     * @date 2021/8/10 10:42
     * @version 1.0
     */
    public void after() throws IOException {
        httpClient.close();
    }

    /**
     * @description:
     * 请求账单
     * bill_date 账单日期 格式YYYY-MM-DD 仅支持三个月内的账单下载申请。
     *
     * bill_type 账单类型
     *  枚举值：
     *  ALL：返回当日所有订单信息（不含充值退款订单）
     *  SUCCESS：返回当日成功支付的订单（不含充值退款订单）
     *  REFUND：返回当日退款订单（不含充值退款订单）
     * @author thuang
     * @date 2021/8/10 10:42
     * @version 1.0
     */
    public void TradeBill(String bill_date,String bill_type) throws Exception {

        //请求URL
        URIBuilder uriBuilder = new URIBuilder("https://api.mch.weixin.qq.com/v3/bill/tradebill");
        uriBuilder.setParameter("bill_date", bill_date);
        uriBuilder.setParameter("bill_type", bill_type);

        //完成签名并执行请求
        HttpGet httpGet = new HttpGet(uriBuilder.build());
        httpGet.addHeader("Accept", "application/json");
        CloseableHttpResponse response = httpClient.execute(httpGet);

        try {
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == 200) {
                System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
            } else if (statusCode == 204) {
                System.out.println("success");
            } else {
                System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
                throw new IOException("request failed");
            }
        } finally {
            response.close();
        }
    }

    /**
     * @description:
     * 下载账单
     * @author thuang
     * @date 2021/8/10 10:45
     * @version 1.0
     */
    public void DownloadUrl(String download_url) throws Exception{
        PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));

        //初始化httpClient
        //该接口无需进行签名验证、通过withValidator((response) -> true)实现
        httpClient =  WechatPayHttpClientBuilder.create().withMerchant(mchId, mchSerialNo, merchantPrivateKey).withValidator((response) -> true).build();

        //请求URL
        //账单文件的下载地址的有效时间为30s
        URIBuilder uriBuilder = new URIBuilder(download_url);
        HttpGet httpGet = new HttpGet(uriBuilder.build());
        httpGet.addHeader("Accept", "application/json");

        //执行请求
        CloseableHttpResponse response = httpClient.execute(httpGet);
        try {
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == 200) {
                System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
            } else if (statusCode == 204) {
                System.out.println("success");
            } else {
                System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
                throw new IOException("request failed");
            }
        } finally {
            response.close();
        }
    }
}
