package com.kmall.manager.manager.pingan;

import com.kmall.manager.manager.pingan.dto.PinganPayOrderDto;
import com.kmall.manager.manager.pingan.dto.PinganResponseDto;
import com.kmall.manager.manager.pingan.properties.PinganPayPropertiesBuilder;
import com.kmall.manager.manager.pingan.utils.InterfaceParams;
import com.kmall.manager.manager.pingan.utils.TLinx2Util;
import com.kmall.manager.manager.pingan.utils.TLinxAESCoder;
import com.kmall.manager.manager.pingan.utils.TLinxSHA1;
import com.kmall.common.utils.DateUtils;
import com.kmall.common.utils.MapUtils;
import com.kmall.common.utils.StringUtils;
import com.kmall.common.utils.wechat.WechatRefundQueryResult;
import net.sf.json.JSONObject;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.Date;
import java.util.TreeMap;

public class PinganUtil {

    private static final String SUCCESS_CODE = "0";
    private static Log logger = LogFactory.getLog(PinganUtil.class);

    /**
     * 构建平安支付订单信息
     */
    public static PinganPayOrderDto buildPayOrderDto(JSONObject dataObject) {
        PinganPayOrderDto payorder = new PinganPayOrderDto();
        payorder.setOutNo(StringUtils.isNullOrEmpty(MapUtils.getString("out_no", dataObject)) || MapUtils.getString("out_no", dataObject).equals("null") ? null : MapUtils.getString("out_no", dataObject));
        payorder.setPmtName(StringUtils.isNullOrEmpty(MapUtils.getString("pmt_name", dataObject)) || MapUtils.getString("pmt_name", dataObject).equals("null") ? null : MapUtils.getString("pmt_name", dataObject));
        payorder.setPmtTag(StringUtils.isNullOrEmpty(MapUtils.getString("pmt_tag", dataObject)) || MapUtils.getString("pmt_tag", dataObject).equals("null") ? null : MapUtils.getString("pmt_tag", dataObject));
        payorder.setOrdMctId(MapUtils.getInteger("ord_mct_id", dataObject));
        payorder.setOrdShopId(MapUtils.getInteger("ord_shop_id", dataObject));
        payorder.setOrdCurrency(StringUtils.isNullOrEmpty(MapUtils.getString("ord_currency", dataObject)) || MapUtils.getString("ord_currency", dataObject).equals("null") ? null : MapUtils.getString("ord_currency", dataObject));
        payorder.setCurrencySign(StringUtils.isNullOrEmpty(MapUtils.getString("currency_sign", dataObject)) || MapUtils.getString("currency_sign", dataObject).equals("null") ? null : MapUtils.getString("currency_sign", dataObject));
        payorder.setOrdNo(StringUtils.isNullOrEmpty(MapUtils.getString("ord_no", dataObject)) || MapUtils.getString("ord_no", dataObject).equals("null") ? null : MapUtils.getString("ord_no", dataObject));
        payorder.setOrdType(MapUtils.getInteger("ord_type", dataObject));
        payorder.setOriginalAmount(MapUtils.getInteger("original_amount", dataObject));
        payorder.setDiscountAmount(MapUtils.getInteger("discount_amount", dataObject));
        payorder.setIgnoreAmount(MapUtils.getInteger("ignore_amount", dataObject));
        payorder.setTradeAccount(StringUtils.isNullOrEmpty(MapUtils.getString("trade_account", dataObject)) || MapUtils.getString("trade_account", dataObject).equals("null") ? null : MapUtils.getString("trade_account", dataObject));
        payorder.setTradeNo(StringUtils.isNullOrEmpty(MapUtils.getString("trade_no", dataObject)) || MapUtils.getString("trade_no", dataObject).equals("null") ? null : MapUtils.getString("trade_no", dataObject));
        payorder.setTradeAmount(MapUtils.getInteger("trade_amount", dataObject));
        payorder.setTradeQrcode(StringUtils.isNullOrEmpty(MapUtils.getString("trade_qrcode", dataObject)) || MapUtils.getString("trade_qrcode", dataObject).equals("null") ? null : MapUtils.getString("trade_qrcode", dataObject));
        payorder.setAmount(StringUtils.isNullOrEmpty(MapUtils.getString("amount", dataObject)) || MapUtils.getString("amount", dataObject).equals("null") ? null : MapUtils.getString("amount", dataObject));
        payorder.setTradeTime(StringUtils.isNullOrEmpty(MapUtils.getString("trade_time", dataObject)) || MapUtils.getString("trade_time", dataObject) == null || MapUtils.getString("trade_time", dataObject).equals("null") ? null : DateUtils.strToDate(MapUtils.getString("trade_time", dataObject)));
        payorder.setTradePayTime(StringUtils.isNullOrEmpty(MapUtils.getString("trade_pay_time", dataObject)) || MapUtils.getString("trade_pay_time", dataObject) == null || MapUtils.getString("trade_pay_time", dataObject).equals("null") ? null : DateUtils.strToDate(MapUtils.getString("trade_pay_time", dataObject)));
        payorder.setPayTime(StringUtils.isNullOrEmpty(MapUtils.getString("pay_time", dataObject)) || MapUtils.getString("pay_time", dataObject).equals("null") ? null : MapUtils.getString("pay_time", dataObject));
        payorder.setStatus(MapUtils.getInteger("status", dataObject));
        payorder.setTradeResult(StringUtils.isNullOrEmpty(MapUtils.getString("trade_result", dataObject)) || MapUtils.getString("trade_result", dataObject).equals("null") ? null : MapUtils.getString("trade_result", dataObject));
        payorder.setJsapiPayUrl(StringUtils.isNullOrEmpty(MapUtils.getString("jsapi_pay_url", dataObject)) || MapUtils.getString("jsapi_pay_url", dataObject).equals("null") ? null : MapUtils.getString("jsapi_pay_url", dataObject));
        payorder.setJsapiPayUrl(StringUtils.isNullOrEmpty(MapUtils.getString("rand_str", dataObject)) || MapUtils.getString("rand_str", dataObject).equals("null") ? null : MapUtils.getString("rand_str", dataObject));
        payorder.setAppid(StringUtils.isNullOrEmpty(MapUtils.getString("appId", dataObject)) || MapUtils.getString("appId", dataObject).equals("null") ? null : MapUtils.getString("appId", dataObject));
        payorder.setNoncestr(StringUtils.isNullOrEmpty(MapUtils.getString("nonceStr", dataObject)) || MapUtils.getString("nonceStr", dataObject).equals("null") ? null : MapUtils.getString("nonceStr", dataObject));
        payorder.setSigntype(StringUtils.isNullOrEmpty(MapUtils.getString("signType", dataObject)) || MapUtils.getString("signType", dataObject).equals("null") ? null : MapUtils.getString("signType", dataObject));
        payorder.setPrepayId(StringUtils.isNullOrEmpty(MapUtils.getString("package", dataObject)) || MapUtils.getString("package", dataObject).equals("null") ? null : MapUtils.getString("package", dataObject));
        payorder.setPaysign(StringUtils.isNullOrEmpty(MapUtils.getString("paySign", dataObject)) || MapUtils.getString("paySign", dataObject).equals("null") ? null : MapUtils.getString("paySign", dataObject));
        payorder.setTimeStamp(StringUtils.isNullOrEmpty(MapUtils.getString("timeStamp", dataObject)) || MapUtils.getString("timeStamp", dataObject).equals("null") ? null : MapUtils.getString("timeStamp", dataObject));
        return payorder;
    }

    public static WechatRefundQueryResult buildWechatRefundQueryResult(JSONObject tradeResult, int count) {
        WechatRefundQueryResult refundQueryResult = new WechatRefundQueryResult();
        refundQueryResult.setOut_refund_no(StringUtils.isNullOrEmpty(MapUtils.getString("out_refund_no_" + (count), tradeResult)) || MapUtils.getString("out_refund_no_" + (count), tradeResult).equals("null") ? null : MapUtils.getString("out_refund_no_" + (count), tradeResult));
        refundQueryResult.setRefund_account(StringUtils.isNullOrEmpty(MapUtils.getString("refund_account_" + (count), tradeResult)) || MapUtils.getString("refund_account_" + (count), tradeResult).equals("null") ? null : MapUtils.getString("refund_account_" + (count), tradeResult));
        refundQueryResult.setRefund_channel(StringUtils.isNullOrEmpty(MapUtils.getString("refund_channel_" + (count), tradeResult)) || MapUtils.getString("refund_channel_" + (count), tradeResult).equals("null") ? null : MapUtils.getString("refund_channel_" + (count), tradeResult));
        refundQueryResult.setRefund_fee(StringUtils.isNullOrEmpty(MapUtils.getString("refund_fee_" + (count), tradeResult)) || MapUtils.getString("refund_fee_" + (count), tradeResult).equals("null") ? null : MapUtils.getString("refund_fee_" + (count), tradeResult));
        refundQueryResult.setRefund_id(StringUtils.isNullOrEmpty(MapUtils.getString("refund_id_" + (count), tradeResult)) || MapUtils.getString("refund_id_" + (count), tradeResult).equals("null") ? null : MapUtils.getString("refund_id_" + (count), tradeResult));
        refundQueryResult.setRefund_recv_accout(StringUtils.isNullOrEmpty(MapUtils.getString("refund_recv_accout_" + (count), tradeResult)) || MapUtils.getString("refund_recv_accout_" + (count), tradeResult).equals("null") ? null : MapUtils.getString("refund_recv_accout_" + (count), tradeResult));
        refundQueryResult.setRefund_status(StringUtils.isNullOrEmpty(MapUtils.getString("refund_status_" + (count), tradeResult)) || MapUtils.getString("refund_status_" + (count), tradeResult).equals("null") ? null : MapUtils.getString("refund_status_" + (count), tradeResult));
        refundQueryResult.setRefund_success_time(StringUtils.isNullOrEmpty(MapUtils.getString("refund_success_time_" + (count), tradeResult)) || MapUtils.getString("refund_success_time_" + (count), tradeResult).equals("null") ? null : MapUtils.getString("refund_success_time_" + (count), tradeResult));
        return refundQueryResult;
    }

    public static WechatRefundQueryResult buildWechatRefundQueryResult(JSONObject tradeResult) {
        WechatRefundQueryResult refundQueryResult = new WechatRefundQueryResult();
        refundQueryResult.setOut_refund_no(StringUtils.isNullOrEmpty(MapUtils.getString("out_refund_no", tradeResult)) || MapUtils.getString("out_refund_no", tradeResult).equals("null") ? null : MapUtils.getString("out_refund_no", tradeResult));
        refundQueryResult.setRefund_account(StringUtils.isNullOrEmpty(MapUtils.getString("refund_account", tradeResult)) || MapUtils.getString("refund_account", tradeResult).equals("null") ? null : MapUtils.getString("refund_account", tradeResult));
        refundQueryResult.setRefund_channel(StringUtils.isNullOrEmpty(MapUtils.getString("refund_channel", tradeResult)) || MapUtils.getString("refund_channel", tradeResult).equals("null") ? null : MapUtils.getString("refund_channel", tradeResult));
        refundQueryResult.setRefund_fee(StringUtils.isNullOrEmpty(MapUtils.getString("refund_fee", tradeResult)) || MapUtils.getString("refund_fee", tradeResult).equals("null") ? null : MapUtils.getString("refund_fee", tradeResult));
        refundQueryResult.setRefund_id(StringUtils.isNullOrEmpty(MapUtils.getString("refund_id", tradeResult)) || MapUtils.getString("refund_id", tradeResult).equals("null") ? null : MapUtils.getString("refund_id", tradeResult));
        refundQueryResult.setRefund_recv_accout(StringUtils.isNullOrEmpty(MapUtils.getString("refund_recv_accout", tradeResult)) || MapUtils.getString("refund_recv_accout", tradeResult).equals("null") ? null : MapUtils.getString("refund_recv_accout", tradeResult));
        refundQueryResult.setRefund_status(StringUtils.isNullOrEmpty(MapUtils.getString("refund_status", tradeResult)) || MapUtils.getString("refund_status", tradeResult).equals("null") ? null : MapUtils.getString("refund_status", tradeResult));
        refundQueryResult.setRefund_success_time(StringUtils.isNullOrEmpty(MapUtils.getString("refund_success_time", tradeResult)) || MapUtils.getString("refund_success_time", tradeResult).equals("null") ? null : MapUtils.getString("refund_success_time", tradeResult));
        return refundQueryResult;
    }

    /**
     * 平安订单退款接口
     */
    public static PinganResponseDto pinganPayRefund(String outNo, String refundOutNo, Integer refundAmount, String tradeNo) {
        // 初始化参数
        String timestamp = new Date().getTime() / 1000 + "";    // 时间
        PinganResponseDto response = null;
        try {
            // 固定参数
            TreeMap<String, String> postmap = new TreeMap<String, String>();    // 请求参数的map
            postmap.put("open_id", PinganPayPropertiesBuilder.instance().getPayOpenId());
            postmap.put("timestamp", timestamp);

            TreeMap<String, String> datamap = new TreeMap<String, String>();    // data参数的map
            datamap.put("out_no", outNo);
            datamap.put("refund_out_no", refundOutNo);
            datamap.put("refund_amount", refundAmount + "");
            datamap.put("trade_no", tradeNo);
            datamap.put("shop_pass", TLinxSHA1.SHA1("123456"));

            TLinx2Util.handleEncrypt(datamap, postmap);
            postmap.put("sign_type", "RSA");
            TLinx2Util.handleSignRSA(postmap);

            String rspStr = TLinx2Util.handlePost(postmap, InterfaceParams.PAYREFUND);
            System.out.println("返回字符串=" + rspStr);

            JSONObject respObject = JSONObject.fromObject(rspStr);
            logger.info("返回错误码：【" + MapUtils.getString("errcode", respObject) + "】");
            logger.info("返回错误提示【" + MapUtils.getString("msg", respObject) + "】");
            logger.info("平安支付下单返回数据:【" + MapUtils.getString("data", respObject) + "】");
            logger.info("接口签名【" + MapUtils.getString("sign", respObject) + "】");

            response = new PinganResponseDto();
            response.setErrcode(MapUtils.getString("errcode", respObject));
            response.setMsg(MapUtils.getString("msg", respObject));
            response.setData(MapUtils.getString("data", respObject));
            response.setSign(MapUtils.getString("sign", respObject));
            if (StringUtils.isNotEmpty(MapUtils.getString("timestamp", respObject))) {
                Long tstm = Long.parseLong(MapUtils.getString("timestamp", respObject)) * 1000;
                response.setTimestamp(new Date(tstm));
            }
            response.setReqInterface(InterfaceParams.PAYREFUND);

            if (SUCCESS_CODE.equals(MapUtils.getString("errcode", respObject))) {
                Object dataStr = MapUtils.getString("data", respObject);
                if (!rspStr.isEmpty() && (dataStr != null)) {
                    if (TLinx2Util.verifySign(respObject)) {    // 验签成功
                        String respData = TLinxAESCoder.decrypt(dataStr.toString(), PinganPayPropertiesBuilder.instance().getPayOpenKey());
                        System.out.println("==================响应data内容:" + respData);
                        response.setDatajson(respData);
                    } else {
                        System.out.println("=====验签失败=====");
                    }
                } else {
                    System.out.println("=====没有返回data数据=====");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return response;
    }


    /**
     * 平安订单取消接口
     * 1、接口适用于所有等待支付的订单。
     * 2、已成功支付的只支持“微信刷卡”类型的订单取消。
     * 3、仅当日订单可以触发，已支付订单按支付完成时间，未支付订单按订单下单时间。
     * 4、下单后，系统会在12分钟后自动取消未支付订单，调用本接口前请先查询订单状态。
     */
    public static PinganResponseDto pinganPayCancel(String ordNo, String outNo) {
        // 初始化参数
        String timestamp = new Date().getTime() / 1000 + "";    // 时间
        PinganResponseDto response = null;
        try {
            // 固定参数
            TreeMap<String, String> postmap = new TreeMap<String, String>();    // 请求参数的map
            postmap.put("open_id", PinganPayPropertiesBuilder.instance().getPayOpenId());
            postmap.put("timestamp", timestamp);

            TreeMap<String, String> datamap = new TreeMap<String, String>();    // data参数的map
            datamap.put("out_no", outNo);
            datamap.put("ord_no", ordNo);

            TLinx2Util.handleEncrypt(datamap, postmap);

            //签名方式
            postmap.put("sign_type", "RSA");
            System.out.println("postmap---:" + postmap);
            TLinx2Util.handleSignRSA(postmap);

            String rspStr = TLinx2Util.handlePost(postmap, InterfaceParams.PAYCANCEL);
            System.out.println("返回字符串=" + new String(rspStr.getBytes("UTF-8")));

            JSONObject respObject = JSONObject.fromObject(rspStr);
            logger.info("返回错误码：【" + MapUtils.getString("errcode", respObject) + "】");
            logger.info("返回错误提示【" + MapUtils.getString("msg", respObject) + "】");
            logger.info("平安支付下单返回数据:【" + MapUtils.getString("data", respObject) + "】");
            logger.info("接口签名【" + MapUtils.getString("sign", respObject) + "】");

            response = new PinganResponseDto();
            response.setErrcode(MapUtils.getString("errcode", respObject));
            response.setMsg(MapUtils.getString("msg", respObject));
            response.setData(MapUtils.getString("data", respObject));
            response.setSign(MapUtils.getString("sign", respObject));
            if (StringUtils.isNotEmpty(MapUtils.getString("timestamp", respObject))) {
                Long tstm = Long.parseLong(MapUtils.getString("timestamp", respObject)) * 1000;
                response.setTimestamp(new Date(tstm));
            }
            response.setReqInterface(InterfaceParams.PAYCANCEL);

            if (SUCCESS_CODE.equals(MapUtils.getString("errcode", respObject))) {
                Object dataStr = MapUtils.getString("data", respObject);
                if (!rspStr.isEmpty() || (dataStr != null)) {
                    if (TLinx2Util.verifySign(respObject)) {    // 验签成功
                        String respData = TLinxAESCoder.decrypt(dataStr.toString(), PinganPayPropertiesBuilder.instance().getPayOpenKey());
                        System.out.println("==================响应data内容:" + respData);
                        response.setDatajson(respData);
                    } else {
                        System.out.println("=====验签失败=====");
                    }
                } else {
                    System.out.println("=====没有返回data数据=====");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return response;
    }


    /**
     * 平安查询付款状态
     */
    public static PinganResponseDto pinganPaystatus(String outNo) {
        // 初始化参数
        String timestamp = new Date().getTime() / 1000 + "";    // 时间
        PinganResponseDto response = null;
        try {
            // 固定参数
            TreeMap<String, String> postmap = new TreeMap<String, String>();    // 请求参数的map
            postmap.put("open_id", PinganPayPropertiesBuilder.instance().getPayOpenId());
            postmap.put("timestamp", timestamp);

            TreeMap<String, String> datamap = new TreeMap<String, String>();    // data参数的map
            datamap.put("out_no", outNo);

            TLinx2Util.handleEncrypt(datamap, postmap);
            TLinx2Util.handleSign(postmap);

            String rspStr = TLinx2Util.handlePost(postmap, InterfaceParams.QUERYPAYSTATUS);
            System.out.println("返回字符串=" + rspStr);

            JSONObject respObject = JSONObject.fromObject(rspStr);
            logger.info("返回错误码：【" + MapUtils.getString("errcode", respObject) + "】");
            logger.info("返回错误提示【" + MapUtils.getString("msg", respObject) + "】");
            logger.info("平安支付下单返回数据:【" + MapUtils.getString("data", respObject) + "】");
            logger.info("接口签名【" + MapUtils.getString("sign", respObject) + "】");

            response = new PinganResponseDto();
            response.setErrcode(MapUtils.getString("errcode", respObject));
            response.setMsg(MapUtils.getString("msg", respObject));
            response.setData(MapUtils.getString("data", respObject));
            response.setSign(MapUtils.getString("sign", respObject));
            if (StringUtils.isNotEmpty(MapUtils.getString("timestamp", respObject))) {
                Long tstm = Long.parseLong(MapUtils.getString("timestamp", respObject)) * 1000;
                response.setTimestamp(new Date(tstm));
            }
            response.setReqInterface(InterfaceParams.QUERYPAYSTATUS);

            if (SUCCESS_CODE.equals(MapUtils.getString("errcode", respObject))) {
                Object dataStr = MapUtils.getString("data", respObject);
                if (!rspStr.isEmpty() || (dataStr != null)) {
                    if (TLinx2Util.verifySign(respObject)) {    // 验签成功
                        String respData = TLinxAESCoder.decrypt(dataStr.toString(), PinganPayPropertiesBuilder.instance().getPayOpenKey());
                        System.out.println("==================响应data内容:" + respData);
                        response.setDatajson(respData);
                    } else {
                        System.out.println("=====验签失败=====");
                    }
                } else {
                    System.out.println("=====没有返回data数据=====");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return response;
    }

    /**
     * 平安订单退款查询
     */
    public static PinganResponseDto pinganQueryRefund(String refund_out_no, String refund_ord_no) {
        // 初始化参数
        String timestamp = new Date().getTime() / 1000 + "";    // 时间
        PinganResponseDto response = null;
        try {
            // 固定参数
            TreeMap<String, String> postmap = new TreeMap<String, String>();    // 请求参数的map
            postmap.put("open_id", PinganPayPropertiesBuilder.instance().getPayOpenId());
            postmap.put("timestamp", timestamp);

            TreeMap<String, String> datamap = new TreeMap<String, String>();    // data参数的map
            datamap.put("refund_out_no", refund_out_no);
            datamap.put("refund_ord_no", refund_ord_no);

            TLinx2Util.handleEncrypt(datamap, postmap);
            TLinx2Util.handleSign(postmap);

            String rspStr = TLinx2Util.handlePost(postmap, InterfaceParams.QUERYPAYREFUND);
            System.out.println("返回字符串=" + rspStr);

            JSONObject respObject = JSONObject.fromObject(rspStr);
            logger.info("返回错误码：【" + MapUtils.getString("errcode", respObject) + "】");
            logger.info("返回错误提示【" + MapUtils.getString("msg", respObject) + "】");
            logger.info("平安支付下单返回数据:【" + MapUtils.getString("data", respObject) + "】");
            logger.info("接口签名【" + MapUtils.getString("sign", respObject) + "】");

            response = new PinganResponseDto();
            response.setErrcode(MapUtils.getString("errcode", respObject));
            response.setMsg(MapUtils.getString("msg", respObject));
            response.setData(MapUtils.getString("data", respObject));
            response.setSign(MapUtils.getString("sign", respObject));
            if (StringUtils.isNotEmpty(MapUtils.getString("timestamp", respObject))) {
                Long tstm = Long.parseLong(MapUtils.getString("timestamp", respObject)) * 1000;
                response.setTimestamp(new Date(tstm));
            }
            response.setReqInterface(InterfaceParams.QUERYPAYREFUND);

            if (SUCCESS_CODE.equals(MapUtils.getString("errcode", respObject))) {
                Object dataStr = MapUtils.getString("data", respObject);
                if (!rspStr.isEmpty() && (dataStr != null)) {
                    if (TLinx2Util.verifySign(respObject)) {    // 验签成功
                        String respData = TLinxAESCoder.decrypt(dataStr.toString(), PinganPayPropertiesBuilder.instance().getPayOpenKey());
                        System.out.println("==================响应data内容:" + respData);
                        response.setDatajson(respData);
                    } else {
                        System.out.println("=====验签失败=====");
                    }
                } else {
                    System.out.println("=====没有返回data数据=====");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return response;
    }
}
