package com.ruoyi.pay.type.ali.service.impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.ruoyi.pay.type.ali.param.AlipayOrderParam;
import com.ruoyi.pay.type.ali.service.AliPayService;
import com.ruoyi.response.ResponseData;
import com.ruoyi.utils.BusinessUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author liuyao
 * Created by Mr.Loe on 2019-01-08
 * 类说明：支付宝工具类
 */
@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class AliPayServiceImpl implements AliPayService {

    /**
     * 用户
     */
    @Value("${alipay.appid}")
    private String appid;

    @Value("${alipay.private-key}")
    private String privateKey;

    @Value("${alipay.ali-public-key}")
    private String aliPublicKey;

    @Value("${alipay.subject}")
    private String subject;


    @Value("${alipay.sign-type}")
    private String signType;

    @Value("${alipay.ali-url}")
    private String aliUrl;

    @Value("${alipay.product-code}")
    private String productCode;

    /**
     * 用户使用支付宝支付
     *
     * @return
     */
    @Override
    public ResponseData aliPayUserPay(String orderNo, BigDecimal amount, String returnUrl,Long orderId) {
        if (amount.compareTo(new BigDecimal(0)) != 1) {
            return ResponseData.error("支付金额不可小于0");
        }
        AlipayClient alipayClient = new DefaultAlipayClient(aliUrl, appid
                , privateKey, "json", "UTF-8"
                , aliPublicKey, signType);
        //向支付宝发送支付请求
        String urlEncodeOrderNum = "";
        try {
            //公众参数订单号
            urlEncodeOrderNum = URLEncoder.encode(orderNo, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        //创建Alipay支付请求对象
        AlipayTradeAppPayRequest payRequest = new AlipayTradeAppPayRequest();
        //回调地址
        payRequest.setNotifyUrl(returnUrl);
        AlipayOrderParam alipayOrderParam = new AlipayOrderParam();
        //流水号
        alipayOrderParam.setOut_trade_no(orderNo);
        alipayOrderParam.setProduct_code(productCode);
        alipayOrderParam.setSubject(subject);
        alipayOrderParam.setTotal_amount(amount);
        alipayOrderParam.setTimeout_express("15m");
        alipayOrderParam.setPassback_params(urlEncodeOrderNum);
        log.info(JSON.toJSONString(alipayOrderParam));
        //设置参数
        payRequest.setBizContent(JSON.toJSONString(alipayOrderParam));
        //输出页面的表单
        AlipayTradeAppPayResponse alipayTradeAppPayResponse;
        try {
            //调用SDK生成表单
            alipayTradeAppPayResponse = alipayClient.sdkExecute(payRequest);
        } catch (Exception e) {
            log.info("支付请求发送失败");
            return ResponseData.error("支付请求发送失败,请联系我们客服协助处理");
        }
        Map<String,Object> map = new HashMap<>();
        map.put("alipayTradeAppPayResponse",alipayTradeAppPayResponse);
        map.put("orderId",orderId);
        log.info(JSONObject.toJSONString(map));

        return ResponseData.success(map);
    }

    @Autowired
    private BusinessUtil businessUtil;

    @Override
    public ResponseData alipayRefund(String orderNo, String aliReturnPayId, BigDecimal price) {
        final AlipayClient alipayClient = new DefaultAlipayClient(aliUrl, appid
                , privateKey, "json", "UTF-8"
                , aliPublicKey, signType);

        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        Map map = new HashMap(4);
        map.put("out_trade_no", orderNo);
        //支付宝返回交易流水号
        map.put("trade_no", aliReturnPayId);
        map.put("out_request_no", UUID.randomUUID().toString().replace("-", ""));
        //退款金额
        map.put("refund_amount", price.setScale(2, BigDecimal.ROUND_DOWN));
        //退款原因
        map.put("refund_reason", "取消订单");
        String s = JSONObject.toJSONString(map);
        request.setBizContent(s);
        //请求支付宝，执行退款
        AlipayTradeRefundResponse response = null;
        try {
            response = alipayClient.execute(request);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        if (response.isSuccess()) {
            log.info("支付宝退款调用成功！");
        } else {
            log.info(response.getSubMsg());
            return ResponseData.error(response.getSubMsg() + ",退款失败");
        }
        return ResponseData.success();
    }


    @Value("${alipay.h5appid}")
    private String h5appid;

    @Value("${alipay.h5private-key}")
    private String h5privateKey;

    @Value("${alipay.h5ali-public-key}")
    private String h5aliPublicKey;


    //H5支付
    @Override
    public ResponseData aliH5Pay(String orderNum, BigDecimal price, String notify,Long orderId) {
        AlipayClient alipayClient = new DefaultAlipayClient(aliUrl, h5appid, h5privateKey, "json", "utf-8", h5aliPublicKey, "RSA2");
        // 创建API对应的request
        AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();
        alipayRequest.setNotifyUrl(notify);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("out_trade_no", orderNum);
        map.put("total_amount", price);
        map.put("subject", "");
//        map.put("seller_id", partner);
        map.put("product_code", "QUICK_WAP_PAY");
        // 填充业务参数
        alipayRequest.setBizContent(JSONObject.toJSONString(map));
        // 调用SDK生成表单
        String form = null;
        try {
            form = alipayClient.pageExecute(alipayRequest).getBody();
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return ResponseData.error("支付失败");
        }
        Map<String,Object> map2 = new HashMap<>();
        map2.put("alipayTradeAppPayResponse",form);
        map2.put("orderId",orderId);
        log.info(JSONObject.toJSONString(map2));
        return ResponseData.success(map2);
    }

}
