package com.xxfc.platform.universal.biz;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.github.wxiaoqi.security.common.biz.BaseBiz;
import com.github.wxiaoqi.security.common.msg.ObjectRestResponse;
import com.github.wxiaoqi.security.common.util.process.ResultCode;
import com.github.wxiaoqi.security.common.util.process.SystemConfig;
import com.github.wxiaoqi.security.common.util.result.JsonResultUtil;
import com.xxfc.platform.universal.entity.OrderPay;
import com.xxfc.platform.universal.entity.OrderRefund;
import com.xxfc.platform.universal.mapper.OrderRefundMapper;
import com.xxfc.platform.universal.vo.OrderRefundVo;
import com.xxfc.platform.universal.weixin.api.WxPayRefundUtils;
import com.xxfc.platform.universal.weixin.util.Snowflake;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.util.List;

/**
 * 订单支付退款表
 *
 * @author zjw
 * @email nishijjo@qq.com
 * @date 2019-05-28 16:17:42
 */
@Service
@Slf4j
public class OrderRefundBiz extends BaseBiz<OrderRefundMapper, OrderRefund> {

    @Autowired
    private OrderPayBiz payBiz;
    @Value("${universal.cert}")
    private String APICLIENT_CERT;

    @Autowired
    DictionaryBiz dictionaryBiz;

    //申请退款
    public JSONObject refund(OrderRefundVo orderRefundVo) throws Exception {
        if (orderRefundVo == null) {
            log.error("-----参数为空-----------");
            return JsonResultUtil.createFailedResult(ResultCode.NULL_CODE, "参数为空");
        }
        String order_no = orderRefundVo.getOrderNo();
        String appid = SystemConfig.APP_ID;
        String mchId = SystemConfig.APP_PARTNER;
        String partnerKey = SystemConfig.APP_PARTNER_KEY;
        Integer payAmount = orderRefundVo.getAmount();
        Integer refundAmount = orderRefundVo.getRefundAmount();

        //临时处理
//        Map<String, Dictionary> dictionaryMap = dictionaryBiz.getAll4Map();
//        Integer demotion = Integer.valueOf(dictionaryMap.get(UNIVERSAL_PAY + "_" + PAY_DEMOTION).getDetail());
//        payAmount = payAmount / demotion;
//        if (payAmount <= 0) {
//            payAmount = 1;
//        }
//
//        refundAmount = refundAmount / demotion;
//        if (refundAmount <= 0) {
//            refundAmount = 1;
//        }

        String refundDesc = StringUtils.isNotBlank(orderRefundVo.getRefundDesc()) ? orderRefundVo.getRefundDesc() : "审核通过，退款";
        String out_refund_no = Snowflake.build() + "";
        if (StringUtils.isBlank(order_no) || StringUtils.isBlank(appid) || StringUtils.isBlank(mchId) || StringUtils.isBlank(partnerKey)
                || payAmount == null || payAmount == 0 || refundAmount == null || refundAmount == 0) {
            log.error("-----参数为空-----------");
            return JsonResultUtil.createFailedResult(ResultCode.NULL_CODE, "参数为空");
        }
        log.error("-----payAmoun=======" + payAmount + "------refundAmount======" + refundAmount);
        Example example = new Example(OrderPay.class);
        example.createCriteria().andEqualTo("orderNo", order_no).andEqualTo("isDel", 0).andEqualTo("status", 1);
        List<OrderPay> list = payBiz.selectByExample(example);
        if (list.size() == 0) {
            log.error("---支付回调---trade_no=====" + order_no + "----订单不存在或未支付");
            return JsonResultUtil.createFailedResult(ResultCode.FAILED_CODE, order_no + "订单不存在或未支付");
        }
        OrderPay orderPay = list.get(0);
        String out_trade_no = orderPay.getTradeNo();
        boolean flag = false;
        if (orderPay.getPayWay() == 2 && orderPay.getPayType() == 1) {
            log.info("======支付宝APP支付退款中===========");
            flag = payBiz.alipayOrderRefund(out_trade_no, orderPay.getSerialNumber(), refundAmount, refundDesc,
                    out_trade_no + System.currentTimeMillis());
        } else if (orderPay.getPayWay() == 2 && orderPay.getPayType() == 2) {
            log.info("======支付宝预授权支付退款中===========");
            //需要根据实际传过来的参数类型来进行解冻或者预授权转支付
            if (orderRefundVo.getRefundAmount() != 0) { //解冻金额
                flag = payBiz.fundAuthOrderUnFreeze(out_refund_no,
                        orderPay.getSerialNumber(), orderRefundVo.getRefundAmount(), orderRefundVo.getRefundDesc());
            }
            //预授权转支付
            if(orderRefundVo.getFreeze2PayAmount() != null && orderRefundVo.getFreeze2PayAmount() != 0) {
                log.info("======预授权转支付===========");
                String refundTradeNo = Snowflake.build() + "";
                boolean isComplete = payBiz.tradePay(refundTradeNo,
                        orderPay.getSerialNumber(), orderRefundVo.getFreeze2PayAmount(),
                        orderRefundVo.getFreeze2PayDesc(), orderRefundVo.getFreeze2PayDesc());
                if (isComplete) {
                    OrderRefund orderRefund = new OrderRefund();
                    BeanUtils.copyProperties(orderRefund, orderRefundVo);
                    if (StringUtils.isNotBlank(orderRefundVo.getFreeze2PayDesc())) {
                        orderRefund.setRefundDesc("预授权转支付：" + orderRefundVo.getFreeze2PayDesc());
                    } else {
						orderRefund.setRefundDesc("预授权转支付");
					}
                    orderRefund.setRefundAmount(orderRefundVo.getFreeze2PayAmount());
                    orderRefund.setUserId(orderPay.getUserId());
                    orderRefund.setStatus(2);
                    orderRefund.setFinishTime(System.currentTimeMillis());
                    orderRefund.setRefundTradeNo(refundTradeNo);
                    orderRefund.setOutRefundNo(out_trade_no);
                    orderRefund.setSerialNumber(orderPay.getSerialNumber());
                    insertSelective(orderRefund);
                }
            }
        } else if(orderPay.getPayWay() == 1){
            log.info("======微信退款中===========");
            flag = WxPayRefundUtils.refund(appid, mchId, partnerKey, out_trade_no, out_refund_no, payAmount + "",
                    refundAmount + "", refundDesc, APICLIENT_CERT);
        }
        if (flag) {
            OrderRefund orderRefund = new OrderRefund();
            BeanUtils.copyProperties(orderRefund, orderRefundVo);
            if (StringUtils.isNotBlank(orderRefund.getRefundDesc())) {
                orderRefund.setRefundDesc(refundDesc);
            }
            orderRefund.setUserId(orderPay.getUserId());
            orderRefund.setStatus(2);
            orderRefund.setFinishTime(System.currentTimeMillis());
            orderRefund.setRefundTradeNo(out_refund_no);
            orderRefund.setOutRefundNo(out_trade_no);
            orderRefund.setSerialNumber(orderPay.getSerialNumber());
            insertSelective(orderRefund);
            return JsonResultUtil.createSuccessResultWithObj(out_refund_no);
        }
        return JsonResultUtil.createFailedResult(40004, "退款失败！");
    }

    public ObjectRestResponse tradeRefund(String tradNo, Integer refundAmount, String refundReason, String outRequestNo) {
        AlipayTradeRefundResponse refundResponse = payBiz.testTradeRefund(tradNo, refundAmount, refundReason, outRequestNo);
        log.info("预授权转支付退款： {}", refundResponse.getBody());
        if (refundResponse == null) {
            return ObjectRestResponse.createFailedResult(1002, "预授权转支付失败！");
        }
        OrderRefund orderRefund = selectByTradNo(tradNo);
        if (orderRefund == null) {
            return ObjectRestResponse.createFailedResult(1003, "预授权转支付商户订单不存在！");
        }
        orderRefund.setRefundTradeNo(outRequestNo);
        orderRefund.setId(null);
        if (refundResponse.getTradeNo() != null) {
            orderRefund.setSerialNumber(refundResponse.getTradeNo());
        }
        orderRefund.setRefundAmount(refundAmount);
        orderRefund.setRefundDesc(refundReason + "  预授权转支付商户订单号是：" + tradNo);
        orderRefund.setFinishTime(System.currentTimeMillis());
        orderRefund.setCrtTime(System.currentTimeMillis());
        orderRefund.setUpdTime(System.currentTimeMillis());
        mapper.insertSelective(orderRefund);
        return ObjectRestResponse.succ(orderRefund);
    }

    public OrderRefund selectByTradNo(String refundTradeNo) {
        if (StringUtils.isNotBlank(refundTradeNo)) {
            Example example = new Example(OrderRefund.class);
            example.createCriteria().andEqualTo("refundTradeNo", refundTradeNo);
            OrderRefund orderRefund = mapper.selectOneByExample(example);
            return orderRefund;
        }
        return null;
    }
}