package com.ruoyi.hezhi.api.entity;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.hezhi.domain.TbMemberOrder;
import com.ruoyi.hezhi.service.ITbMemberOrderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.rmi.server.ServerCloneException;
import java.util.Map;

/**
 * 支付宝支付
 * @author Wzp
 */
@Component
public class AlipayService {

    private static Logger log = LoggerFactory.getLogger(AlipayService.class);

    @Resource
    private AliPayConfig aliPayConfig;

    @Resource
    private ITbMemberOrderService memberOrderService;

    public AlipayClient getAlipayClient() throws AlipayApiException {
        AlipayConfig alipayConfig = new AlipayConfig();
        alipayConfig.setServerUrl(aliPayConfig.getUrl());// 设置网关地址
        alipayConfig.setAppId(aliPayConfig.getAppId());// 设置应用APPID
        alipayConfig.setPrivateKey(aliPayConfig.getPrivateKey());// 设置应用私钥
        alipayConfig.setFormat("json");// 设置请求格式，固定值json
        alipayConfig.setCharset(aliPayConfig.getCharset());// 设置字符集
        alipayConfig.setAlipayPublicKey(aliPayConfig.getPublicKey());// 设置支付宝公钥
        alipayConfig.setSignType(aliPayConfig.getSignType());// 设置签名类型
        return new DefaultAlipayClient(alipayConfig);// 构造client
    }

    /**
     * 支付宝支付生成预付单
     * @param realPay 支付金额
     * @param paySn 支付单号
     * @param description 描述
     * @return 结果
     */
    public String aliPaySubmit(BigDecimal realPay, String paySn, String description,Long examId,Long memberUserId) {
        try {
            // 初始化SDK
            AlipayClient alipayClient = getAlipayClient();
            // 构造请求参数以调用接口
            AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
            AlipayTradePagePayModel model = new AlipayTradePagePayModel();

            model.setOutTradeNo(paySn);// 设置商户订单号
            model.setTotalAmount(realPay.toString());// 设置订单总金额
            model.setSubject(description);// 设置订单标题
            model.setProductCode("FAST_INSTANT_TRADE_PAY");// 设置产品码
            model.setQrPayMode("1");// 设置PC扫码支付的方式
            model.setQrcodeWidth(100L);// 设置商户自定义二维码宽度
            model.setRequestFromUrl("https://www.chsie.com.cn/payTheFees?examId="+examId+"&memberUserId="+memberUserId);

            request.setBizModel(model);
            request.setNotifyUrl(aliPayConfig.getNotifyUrl()+"/api/pay/aliPayBoilerNotify");
//            request.setReturnUrl("https://www.chsie.com.cn/examDetail?examId="+examId);//支付成功后跳转回哪个页面

            AlipayTradePagePayResponse response = alipayClient.pageExecute(request, "POST");
            // 如果需要返回GET请求，请使用
            if (response.isSuccess()){
                return response.getBody();
            }else {
                throw new ServerCloneException("支付宝支付失败");
            }
        }catch (Exception e){
            e.printStackTrace();
            throw new ServiceException("支付宝支付异常");
        }
    }

    /**
     * 支付宝退款
     * @param orderSn 订单号
     * @param payment 支付金额
     * @return 结果
     */
    public String tradeRefund(String orderSn, BigDecimal payment)  {

        System.out.println("开始调用支付宝退款****************");
        try {
            //实例化客户端
            AlipayClient alipayClient = this.getAlipayClient();
            //SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
            AlipayTradeRefundModel refundModel = new AlipayTradeRefundModel();
            refundModel.setOutTradeNo(orderSn);
            refundModel.setRefundAmount(payment.toString());
            refundModel.setRefundReason("退款");
            //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
            AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
            request.setBizModel(refundModel);
            AlipayTradeRefundResponse response = alipayClient.certificateExecute(request);

            if (response.isSuccess()){
                log.info("支付宝退款调用成功" + response);
                return "SUCCESS";
            }else{
                log.error("支付宝退款调用失败" + response);
                return "FAIL";
            }
        }catch(Exception e) {
            e.printStackTrace();
            log.error("支付宝退款错误！", e.getMessage());
            return "FAIL";
        }
    }

    /**
     * 校验回调参数
     * @param params 参数
     * @return
     */
    public String checkParams(Map<String, String> params) {
        // 查询订单是否是本平台的
        String outTradeNo = params.get("out_trade_no");

        TbMemberOrder order = memberOrderService.selectOrderByOrderNo(outTradeNo);
        if (ObjectUtils.isEmpty(order)) {
            return "FAIL";
        }
        // 验证商户app_id
        String appId = params.get("app_id");
        if(! appId.equals(aliPayConfig.getAppId())){
            log.error("app_id 错误");
            return "FAIL";
        }
        return "success";
    }


}
