package com.jpsoft.shinestar.modules.base.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.ijpay.core.enums.SignType;
import com.ijpay.core.kit.WxPayKit;
import com.ijpay.wxpay.WxPayApi;
import com.ijpay.wxpay.model.RefundModel;
import com.ijpay.wxpay.model.TransferModel;
import com.jpsoft.shinestar.config.AliPayConfig;
import com.jpsoft.shinestar.config.WxConfig;
import com.jpsoft.shinestar.config.WxJpsoftConfig;
import com.jpsoft.shinestar.config.WxTransferConfig;
import com.jpsoft.shinestar.modules.base.entity.OrderInfo;
import com.jpsoft.shinestar.modules.base.service.OrderInfoService;
import com.jpsoft.shinestar.modules.base.service.PersonInfoService;
import com.jpsoft.shinestar.modules.base.service.TransferService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 墨鱼_mo
 * @date 2020-6-1 8:58
 */
@Slf4j
@Transactional
@Component(value = "transferService")
public class TransferServiceImpl implements TransferService {

    @Autowired
    private WxTransferConfig wxTransferConfig;

    @Autowired
    private WxConfig wxConfig;

    @Autowired
    private OrderInfoService orderInfoService;

    @Autowired
    private WxJpsoftConfig wxJpsoftConfig;

    @Autowired
    private AliPayConfig aliPayConfig;

    @Autowired
    private PersonInfoService personInfoService;


    /**
     * 企业到零钱
     * @param openId
     * @param amount
     * @return
     * @throws Exception
     */
    @Override
    public Boolean transfer(String openId, String amount) throws Exception {

        BigDecimal tee = new BigDecimal(amount).multiply(new BigDecimal(100)).setScale(0);

        Map<String, String> params = TransferModel.builder()
                .mch_appid(wxConfig.getAppId())
                .mchid(wxTransferConfig.getMchId())
                .nonce_str(WxPayKit.generateStr())
                .partner_trade_no(WxPayKit.generateStr())
                .openid(openId)
                .check_name("NO_CHECK")
                .amount(tee.toString())
                .desc("积分兑换")
                .spbill_create_ip(wxTransferConfig.getIp())
                .build()
                .createSign(wxTransferConfig.getKey(), SignType.MD5, false);

        // 提现
        String transfers = WxPayApi.transfers(params, wxTransferConfig.getCertPath(), wxTransferConfig.getMchId());
        log.info("提现结果:" + transfers);
        Map<String, String> map = WxPayKit.xmlToMap(transfers);
        String returnCode = map.get("return_code");
        String resultCode = map.get("result_code");
        if (WxPayKit.codeIsOk(returnCode) && WxPayKit.codeIsOk(resultCode)) {
            // 提现成功
            return true;
        } else {
            // 提现失败
            throw new Exception("兑换失败," + map.get("return_msg") + "," + map.get("err_code_des"));
        }
    }

    /**
     * 微信退款
     * @param outOrderNo
     * @return
     * @throws Exception
     */
    @Override
    public Boolean refund(String outOrderNo) throws Exception {

        if (StringUtils.isBlank(outOrderNo)) {
            throw new Exception("订单号为空");
        }

        OrderInfo orderInfo = orderInfoService.findByOutOrderNo(outOrderNo);
        String totalFee = orderInfo.getTotalFee().multiply(new BigDecimal(100)).setScale(0).toString();


        Map<String, String> params = RefundModel.builder()
                .appid(wxConfig.getAppId())
                .mch_id(wxJpsoftConfig.getMchId())
                .sub_mch_id(wxJpsoftConfig.getSubMchId())
                .nonce_str(WxPayKit.generateStr())
                .transaction_id(orderInfo.getTransactionId())
                .out_trade_no(outOrderNo)
                .out_refund_no(WxPayKit.generateStr())
                .total_fee(totalFee)
                .refund_fee(totalFee)
                .notify_url(wxJpsoftConfig.getRefundUrl())
                .build()
                .createSign(wxJpsoftConfig.getMchKey(), SignType.HMACSHA256);
        //  .createSign(wxTransferConfig.getKey(), SignType.HMACSHA256);

        //  return WxPayApi.orderRefund(false, params, wxTransferConfig.getCertPath(), wxTransferConfig.getMchId());
        String result = WxPayApi.orderRefund(false, params, wxJpsoftConfig.getCertPath(), wxJpsoftConfig.getMchId());
        Map<String, String> map = WxPayKit.xmlToMap(result);
        String returnCode = map.get("return_code");
        String resultCode = map.get("result_code");
        if (WxPayKit.codeIsOk(returnCode) && WxPayKit.codeIsOk(resultCode)) {

            return true;
        } else {
            // 退款失败
            throw new Exception("退款失败," + map.get("return_msg") + "," + map.get("err_code_des"));
        }

    }

    /**
     * 支付宝退款
     * @param outOrderNo
     * @return
     * @throws Exception
     */
    @Override
    public Boolean aliPayRefund(String outOrderNo) throws Exception {


        if (StringUtils.isBlank(outOrderNo)) {
            throw new Exception("订单号为空");
        }
        OrderInfo orderInfo = orderInfoService.findByOutOrderNo(outOrderNo);
        if (orderInfo == null) {
            throw new Exception("订单不存在");
        }
        AlipayClient alipayClient = new DefaultAlipayClient(aliPayConfig.getServiceUrl(), aliPayConfig.getAppId(), aliPayConfig.getPrivateKey(), "json", aliPayConfig.getInputCharset(), aliPayConfig.getZfbPublicKey(), aliPayConfig.getSignType());
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();


        Map<String, Object> maps = new HashMap<>();
        maps.put("out_trade_no", orderInfo.getOutOrderNo());
        maps.put("refund_reason", "正常退款");
        maps.put("refund_amount", orderInfo.getPayFee());

        JSONObject extendParams = new JSONObject();

        extendParams.put("sys_service_provider_id", aliPayConfig.getMchId());
        maps.put("extend_params", extendParams);
        request.putOtherTextParam("app_auth_token", aliPayConfig.getAppAuthToken());
        //把订单信息转换为json对象的字符串
        String postdata = JSONObject.toJSONString(maps);
        request.setBizContent(postdata);


        AlipayTradeRefundResponse response = alipayClient.execute(request);


//        new Thread(() -> {
//            Map<String,Object> map1 = pointsUtil.refundPoints(orderInfo.getOutOrderNo());
//            if (StringUtils.isNotBlank((String)map1.get("renewalNum"))){
//                personInfoService.refundVipDays(orderInfo.getPayPersonId(),(Integer) map1.get("renewalNum"),orderInfo.getOutOrderNo());
//            }
//
//
//        }).start();
        return response.isSuccess();


    }
}
