package com.izouma.awesomeadmin.util;

import com.izouma.awesomeadmin.dto.WxPayRefundData;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
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.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.KeyStore;
import java.util.*;

/**
 * <p>微信申请退款相关服务类。</p>
 *
 * @author 索晨成 <br />
 * 更新履历 <br />
 * 日期 : 姓名: 更新内容<br />
 * @version 1.0
 */
public class WXRefundService {

    /**
     * 日志对象
     */
    private static Logger logger = Logger.getLogger(WXRefundService.class);


    public static Map<String, String> refund(WxPayRefundData data, String key, String certificatePath, String password) {

        //统一下单支付
        // 将解析结果存储在HashMap中
        Map<String, String> map = new HashMap<String, String>();
        try {
            //生成sign签名
            SortedMap<Object, Object> parameters = new TreeMap<Object, Object>();
            parameters.put("appid", data.getAppid());
            parameters.put("mch_id", data.getMch_id());
            parameters.put("device_info", data.getDevice_info());
            parameters.put("nonce_str", data.getNonce_str());
            parameters.put("transaction_id", data.getTransaction_id());
            parameters.put("out_trade_no", data.getOut_trade_no());
            parameters.put("out_refund_no", data.getOut_refund_no());
            parameters.put("total_fee", data.getTotal_fee());
            parameters.put("refund_fee", data.getRefund_fee());
            parameters.put("refund_fee_type", data.getRefund_fee_type());
            parameters.put("op_user_id", data.getOp_user_id());

            String mySign = MbappUtil.createSign(key, parameters);
            logger.info("SIGN:" + mySign);
            // System.out.println("SIGN:" + mySign);
            data.setSign(mySign);
            XStream xs = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("__", "_")));
            xs.alias("xml", WxPayRefundData.class);
            String xml = xs.toXML(data);
            logger.error("申请退款xml为:\n" + xml);
            //指定读取证书格式为PKCS12
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            //读取本机存放的PKCS12证书文件
            FileInputStream instream = new FileInputStream(new File(certificatePath));
            try {
                //指定PKCS12的密码(商户ID)
                keyStore.load(instream, password.toCharArray());
            } finally {
                instream.close();
            }
            SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, password.toCharArray()).build();
            //指定TLS版本
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}, null,
                    SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
            //设置httpclient的SSLSocketFactory
            CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();

            HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/secapi/pay/refund");

            StringEntity reqEntity = new StringEntity(xml, "utf-8");

            // 设置类型 
            reqEntity.setContentType("application/x-www-form-urlencoded");

            httpPost.setEntity(reqEntity);

            System.out.println("executing request" + httpPost.getRequestLine());

            HttpResponse response = httpclient.execute(httpPost);

            try {
                HttpEntity entity = response.getEntity();
                System.out.println(response.getStatusLine());
                if (entity != null) {

                    // 从request中取得输入流
                    InputStream inputStream = entity.getContent();
                    // 读取输入流
                    SAXReader reader = new SAXReader();
                    Document document = reader.read(inputStream);
                    // 得到xml根元素
                    Element root = document.getRootElement();
                    // 得到根元素的所有子节点
                    @SuppressWarnings("unchecked")
                    List<Element> elementList = root.elements();
                    logger.error("微信退款信息");
                    // 遍历所有子节点
                    for (Element e : elementList) {
                        map.put(e.getName(), e.getText());

                        System.out.println(e.getName() + ":" + e.getText());
                        logger.error(e.getName() + ":" + e.getText());
                    }
                    // 释放资源
                    inputStream.close();
                    inputStream = null;

                }
                EntityUtils.consume(entity);
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("微信退款异常", e);
            }

        } catch (Exception e) {
            e.printStackTrace();
            logger.error("微信退款异常", e);
        }

        return map;
    }

}
