package com.yiqi.payment;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.*;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradePayResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.ijpay.alipay.AliPayApi;
import com.ijpay.alipay.AliPayApiConfig;
import com.ijpay.alipay.AliPayApiConfigKit;
import com.ijpay.core.kit.WxPayKit;
import com.ijpay.wxpay.WxPayApi;
import com.yiqi.common.config.AlipayConfigs;
import com.yiqi.common.config.RuoYiConfig;
import com.yiqi.common.exception.ServiceException;
import com.yiqi.common.utils.DateUtils;
import com.yiqi.common.utils.spring.SpringUtils;
import com.yiqi.order.domain.dto.*;
import com.yiqi.order.domain.vo.weapp.AppPayRespVO;
import com.yiqi.system.service.ISysConfigRecordService;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Map;


@Service
public class AliPayService {

    private final static Logger logger = LoggerFactory.getLogger(AliPayService.class);

    /**
     * 支付宝支付配置
     */
    public static final String appId = "2019102468561642";

    /**
     * 商户私钥
     */
    public static final String privateKey = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCNHrehof5qxi6qiOVOUUAdx52RZb24iBBk32NyMhT5RvpgbjoT+tha5gdM/YJcjBGOK/K56Q3465BUwM2qLjT9EeF+jTC7CppI2CT2re5/c3vAN/XJ17LPhMlQBBiS6W1WRfWJZF1bT9430K1U8gF50E1Ilbqmt8+QR5TAxgl4mN35Whrhbtkh+qoEGmH0tihqebNiewP1/Lr57qVtANXKhoGj6b8pk8Vir76c3Q5EtSEw1goq3dsAt5bFYavY9WXpG0dexOLK1J8ggryPrUfukSMasQMfd7JX+zjsefXWFcx5oFS19tJKTSlMpnc3WeFJV1dGE9QUHTs8c+KRZQERAgMBAAECggEABDmJMdORtEyelQhoJQIVs06IjxPGrEGWjA6MAZ0yN4xCbqSeJH77/yynx0xHnNGsrN7v81Tg0DTtKzxia9faSkFAyPMdJFxa5hdic+gdHb+tUsHaH+LPPZsyE60rtyo51b1ebnCMwvEPLAiZR9O+65Cq36Nr5RXXpvAdqe/D1NJjYIpSPobQIu2cD5wOv87rzIyNTrFEQNqwRy58mEQBIJeUrGD6JnAY1DIOAiQ+4svUDuVQP+jBuK2vg6TCG/dcQFR8lemjHQKnRaBGpZ21FuDDoRfY5h8t7THP0Sdatr4rGOY70kAVZer+TmWPGuPmS1rNY8rD69oP+n3d410GgQKBgQDCx+YcwFs9xnbHTLGDukaYuZb4bMyyttfhvT6cYXbn2jzEBWhAe07onvDkGGl9CU6Z22Sc7O4cAK4GfIidUDiynd5yQrZBT5Ga87VSOJXPvQ7OwDAeelfatPCNYYQVIYLsSWxNGjeTvyR7JD0s3j1MqIdb8BcV/79OvtxyC0royQKBgQC5eUGGf+1roso3G5okcYp9wQTvP/qnm6lEggCzWkUdnbudQ/+6xwccZnfYqkHZ50dc9swXOibbQeBOnFGm1tUzucmhY0UJhPKatiAagEbfMgzVBkhEKOXnPt4s2iOQDn08sGvH3xYwc58gRrM05BI/pzF7pleX5i3t++pf7EdCCQKBgCIIgYmGhqq9kaVzHhUxKAKpctqHUCDt17ymr1jtorQSKsnpU/ToVrpIgzinl070oFo7vlG5CEW2TLHvcoNiL/XtpZ97TpMMzxku+gCayHpaw0qWxBGfONiLAvkBD+4NQ+37SkQSj6FuJXaqt1GupzFMxRHoWnBKlmew6521oWoZAoGAPCff4MfNMYPzIjyJmhhZWsAn4ZFWstYB6H5hy8oTcK+gEjnjz6iN3eA+Lr/J6+rfcn95Ym8x+xs6rUR2Fy7Gp6gyhW21DolYRmWbs/y2/90z3EPVXIYHSyFQ3itCLY8Ff5GY45Kvl7dofQdxSE5QvOR1YC1ra5D0hKOYONRhqEECgYBr8usEuVMld+fMLbGqc9Jkgu2FvPwjUUY4hOuO6bOiZ8VDujWDoZOWEuT1PCaFwbG3dV0oZNFic0VUOz1ziXlav6+cK6O11//TexFs0UNgdIYs+sllSTbZBM0n8fGy2gucYcQaV7mfp1O/2jlFnMIfhkFVjBLKMGAdAQAlNv7Mpg==";

    /**
     * 支付宝公钥
     */
    public static final String aliPayPublicKey = "";

    /**
     * 支付宝公钥
     */
    public static final String appCertPath = "/www/server/yiqi_wash_v2/paycert/appCertPublicKey_2019102468561642.crt";


    public static  String aliPayCertPath = "/www/server/yiqi_wash_v2/paycert/alipayCertPublicKey_RSA2.crt";


    public static  String aliPayRootCertPath = "/www/server/yiqi_wash_v2/paycert/alipayRootCert.crt";

    /**
     * 支付宝异步回调地址
     */
    private static String aliNotifyUrl = "";

    @Autowired
    ISysConfigRecordService sysConfigRecordService;
    @Autowired
    private RuoYiConfig ruoYiConfig;

    @PostConstruct
    public void init() {
        aliNotifyUrl = sysConfigRecordService.getCacheConfigRecordByKey("pay_ali_notify");
        if(ruoYiConfig.getEnv().equals("dev")){
            aliPayRootCertPath = "";
            aliPayCertPath = "";
        }
        initConfig();
    }

    /**
     *
     */
    private void initConfig() {
        AliPayApiConfig aliPayApiConfig = AliPayApiConfig.builder(); // 普通公钥方式
        try {
            aliPayApiConfig = AliPayApiConfig.builder()
                    .setAppId(appId)
                    .setCertModel(true)
                    .setAppCertPath(appCertPath)
                    .setAliPayCertPath(aliPayCertPath)
                    .setAliPayPublicKey("")
                    .setAliPayRootCertPath(aliPayRootCertPath)
                    .setPrivateKey(privateKey)
                    .setCharset("UTF-8")
                    .setServiceUrl("")
                    .setSignType("RSA2")
                    .buildByCert();
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        AliPayApiConfigKit.setThreadLocalAliPayApiConfig(aliPayApiConfig);
    }

    /**
     * 当面付
     */
    public PayResponseDTO facePay(PayOrderFaceToFaceDTO payOrderFaceToFaceDTO) {
        AlipayTradePayModel model = new AlipayTradePayModel();
        model.setSubject(payOrderFaceToFaceDTO.getSubjectTitle());
        model.setTotalAmount(payOrderFaceToFaceDTO.getPayAmount().toString());
//        model.setStoreId("门店");
        model.setTimeoutExpress("5m");
        model.setAuthCode(payOrderFaceToFaceDTO.getAuthCode());
        model.setOutTradeNo(payOrderFaceToFaceDTO.getRequestNo());
        model.setScene("bar_code");
        try {
            AlipayTradePayResponse response = AliPayApi.tradePayToResponse(model, aliNotifyUrl);
            logger.info("支付宝当面付下单成功，返回：{}", JSONUtil.toJsonStr(response));
            //接口调用成功
            if ("10000".equals(response.getCode())) {
                return PayResponseDTO.paySuccess(payOrderFaceToFaceDTO.getOrderNo(), response.getTradeNo());
            } else if ("10003".equals(response.getCode()) || "20000".equals(response.getCode())) {
                return PayResponseDTO.payWait(payOrderFaceToFaceDTO.getOrderNo());
            } else {
                return PayResponseDTO.payError(response.getSubMsg());
            }
        } catch (AlipayApiException e) {
            return PayResponseDTO.payError("下单失败，请重新支付");
        }
    }

    /**
     * 订单支付查询
     *
     * @param orderSn
     * @return
     */
    public PayResponseDTO orderPayQuery(String orderSn) {
        AlipayTradeQueryModel model = new AlipayTradeQueryModel();
        model.setOutTradeNo(orderSn);
        try {
            AlipayTradeQueryResponse response = AliPayApi.tradeQueryToResponse(AliPayApiConfigKit.getAliPayApiConfig().getAliPayClient(), true, model);
            logger.info("支付宝下单结果查询，返回：{}", JSONUtil.toJsonStr(response));
            //接口调用成功
            if ("10000".equals(response.getCode()) && "TRADE_SUCCESS".equals(response.getTradeStatus())) {
                return PayResponseDTO.paySuccess(orderSn, response.getTradeNo());
            }
            if ("20000".equals(response.getCode())) {
                return PayResponseDTO.payWait(orderSn);
            }
            if ("10000".equals(response.getCode()) && "WAIT_BUYER_PAY".equals(response.getTradeStatus())) {
                return PayResponseDTO.payWait(orderSn);
            }
            return PayResponseDTO.payError(response.getSubMsg() == null ? response.getMsg() : response.getSubMsg());
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return PayResponseDTO.payWait(orderSn);
        }
    }

    /**
     * 扫码支付，获取支付二维码
     */
    public String getScanCode(String orderSn, BigDecimal amount, String subject) {
        AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
        model.setSubject(subject);
        model.setTotalAmount(amount.toString());
        model.setStoreId("001");
        model.setTimeoutExpress("5m");
        model.setOutTradeNo(orderSn);
        try {
            String res = AliPayApi.tradePrecreatePayToResponse(model, aliNotifyUrl).getBody();
            JSONObject jsonObject = JSONObject.parseObject(res);
            return jsonObject.getJSONObject("alipay_trade_precreate_response").getString("qr_code");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 退款
     *
     * @param payRefundDTO
     * @return
     */
    public RefundResponseDTO orderRefund(PayRefundDTO payRefundDTO) {
        try {
            AlipayTradeRefundModel model = new AlipayTradeRefundModel();
            model.setTradeNo(payRefundDTO.getOutTradeNo());
            model.setOutRequestNo(payRefundDTO.getOutRequestNo());
            model.setRefundAmount(payRefundDTO.getRefundAmount().toString());
            model.setRefundReason(payRefundDTO.getRefundReason());
            AlipayTradeRefundResponse refundResponse = AliPayApi.tradeRefundToResponse(model);
            if (refundResponse.isSuccess()) {
                return RefundResponseDTO.refundSuccess(payRefundDTO.getOutRequestNo(), refundResponse.getTradeNo());
            } else {
                return RefundResponseDTO.refundError(refundResponse.getSubMsg());
            }
        } catch (Exception e) {
            logger.error("支付宝退款异常", e);
        }
        return RefundResponseDTO.refundError("支付宝退款异常");
    }


    /**
     * 小程序支付
     */
    public AppPayRespVO appPay(PayOrderAppDTO payOrderAppDTO) {

        AlipayTradeAppPayModel alipayTradeAppPayModel = new AlipayTradeAppPayModel();
        alipayTradeAppPayModel.setBody(payOrderAppDTO.getSubjectTitle());
        alipayTradeAppPayModel.setSubject(payOrderAppDTO.getSubjectTitle());
        alipayTradeAppPayModel.setOutTradeNo(payOrderAppDTO.getRequestNo());
        alipayTradeAppPayModel.setTotalAmount(payOrderAppDTO.getPayAmount().toString());
        if (payOrderAppDTO.getExpireTime() != null) {
            alipayTradeAppPayModel.setTimeoutExpress(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, payOrderAppDTO.getExpireTime()));
        }
        alipayTradeAppPayModel.setProductCode("QUICK_MSECURITY_PAY");
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        request.setBizModel(alipayTradeAppPayModel);
        request.setNotifyUrl(aliNotifyUrl);
        try {
            AlipayTradeAppPayResponse response = AliPayApi.certificateExecute(AliPayApiConfigKit.getAliPayApiConfig().getAliPayClient(), request);
            logger.info("支付宝APP下单，返回：{}", JSONUtil.toJsonStr(response));
            //接口调用成功
            if ("10000".equals(response.getCode())) {
                String orderStr = response.getBody();
                //定时校验订单状态，如果订单已经付款完成，则终止校验，如果超过5分钟，则修改订单状态为已取消
                return new AppPayRespVO(orderStr);
            } else {
                throw new ServiceException("支付宝下单失败，请重试：" + response.getSubMsg());
            }
        } catch (AlipayApiException e) {
            throw new ServiceException("支付宝下单失败，请重试");
        }
    }


    /**
     * 退款
     */
    public String refund(String outTradeNo, String tradeNo, BigDecimal totalAmount, BigDecimal refundAmount, String
            reason) {
        try {
            AlipayTradeRefundModel model = new AlipayTradeRefundModel();
            if (StringUtils.isNotEmpty(outTradeNo)) {
                model.setOutTradeNo(outTradeNo);
            }
            if (StringUtils.isNotEmpty(tradeNo)) {
                model.setTradeNo(tradeNo);
            }
            model.setRefundAmount(refundAmount.toString());
            model.setRefundReason(reason);
            AlipayTradeRefundResponse refundResponse = AliPayApi.tradeRefundToResponse(model);
            return refundResponse.getBody();
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return null;
    }

}
