package com.zsElectric.boot.core.pay.swiftpass.util;

import com.zsElectric.boot.core.pay.swiftpass.config.SwiftpassConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;

@Slf4j
public class PayUtill {

    private final static String version = "2.0";
    private final static String charset = "UTF-8";
    //private final static String sign_type = "MD5";
   /* @Autowired
	private SwiftpassConfig sws;*/

    /**
     * 微信支付请求
     * @throws ServletException
     * @throws IOException
     * @see [类、类#方法、类#成员]
     */
    public Map<String,Object> pay(SortedMap<String, String> map, String openid, SwiftpassConfig sws) throws ServletException, IOException {
        log.info("发起微信支付请求...");

        map.put("service", "pay.weixin.jspay");
        map.put("version", version);
        map.put("charset", charset);

        map.put("is_raw", "1");
        map.put("mch_id", sws.getMch_id());//商户号
        map.put("nonce_str", String.valueOf(new Date().getTime()));//随机字符窜
        map.put("sub_openid", openid);

        Map<String, String> params = SignUtils.paraFilter(map);
        StringBuilder buf = new StringBuilder((params.size() + 1) * 10);
        SignUtils.buildPayParams(buf, params, false);
        String preStr = buf.toString();
        String sign_type = map.get("sign_type");//签名方式
        map.put("sign", SignUtil.getSign(sign_type, preStr,sws));
        String reqUrl = sws.getReq_url();
        log.info("请求xml："+XmlUtils.toXml(map));
        CloseableHttpResponse response = null;
        CloseableHttpClient client = null;
        String res = null;
        Map<String, String> resultMap = null;
        try {
            HttpPost httpPost = new HttpPost(reqUrl);
            StringEntity entityParams = new StringEntity(XmlUtils.parseXML(map), "utf-8");
            httpPost.setEntity(entityParams);
            httpPost.setHeader("Content-Type", "text/xml;utf-8");
            client = HttpClients.createDefault();
            response = client.execute(httpPost);
            if (response != null && response.getEntity() != null) {
                resultMap = XmlUtils.toMap(EntityUtils.toByteArray(response.getEntity()), "utf-8");
                String reSign = resultMap.get("sign");
                sign_type = resultMap.get("sign_type");
                res = XmlUtils.toXml(resultMap);
                log.info("签名方式"+sign_type);
                log.info("请求结果：" + res);
                boolean boolSin = SignUtil.verifySign(reSign, sign_type, resultMap,sws);
                log.info("验证结果："+boolSin);
                if (resultMap.containsKey("sign") && !boolSin) {
                    res = "验证签名不通过";
                } else {
                    if ("0".equals(resultMap.get("status")) && "0".equals(resultMap.get("result_code"))) {
                        String pay_info = resultMap.get("pay_info");
                        System.out.println("pay_info : " + pay_info);
                        //                       log.debug("pay_info : " + pay_info);
                        res = "ok";
                    }
                }
            } else {
                res = "操作失败";
            }
        } catch (Exception e) {
            log.error("操作失败，原因：",e);
            res = "系统异常";
        } finally {
            if (response != null) {
                response.close();
            }
            if (client != null) {
                client.close();
            }
        }
        Map result = new HashMap();
        if("ok".equals(res)){
            result = resultMap;
            result.put("status", "200");
        }else{
            result.put("status", "500");
            result.put("msg", res);
        }
        return result;
    }



    /**
     * 订单查询
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     * @see [类、类#方法、类#成员]
     */
    public Map query(HttpServletRequest req, HttpServletResponse resp, SwiftpassConfig sws) throws ServletException, IOException{
        log.info("订单查询...");
        SortedMap<String,String> map = XmlUtils.getParameterMap(req);

        map.put("service", "unified.trade.query");
        map.put("version", version);
        map.put("charset", charset);
        map.put("mch_id", sws.getMch_id());

        String reqUrl = sws.getReq_url();
        map.put("nonce_str", String.valueOf(new Date().getTime()));

        Map<String,String> params = SignUtils.paraFilter(map);
        StringBuilder buf = new StringBuilder((params.size() +1) * 10);
        SignUtils.buildPayParams(buf,params,false);
        String preStr = buf.toString();
        String sign_type = map.get("sign_type");

        map.put("sign", SignUtil.getSign(sign_type, preStr,sws));


        CloseableHttpResponse response = null;
        CloseableHttpClient client = null;
        String res = null;
        try {
            HttpPost httpPost = new HttpPost(reqUrl);
            StringEntity entityParams = new StringEntity(XmlUtils.parseXML(map),"utf-8");
            httpPost.setEntity(entityParams);
            httpPost.setHeader("Content-Type", "text/xml;utf-8");
            client = HttpClients.createDefault();
            response = client.execute(httpPost);

            if(response != null && response.getEntity() != null){
                Map<String,String> resultMap = XmlUtils.toMap(EntityUtils.toByteArray(response.getEntity()), "utf-8");
                String reSign = resultMap.get("sign");
                sign_type = resultMap.get("sign_type");
                res = XmlUtils.toXml(resultMap);
                log.info("签名方式"+sign_type);
                log.info("请求结果：" + res);
                if (resultMap.containsKey("sign") && !SignUtil.verifySign(reSign, sign_type, resultMap,sws)) {
                    res = "验证签名不通过";
                }else{
                    if("0".equals(resultMap.get("status"))){
                        if("0".equals(resultMap.get("result_code"))){
                            String trade_state = resultMap.get("trade_state");
                        }else{
                        }
                    }else{
                    }
                }
            }else{
                res = "操作失败!";
            }
        } catch (Exception e) {
            log.error("操作失败，原因：",e);
            res = "操作失败";
        } finally {
            if(response != null){
                response.close();
            }
            if(client != null){
                client.close();
            }
        }
        Map<String,String> result = new HashMap<String,String>();
        if(res.startsWith("<")){
            result.put("status", "200");
            result.put("msg", "操作成功，请在日志文件中查看");
        }else{
            result.put("status", "500");
            result.put("msg", res);
        }
        return result;
    }

    /**
     * 退款查询
     * @throws ServletException
     * @throws IOException
     * @see [类、类#方法、类#成员]
     */
    public Map refundQuery(SortedMap<String, String> map,SwiftpassConfig sws) throws Exception{
        log.info("退款查询...");

        map.put("service", "unified.trade.refundquery");
        map.put("version", version);
        map.put("charset", charset);

        String reqUrl = sws.getReq_url();
        map.put("mch_id", sws.getMch_id());
        map.put("nonce_str", String.valueOf(new Date().getTime()));

        Map<String,String> params = SignUtils.paraFilter(map);
        StringBuilder buf = new StringBuilder((params.size() +1) * 10);
        SignUtils.buildPayParams(buf,params,false);
        String preStr = buf.toString();
        String sign_type = map.get("sign_type").toString();

        map.put("sign", SignUtil.getSign(sign_type, preStr,sws));
        Map<String,String> resultMap = null;

        CloseableHttpResponse response = null;
        CloseableHttpClient client = null;
        String res = null;
        try {
            HttpPost httpPost = new HttpPost(reqUrl);
            StringEntity entityParams = new StringEntity(XmlUtils.parseXML(map),"utf-8");
            httpPost.setEntity(entityParams);
            httpPost.setHeader("Content-Type", "text/xml;utf-8");
            client = HttpClients.createDefault();
            response = client.execute(httpPost);
            if(response != null && response.getEntity() != null){
                resultMap = XmlUtils.toMap(EntityUtils.toByteArray(response.getEntity()), "utf-8");
                String reSign = resultMap.get("sign");
                sign_type = resultMap.get("sign_type");
                res = XmlUtils.toXml(resultMap);
                log.info("签名方式"+sign_type);
                log.info("请求结果：" + res);
                if (resultMap.containsKey("sign") && !SignUtil.verifySign(reSign, sign_type, resultMap,sws)) {
                    res = "验证签名不通过";
                }
            }else{
                res = "操作失败!";
            }
        } catch (Exception e) {
            log.error("操作失败，原因：",e);
            res = "操作失败";
        } finally {
            if(response != null){
                response.close();
            }
            if(client != null){
                client.close();
            }
        }
        Map<String,Object> result = new HashMap<String,Object>();
        if(res.startsWith("<")){
            result.put("status", "200");
            result.put("data", resultMap);
        }else{
            result.put("status", "500");
            result.put("msg", res);
        }
        return result;
    }
    /**
     * 退款
     * @throws ServletException
     * @throws IOException
     * @see [类、类#方法、类#成员]
     */
    public Map refund(SortedMap<String, String> map,SwiftpassConfig sws) throws ServletException, IOException{
        log.debug("发起微信退款...");

        map.put("service", "unified.trade.refund");
        map.put("version", version);
        map.put("charset", charset);
        String reqUrl = sws.getReq_url();
        map.put("mch_id", sws.getMch_id());
        map.put("op_user_id", sws.getMch_id());
        map.put("nonce_str", String.valueOf(new Date().getTime()));

        Map<String,String> params = SignUtils.paraFilter(map);
        StringBuilder buf = new StringBuilder((params.size() +1) * 10);
        SignUtils.buildPayParams(buf,params,false);
        String preStr = buf.toString();
        String sign_type = map.get("sign_type");

        map.put("sign", SignUtil.getSign(sign_type, preStr,sws));

        CloseableHttpResponse response = null;
        CloseableHttpClient client = null;
        String res = null;
        Map<String,String> resultMap = null;
        System.out.println("请求xml："+XmlUtils.toXml(map));
        try {
            HttpPost httpPost = new HttpPost(reqUrl);
            StringEntity entityParams = new StringEntity(XmlUtils.parseXML(map),"utf-8");
            httpPost.setEntity(entityParams);
            httpPost.setHeader("Content-Type", "text/xml;utf-8");
            client = HttpClients.createDefault();
            response = client.execute(httpPost);
            if(response != null && response.getEntity() != null){
                resultMap = XmlUtils.toMap(EntityUtils.toByteArray(response.getEntity()), "utf-8");
                String reSign = resultMap.get("sign");
                sign_type = resultMap.get("sign_type");
                res = XmlUtils.toXml(resultMap);
                log.info("签名方式"+sign_type);
                log.info("请求结果：" + res);
                if (resultMap.containsKey("sign") && !SignUtil.verifySign(reSign, sign_type, resultMap,sws)) {
                    res = "验证签名不通过";
                }
            }else{
                res = "操作失败!";
            }
        } catch (Exception e) {
            log.error("操作失败，原因：",e);
            res = "操作失败";
        } finally {
            if(response != null){
                response.close();
            }
            if(client != null){
                client.close();
            }
        }
        Map<String,String> result = new HashMap<String,String>();
        if(res.startsWith("<")){
            return resultMap;
        }else{
            result.put("status", "500");
            result.put("msg", res);
        }
        return resultMap;
    }




}
