package cn.ysk.cashier.thirdpay.service;

import cn.hutool.http.HttpRequest;

import cn.ysk.cashier.mybatis.vo.pay.MainScanReq;
import cn.ysk.cashier.mybatis.vo.pay.MainScanResp;
import cn.ysk.cashier.thirdpay.constants.SignTypeEnum;
import cn.ysk.cashier.thirdpay.req.OrderRefundReq;
import cn.ysk.cashier.thirdpay.req.OrderReturnQueryReq;
import cn.ysk.cashier.thirdpay.req.OrderStatusQueryReq;
import cn.ysk.cashier.thirdpay.req.PublicParam;
import cn.ysk.cashier.thirdpay.resp.OrderReturnResp;
import cn.ysk.cashier.thirdpay.resp.OrderStatusQueryResp;
import cn.ysk.cashier.thirdpay.resp.PublicResp;
import cn.ysk.cashier.utils.JSONUtil;
import cn.ysk.cashier.utils.MD5Util;
import cn.ysk.cashier.utils.MD5Utils;
import com.dianguang.cloud.ossservice.model.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Comparator;
import java.util.LinkedHashMap;

@Service
@Slf4j
public class ThirdPayService {

    private static String micropay="/api/open/payment/micropay";

    private static String   ltpay="/api/open/payment/ltpay";


    private static String refund="/api/open/order/refund";


    private static String trade="/api/open/query/trade";

    /**
     * 查询订单状态
     * @param url
     * @param appId
     * @param payOrderId
     * @param mchOrderNo
     * @param key
     * @return
     */
    public PublicResp<OrderStatusQueryResp>  queryOrder(String url, String appId, String payOrderId, String mchOrderNo, String key){
        OrderStatusQueryReq req=new OrderStatusQueryReq(payOrderId,mchOrderNo);
        PublicParam param=new PublicParam(appId,null,SignTypeEnum.MD5.getValue(), null,DateUtils.getSdfTimes(), "1.0", String.valueOf(System.currentTimeMillis()));
        try {
            String str = JSONUtil.toJSONString(sortFields(req));
            param.setBizData(str);
            String tt = sortFieldsAndPrint(param);
            String MD5 = tt.concat("appSecret=" + key);
            log.info("加签原传:{}", MD5);
            String sign = MD5Utils.encrypt(MD5);
            param.setSign(sign);
            String reqbody = JSONUtil.toJSONString(param);
            log.info("请求参数:{}", reqbody);
            String response = HttpRequest.post(url.concat(trade)).body(reqbody).execute().body();
            log.info("返回结果:{}", response);
            PublicResp<OrderStatusQueryResp> resp =JSONUtil.parseJSONStr2T(response,PublicResp.class);
            resp.setObjData(JSONUtil.parseJSONStr2T(resp.getBizData(),OrderStatusQueryResp.class));
            return resp;
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }

    }


    /**
     * 退款
     * @param url
     * @param appId
     * @param mchRefundNo
     * @param payOrderId
     * @param mchOrderNo
     * @param refundReason
     * @param refundAmount
     * @param notifyUrl
     * @param extParam
     * @param key
     * @return
     */
    public PublicResp<OrderReturnResp> returnOrder(String url, String appId, String mchRefundNo, String payOrderId, String mchOrderNo, String refundReason, Long refundAmount, String notifyUrl, String extParam, String key){
        OrderRefundReq req=new OrderRefundReq(mchRefundNo, payOrderId, mchOrderNo, refundReason, refundAmount, notifyUrl, extParam);
        PublicParam param=new PublicParam(appId,null,SignTypeEnum.MD5.getValue(), null,DateUtils.getSdfTimes(), "1.0", String.valueOf(System.currentTimeMillis()));
        try {
            String str = JSONUtil.toJSONString(sortFields(req));
            param.setBizData(str);
            String tt = sortFieldsAndPrint(param);
            String MD5 = tt.concat("appSecret=" + key);
            log.info("加签原传:{}", MD5);
            String sign = MD5Utils.encrypt(MD5);
            param.setSign(sign);
            String reqbody = JSONUtil.toJSONString(param);
            log.info("请求参数:{}", reqbody);
            String response = HttpRequest.post(url.concat(trade)).body(reqbody).execute().body();
            log.info("返回结果:{}", response);
            PublicResp<OrderReturnResp> resp =JSONUtil.parseJSONStr2T(response,PublicResp.class);
            resp.setObjData(JSONUtil.parseJSONStr2T(resp.getBizData(),OrderReturnResp.class));
            return resp;
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }

    }


    /**
     * 查询退款订单
     * @param url
     * @param appId
     * @param mchRefundNo
     * @param refundOrderId
     * @param key
     * @return
     */
    public PublicResp<OrderReturnQueryReq>  returnOrderQuery(String url, String appId, String mchRefundNo, String refundOrderId, String key){
        OrderReturnQueryReq req=new OrderReturnQueryReq(mchRefundNo,refundOrderId);
        PublicParam param=new PublicParam(appId,null, SignTypeEnum.MD5.getValue(), null, DateUtils.getSdfTimes(), "1.0", String.valueOf(System.currentTimeMillis()));
        try {
            String str = JSONUtil.toJSONString(sortFields(req));
            param.setBizData(str);
            String tt = sortFieldsAndPrint(param);
            String MD5 = tt.concat("appSecret=" + key);
            log.info("加签原传:{}", MD5);
            String sign = MD5Utils.encrypt(MD5);
            param.setSign(sign);
            String reqbody = JSONUtil.toJSONString(param);
            log.info("请求参数:{}", reqbody);
            String response = HttpRequest.post(url.concat(trade)).body(reqbody).execute().body();
            log.info("返回结果:{}", response);
            PublicResp<OrderReturnQueryReq> resp =JSONUtil.parseJSONStr2T(response,PublicResp.class);
            resp.setObjData(JSONUtil.parseJSONStr2T(resp.getBizData(),OrderReturnQueryReq.class));
            return resp;
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }

    }






    public static String sortFieldsAndPrint(Object obj) throws IllegalAccessException {
        StringBuffer sb = new StringBuffer();
        Class<?> clazz = obj.getClass();
        Field[] fields = clazz.getDeclaredFields();

        // 按字段名称排序
        Arrays.sort(fields, Comparator.comparing(Field::getName));

        for (Field field : fields) {
            // 可能需要设置访问权限
            field.setAccessible(true);
            if ("sign".equals(field.getName())) {
                continue;
            }
            Object value = field.get(obj);


            StringBuffer param = new StringBuffer();
            param.append(field.getName());
            param.append("=");
            if (value instanceof String) {
                param.append(value);

            } else if (value instanceof Integer) {
                param.append(value);
            } else if (value instanceof Long) {
                param.append(value);
            }

            param.append("&");
            sb.append(param);
        }
        return sb.toString();
    }


    public static LinkedHashMap<String, Object> sortFields(Object obj) throws IllegalAccessException {

        LinkedHashMap<String, Object> map = new LinkedHashMap<>();
        Class<?> clazz = obj.getClass();
        Field[] fields = clazz.getDeclaredFields();

        // 按字段名称排序
        Arrays.sort(fields, Comparator.comparing(Field::getName));

        for (Field field : fields) {
            // 可能需要设置访问权限
            field.setAccessible(true);
            Object value = field.get(obj);
            if(value==null){
                continue;
            }

            map.put(field.getName(), value);
        }
        return map;
    }

    public   PublicResp<MainScanResp> mainScan(String url, String appId, String subject, String body, Long amount, String subAppId, String authCode, String orderNo, String storeId, String notifyUrl,
                                               String key
    ) {
        MainScanReq mainScanReq=null;
        if("66bab943ae82f63b50ae3cff".equals(appId)){

            mainScanReq = new MainScanReq(subject, body, amount, subAppId, "cny", authCode, orderNo, storeId, notifyUrl,1,"TA1824003985261588482",null);
            url="https://paymentweb.sxczgkj.cn";
        }else {
            mainScanReq = new MainScanReq(subject, body, amount, subAppId, "cny", authCode, orderNo, storeId, notifyUrl,0,null,null);
        }



        PublicParam param = new PublicParam(appId, "", SignTypeEnum.MD5.getValue(), null, cn.ysk.cashier.utils.DateUtils.getSdfTimes(), "1.0", String.valueOf(System.currentTimeMillis()));


        try {
            String str = JSONUtil.toJSONString(sortFields(mainScanReq));
            param.setBizData(str);
            String tt = sortFieldsAndPrint(param);
            String MD5 = tt.concat("appSecret=" + key);
            log.info("加签原传:{}", MD5);
            String sign = MD5Util.encrypt(MD5);
            param.setSign(sign);
            String reqbody = JSONUtil.toJSONString(param);
            log.info("请求参数:{}", reqbody);
            String response = HttpRequest.post(url.concat(micropay)).body(reqbody).execute().body();
            log.info("返回结果:{}", response);
            PublicResp<MainScanResp> resp =JSONUtil.parseJSONStr2T(response,PublicResp.class);

            resp.setObjData(JSONUtil.parseJSONStr2T(resp.getBizData(),MainScanResp.class));
            return resp;
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }

    }




    public static void main(String[] args) {
//        mainScan("https://paymentapi.sxczgkj.cn","6639fdc9fdf6f35856a23b3c", "测试支付", "测试支付", 1L, "wx212769170d2c6b2a", "131112206836873461", "CZ".concat(String.valueOf(System.currentTimeMillis())), "S2405103298", "https://", "fEu7tJgqaoPCA5QevafnSHfqHtO7rWcvhyfA0ltuab7rbpgOlab7CFCmqxMIbssUvbOnFKLdQqW5xUvhzb7FoxJNMAkIf2KDzlgDl6Diw1oBq56agSAFHhgYr3bLxXXI");
    }
}
