package com.hfkj.channel.weixin;

import com.hfkj.channel.weixin.entity.OrderRefundModel;
import com.hfkj.channel.weixin.utils.WxUtils;
import com.hfkj.channel.weixin.utils.XmlUtil;
import com.hfkj.channel.weixin.utils.sdk.WXPayConstants;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.SSLContext;
import java.io.FileInputStream;
import java.math.BigDecimal;
import java.security.KeyStore;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 微信订单处理m
 */
public class WxOrderService {

    private static final Logger log = LoggerFactory.getLogger(WxOrderService.class);

    /**
     * 微信支付商户号
     * 个体户黎杨珍
     */
    public static final String MCH_ID_1609882817 = "1609882817";

    /**
     * 微信支付商户号
     * 重庆惠兑电子商务有限公司
     */
    public static final String MCH_ID_1614670195 = "1614670195";

    /**
     * 微信支付商户号
     * 惠昕（贵州）能源有限公司
     */
    public static final String MCH_ID_1619676214 = "1619676214";

    /**
     * 微信支付商户号
     * 惠昕（贵州）能源有限公司
     */
    public static final String MCH_ID_1634835264 = "1634835264";

    /**
     * 微信支付商户号
     * 渝北区浩联物资经营部
     */
    public static final String MCH_ID_1624126902 = "1624126902";

    /**
     * 微信退款
     * @param subMchId
     * @param paySerialNo
     * @param totalFee
     * @param refundFee
     * @return
     * @throws Exception
     */
    public static OrderRefundModel orderToRefund(String subMchId, String paySerialNo, BigDecimal totalFee, BigDecimal refundFee) throws Exception {
        log.info("微信退款开始");
        Map<String,String> param = new HashMap<>();
        param.put("appid", "wx637bd6f7314daa46");
        param.put("mch_id", "1289663601");
        param.put("sub_mch_id" , subMchId);
        param.put("nonce_str", WxUtils.makeNonStr());
        param.put("transaction_id", paySerialNo);
        param.put("out_refund_no", System.currentTimeMillis()+"");
        param.put("total_fee", String.valueOf(totalFee.multiply(new BigDecimal("100")).intValue()));
        param.put("refund_fee", String.valueOf(refundFee.multiply(new BigDecimal("100")).intValue()));
        param.put("sign_type", "HMAC-SHA256");
        String signStr = WxUtils.generateSignature(param, "Skufk5oi85wDFGl888i6wsRSTkdd5df5" , WXPayConstants.SignType.HMACSHA256);
        param.put("sign", signStr);

        String xml = WxUtils.mapToXml(param);
        log.info("请求参数：" + xml);
        String resultXmL = doSSLRequest(param.get("mch_id"), "https://api.mch.weixin.qq.com/secapi/pay/refund", xml);
        log.info("响应参数：" + resultXmL);
        log.info("微信退款结束");
        return XmlUtil.getObjectFromXML(resultXmL, OrderRefundModel.class);
    }

    private static String doSSLRequest(String mchId, String url, String data) throws Exception {
        //双向证书的认证
        CloseableHttpClient httpClient = readCertificate(mchId);
        try {
            //HttpPost httpost = new HttpPost("https://api.mch.weixin.qq.com/secapi/pay/refund"); // 设置响应头信息
            HttpPost httpost = new HttpPost(url); // 设置响应头信息
            httpost.addHeader("Connection", "keep-alive");
            httpost.addHeader("Accept", "*/*");
            httpost.addHeader("Content-Type", "text/xml");
            httpost.addHeader("Host", "api.mch.weixin.qq.com");
            httpost.addHeader("X-Requested-With", "XMLHttpRequest");
            httpost.addHeader("Cache-Control", "max-age=0");
            httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
            httpost.setEntity(new StringEntity(data, "UTF-8"));
            CloseableHttpResponse response = httpClient.execute(httpost);
            try {
                HttpEntity entity = response.getEntity();
                String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
                EntityUtils.consume(entity);
                return jsonStr;
            } finally {
                response.close();
            }
        } catch (Exception e){
            throw new RuntimeException(e);
        } finally {
            httpClient.close();
        }
    }

    private static CloseableHttpClient readCertificate(String mchId) throws Exception{
        /**
         * 注意PKCS12证书 是从微信商户平台-》账户设置-》 API安全 中下载的
         */
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        //P12文件目录 证书路径，这里需要你自己修改，linux下还是windows下的根路径
        // FileInputStream instream = new FileInputStream("/home/project/wx_cert/1289663601_apiclient_cert.p12");
        FileInputStream instream = new FileInputStream("/home/project/wx_cert/"+mchId+"_apiclient_cert.p12");
        try {
            keyStore.load(instream, mchId.toCharArray());//这里写密码..默认是你的MCHID
        } finally {
            instream.close();
        }
        SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, mchId.toCharArray()).build();//这里也是写密码的
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, SSLConnectionSocketFactory.getDefaultHostnameVerifier());
        // Allow TLSv1 protocol only
        return HttpClients.custom().setSSLSocketFactory(sslsf).build();
    }

}
