package com.heyu.api.jsapi;

// 引用微信支付工具库，参考：https://pay.weixin.qq.com/doc/v3/merchant/4014931831

import com.heyu.api.jsapi.dto.DirectAPIv3JsapiPrepayRequest;
import com.heyu.api.jsapi.dto.DirectAPIv3JsapiPrepayResponse;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.security.PrivateKey;
import java.security.PublicKey;


/**
 * JSAPI下单
 */
@Component
@Slf4j
public class JsapiPrepay {

    private static String HOST = "https://api.mch.weixin.qq.com";

    private static String METHOD = "POST";

    private static String PATH = "/v3/pay/transactions/jsapi";

    private String mchid;
    private String certificateSerialNo;
    private PrivateKey privateKey;
    private String wechatPayPublicKeyId;
    private PublicKey wechatPayPublicKey;

    public JsapiPrepay() {

    }
    public JsapiPrepay(String mchid, String certificateSerialNo, String privateKeyFilePath, String wechatPayPublicKeyId, String wechatPayPublicKeyFilePath) {
        this.mchid = mchid;
        this.certificateSerialNo = certificateSerialNo;
        this.privateKey = WXPayUtility.loadPrivateKeyFromPath(privateKeyFilePath);
        this.wechatPayPublicKeyId = wechatPayPublicKeyId;
        this.wechatPayPublicKey = WXPayUtility.loadPublicKeyFromPath(wechatPayPublicKeyFilePath);
    }


    public DirectAPIv3JsapiPrepayResponse rePay(DirectAPIv3JsapiPrepayRequest request) {
        String uri = PATH;
        String reqBody = WXPayUtility.toJson(request);

        Request.Builder reqBuilder = new Request.Builder().url(HOST + uri);
        reqBuilder.addHeader("Accept", "application/json");
        reqBuilder.addHeader("Wechatpay-Serial", wechatPayPublicKeyId);
        reqBuilder.addHeader("Authorization", WXPayUtility.buildAuthorization(mchid, certificateSerialNo, privateKey, METHOD, uri, reqBody));
        reqBuilder.addHeader("Content-Type", "application/json");
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), reqBody);
        reqBuilder.method(METHOD, requestBody);

        Request httpRequest = reqBuilder.build();

        // 发送HTTP请求
        OkHttpClient client = new OkHttpClient.Builder().build();

        try (Response httpResponse = client.newCall(httpRequest).execute()) {

            String respBody = WXPayUtility.extractBody(httpResponse);
            log.info("JsapiPrepay respBody:{}", respBody);
            if (respBody != null) {
            }
            if (httpResponse.code() >= 200 && httpResponse.code() < 300) {
                // 2XX 成功，验证应答签名
                WXPayUtility.validateResponse(this.wechatPayPublicKeyId, this.wechatPayPublicKey, httpResponse.headers(), respBody);

                // 从HTTP应答报文构建返回数据
                return WXPayUtility.fromJson(respBody, DirectAPIv3JsapiPrepayResponse.class);
            } else {
                throw new WXPayUtility.ApiException(httpResponse.code(), respBody, httpResponse.headers());
            }
        } catch (IOException e) {
            throw new UncheckedIOException("Sending request to " + uri + " failed.", e);
        }
    }
}
