package com.yonge.cooleshow.biz.dal.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yonge.cooleshow.auth.api.entity.SysUser;
import com.yonge.cooleshow.biz.dal.dao.UserOrderRefundDao;
import com.yonge.cooleshow.biz.dal.dto.req.AuthOperaReq;
import com.yonge.cooleshow.biz.dal.dto.req.OrderRefundReq;
import com.yonge.cooleshow.biz.dal.dto.search.OrderDetailSearch;
import com.yonge.cooleshow.biz.dal.dto.search.UserOrderRefundSearch;
import com.yonge.cooleshow.biz.dal.entity.*;
import com.yonge.cooleshow.biz.dal.enums.AuthStatusEnum;
import com.yonge.cooleshow.biz.dal.enums.GoodTypeEnum;
import com.yonge.cooleshow.biz.dal.enums.OrderStatusEnum;
import com.yonge.cooleshow.biz.dal.service.*;
import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
import com.yonge.cooleshow.biz.dal.vo.UserOrderRefundVo;
import com.yonge.cooleshow.biz.dal.vo.UserOrderVo;
import com.yonge.cooleshow.biz.dal.vo.res.RefundCreateRes;
import com.yonge.cooleshow.common.entity.HttpResponseResult;
import com.yonge.cooleshow.common.enums.PostStatusEnum;
import com.yonge.cooleshow.common.service.IdGeneratorService;
import com.yonge.toolset.base.exception.BizException;
import com.yonge.toolset.base.result.BaseResult;
import com.yonge.toolset.base.string.StringPool;
import com.yonge.toolset.base.util.StringUtil;
import com.yonge.toolset.payment.base.enums.PaymentClientEnum;
import com.yonge.toolset.payment.base.enums.TradeStatusEnum;
import com.yonge.toolset.payment.base.model.RefundBill;
import com.yonge.toolset.payment.base.model.callback.PaymentCallBack;
import com.yonge.toolset.payment.base.model.callback.RefundPaymentCallBack;
import com.yonge.toolset.payment.core.service.PaymentClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class UserOrderRefundServiceImpl extends ServiceImpl<UserOrderRefundDao, UserOrderRefund> implements UserOrderRefundService {
    private final static Logger log = LoggerFactory.getLogger(UserOrderRefundServiceImpl.class);

    @Autowired
    private UserOrderService orderService;
    @Autowired
    private UserOrderPaymentService orderPaymentService;
    @Autowired
    private UserOrderRefundBillService refundBillService;
    @Autowired
    private UserOrderDetailService orderDetailService;
    @Autowired
    private CourseGroupService courseGroupService;
    @Autowired
    private IdGeneratorService idGeneratorService;
    @Autowired
    private PaymentClient paymentClient;
    @Autowired
    private UserAccountService userAccountService;
    @Autowired
    private UserAccountRecordService userAccountRecordService;
    @Autowired
    private PlatformCashAccountRecordService platformCashAccountRecordService;

    //验证是否可以退款,获取退款金额信息
    private static final Map<GoodTypeEnum, Function<OrderRefundReq, HttpResponseResult<RefundCreateRes>>> refundCreate = new HashMap<>();
    //插入退款后执行
    private static final Map<GoodTypeEnum, Consumer<UserOrderDetailVo>> refundAfter = new HashMap<>();
    //退款完成后执行
    private static final Map<GoodTypeEnum, Consumer<UserOrderDetailVo>> refundSuccess = new HashMap<>();
    //退款未通过后执行
    private static final Map<GoodTypeEnum, Consumer<UserOrderDetailVo>> refundCancel = new HashMap<>();
    //退款失败执行
    private static final Map<GoodTypeEnum, Consumer<UserOrderDetailVo>> refundFailed = new HashMap<>();

    @PostConstruct
    private void init() {
        /**********退费单生成前******************/
        refundSuccess.put(GoodTypeEnum.LIVE, courseGroupService::refundSuccess);
    }

    @Override
    public UserOrderRefundVo detail(Long id) {
        UserOrderRefundVo detail = baseMapper.detail(id, null);
        return detail;
    }

    @Override
    public UserOrderRefundVo detail(Long id, Long userId) {
        UserOrderRefundVo detail = baseMapper.detail(id, userId);
        return detail;
    }

    @Override
    public IPage<UserOrderRefundVo> selectPage(IPage<UserOrderRefundVo> page, UserOrderRefundSearch query) {
        return page.setRecords(baseMapper.selectPage(page, query));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public HttpResponseResult<Boolean> orderRefund(OrderRefundReq refundReq) {
        UserOrderVo detail = orderService.detail(refundReq.getOrderNo(), refundReq.getUserId());
        if (null == detail || CollectionUtils.isEmpty(detail.getOrderDetailList())) {
            return HttpResponseResult.failed("未找到订单信息");
        }
        if (!OrderStatusEnum.PAID.equals(detail.getStatus())) {
            return HttpResponseResult.failed("订单状态异常");
        }
        if (StringUtil.isEmpty(detail.getTransNo()) && StringUtil.isEmpty(detail.getPaymentNo())) {
            return HttpResponseResult.failed("未找到订单付款信息");
        }
        refundReq.setOrderId(detail.getId());
        UserOrderPayment orderPayment = orderPaymentService.detailByTransNoOrPaymentNo(detail.getTransNo(), detail.getPaymentNo());
        if (null == orderPayment || !TradeStatusEnum.succeeded.equals(orderPayment.getStatus())) {
            return HttpResponseResult.failed("订单付款状态异常");
        }
        if (CollectionUtils.isEmpty(refundReq.getOredrDetilIds())) {
            //查询订单下未退款的所有详情订单
            List<UserOrderDetail> orderDetails = baseMapper.selectOrderRefundDetils(detail.getId());
            if (CollectionUtils.isEmpty(orderDetails)) {
                return HttpResponseResult.failed("订单中没有可退款商品");
            }
            refundReq.setOredrDetilIds(orderDetails.stream().map(UserOrderDetail::getId).collect(Collectors.toList()));
        }
        //退款的详情id
        List<Long> detilIds = new ArrayList<>();
        //退款金额
        BigDecimal actualPrice = BigDecimal.ZERO;
        for (UserOrderDetailVo vo : detail.getOrderDetailList()) {
            List<Long> collect = refundReq.getOredrDetilIds().stream().filter(o -> o.equals(vo.getId())).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collect)) {

                Function<OrderRefundReq, HttpResponseResult<RefundCreateRes>> refundCreateFunction = refundCreate.get(vo.getGoodType());
                if (!Objects.isNull(refundCreateFunction)) {
                    refundReq.setOredrDetil(vo);
                    HttpResponseResult<RefundCreateRes> apply = refundCreateFunction.apply(refundReq);
                    if (apply.getStatus()) {
                        detilIds.add(vo.getId());
                        actualPrice = actualPrice.add(apply.getData().getActualPrice());
                    }
                } else {
                    detilIds.add(vo.getId());
                    actualPrice = actualPrice.add(vo.getActualPrice());
                }
            }
        }
        if (BigDecimal.ZERO.compareTo(actualPrice) >= 0) {
            throw new BizException("退款金额不能为0");
        }

        String join = StringUtil.join(detilIds, ",");

        UserOrderRefund orderRefunds = new UserOrderRefund();
        orderRefunds.setUserId(detail.getUserId());
        orderRefunds.setOrderId(detail.getId());
        orderRefunds.setOrderNo(detail.getOrderNo());
        orderRefunds.setOredrDetilIds(join);
        orderRefunds.setStatus(AuthStatusEnum.DOING);
        orderRefunds.setApplyAmount(actualPrice);
        orderRefunds.setReason(refundReq.getReason());
        save(orderRefunds);

        for (UserOrderDetailVo vo : detail.getOrderDetailList()) {
            List<Long> collect = refundReq.getOredrDetilIds().stream().filter(o -> o.equals(vo.getId())).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collect)) {
                Consumer<UserOrderDetailVo> refundAfterConsumer = refundAfter.get(vo.getGoodType());
                if (!Objects.isNull(refundAfterConsumer)) {
                    refundAfterConsumer.accept(vo);
                }
            }
        }
        return HttpResponseResult.succeed(true);
    }

    @Override
    public HttpResponseResult<Boolean> doAuth(AuthOperaReq authOperaReq, SysUser user) {
        Long[] ids = StringUtil.toLongArray(StringPool.COMMA, authOperaReq.getId());
        for (Long id : ids) {
            UserOrderRefund orderRefund = baseMapper.selectById(id);
            if (null == orderRefund || !AuthStatusEnum.DOING.equals(orderRefund.getStatus())) {
                continue;
            }
            String oredrDetilIds = orderRefund.getOredrDetilIds();
            if (StringUtil.isEmpty(oredrDetilIds)) {
                continue;
            }

            orderRefund.setStatus(authOperaReq.getPass() ? AuthStatusEnum.PASS : AuthStatusEnum.UNPASS);
            orderRefund.setActualAmount(orderRefund.getApplyAmount());
            orderRefund.setOperateId(user.getId());
            orderRefund.setOperateReason(authOperaReq.getReason());
            orderRefund.setUpdateTime(new Date());

            if (authOperaReq.getPass()) {
                //通过调用退款接口
                doOrderRefund(orderRefund);
            } else {
                List<String> detilIds = Arrays.asList(oredrDetilIds.split(StringPool.COMMA));
                for (String detilId : detilIds) {
                    UserOrderDetailVo detail = orderDetailService.detail(Long.parseLong(detilId));
                    if (null == detail) {
                        continue;
                    }
                    //调用业务方法
                    Consumer<UserOrderDetailVo> refundCancelConsumer = refundCancel.get(detail.getGoodType());
                    if (!Objects.isNull(refundCancelConsumer)) {
                        refundCancelConsumer.accept(detail);
                    }
                }
            }
        }
        return HttpResponseResult.succeed(true);
    }


    @Transactional(rollbackFor = Exception.class)
    public HttpResponseResult<UserOrderRefundBill> orderRefund(String orderNo, String reason) {
        UserOrderVo detail = orderService.detail(orderNo, null);

        if (null == detail || CollectionUtils.isEmpty(detail.getOrderDetailList())) {
            return HttpResponseResult.failed("未找到订单信息");
        }
        if (!OrderStatusEnum.PAID.equals(detail.getStatus())) {
            return HttpResponseResult.failed("订单状态异常");
        }

        UserOrderPayment orderPayment = orderPaymentService.detailByTransNoOrPaymentNo(
                detail.getTransNo(), detail.getPaymentNo());
        if (null == orderPayment || !TradeStatusEnum.succeeded.equals(orderPayment.getStatus())) {
            return HttpResponseResult.failed("订单付款状态异常");
        }
        //查询订单下未退款的所有详情订单
        List<UserOrderDetail> orderDetails = baseMapper.selectOrderRefundDetils(detail.getId());
        if (CollectionUtils.isEmpty(orderDetails)) {
            return HttpResponseResult.failed("订单中没有可退款商品");
        }

        //退款的详情id
        List<Long> detilIds = orderDetails.stream().map(UserOrderDetail::getId).collect(Collectors.toList());

        OrderRefundReq orderRefundReq = new OrderRefundReq();
        orderRefundReq.setOrderId(detail.getId());
        orderRefundReq.setUserId(detail.getUserId());
        orderRefundReq.setReason(reason);
        orderRefundReq.setOredrDetilIds(detilIds);
        //退款金额
        BigDecimal actualPrice = BigDecimal.ZERO;
        for (UserOrderDetailVo vo : detail.getOrderDetailList()) {
            Optional<Long> first = detilIds.stream().filter(o -> o.equals(vo.getId())).findFirst();
            if (!first.isPresent()) {
                continue;
            }

            Function<OrderRefundReq, HttpResponseResult<RefundCreateRes>> refundCreateFunction = refundCreate.get(vo.getGoodType());
            if (!Objects.isNull(refundCreateFunction)) {
                orderRefundReq.setOredrDetil(vo);
                HttpResponseResult<RefundCreateRes> apply = refundCreateFunction.apply(orderRefundReq);
                if (apply.getStatus()) {
                    actualPrice = actualPrice.add(apply.getData().getActualPrice());
                }
            } else {
                actualPrice = actualPrice.add(vo.getActualPrice());
            }
        }
        String join = StringUtil.join(detilIds, ",");

        UserOrderRefund orderRefunds = new UserOrderRefund();
        orderRefunds.setUserId(detail.getUserId());
        orderRefunds.setOrderId(detail.getId());
        orderRefunds.setOrderNo(detail.getOrderNo());
        orderRefunds.setOredrDetilIds(join);
        orderRefunds.setStatus(AuthStatusEnum.PASS);
        orderRefunds.setApplyAmount(actualPrice);
        orderRefunds.setActualAmount(actualPrice);
        orderRefunds.setReason(reason);
        save(orderRefunds);

        for (UserOrderDetailVo vo : detail.getOrderDetailList()) {
            List<Long> collect = orderRefundReq.getOredrDetilIds().stream().filter(o -> o.equals(vo.getId())).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collect)) {
                Consumer<UserOrderDetailVo> refundAfterConsumer = refundAfter.get(vo.getGoodType());
                if (!Objects.isNull(refundAfterConsumer)) {
                    refundAfterConsumer.accept(vo);
                }
            }
        }
        return doOrderRefund(orderRefunds);
    }

    @Override
    public HttpResponseResult<UserOrderRefundBill> orderFailRefund(PaymentCallBack data, String orderNo, String reason) {
        UserOrderPayment orderPayment = orderPaymentService.detailByTransNoOrPaymentNo(data.getId(), data.getPaymentNo());
        if (null == orderPayment) {
            return HttpResponseResult.failed("未找到付款单");
        }
        //订单完成
        UserOrderVo detail = orderService.detail(orderPayment.getOrderNo(), null);
        if (null == detail) {
            return HttpResponseResult.failed("未找到订单");
        }
        //退款的详情id
        List<Long> detilIds = new ArrayList<>();

        OrderRefundReq orderRefundReq = new OrderRefundReq();
        orderRefundReq.setOrderId(detail.getId());
        orderRefundReq.setUserId(detail.getUserId());
        orderRefundReq.setReason(reason);
        //退款金额
        BigDecimal actualPrice = BigDecimal.ZERO;
        for (UserOrderDetailVo vo : detail.getOrderDetailList()) {
            detilIds.add(vo.getId());
            actualPrice = actualPrice.add(vo.getActualPrice());
        }
        String join = StringUtil.join(detilIds, ",");

        List<UserOrderRefund> list = list(Wrappers.<UserOrderRefund>lambdaQuery().eq(UserOrderRefund::getOrderNo, detail.getOrderNo()));
        if (!CollectionUtils.isEmpty(list)) {
            return HttpResponseResult.failed("已经存在退款单");
        }

        UserOrderRefund orderRefunds = new UserOrderRefund();
        orderRefunds.setUserId(detail.getUserId());
        orderRefunds.setOrderId(detail.getId());
        orderRefunds.setOrderNo(detail.getOrderNo());
        orderRefunds.setOredrDetilIds(join);
        orderRefunds.setStatus(AuthStatusEnum.PASS);
        orderRefunds.setApplyAmount(actualPrice);
        orderRefunds.setReason(reason);
        save(orderRefunds);

        for (UserOrderDetailVo vo : detail.getOrderDetailList()) {
            List<Long> collect = detilIds.stream().filter(o -> o.equals(vo.getId())).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collect)) {
                Consumer<UserOrderDetailVo> refundAfterConsumer = refundAfter.get(vo.getGoodType());
                if (!Objects.isNull(refundAfterConsumer)) {
                    refundAfterConsumer.accept(vo);
                }
            }
        }

        RefundBill refundBill = new RefundBill(orderPayment.getOpenType(),
                PaymentClientEnum.valueOf(orderPayment.getPaymentClient()), orderPayment.getPayChannel());
        refundBill.setTradeNo(data.getId());
        refundBill.setPaymentNo(data.getPaymentNo());

        //单号生成
        Long billNo = idGeneratorService.generatorId("billNo");
        refundBill.setRefundNo(billNo.toString());

        refundBill.setOrderAmt(orderPayment.getPayAmt());
        refundBill.setRefundAmt(orderPayment.getPayAmt());
        refundBill.setReason(reason);

        BaseResult<RefundBill> refundBillBaseResult = paymentClient.refundPayment(refundBill);
        log.info("退款返回: {} ", JSONObject.toJSONString(refundBillBaseResult));

        //入退款单表
        UserOrderRefundBill orderRefundBill = new UserOrderRefundBill();
        orderRefundBill.setRefundId(orderRefunds.getId());
        orderRefundBill.setBillNo(billNo.toString());
        orderRefundBill.setRefundAmt(orderRefunds.getActualAmount());
        if (refundBillBaseResult.getStatus()) {
            orderRefundBill.setTransNo(refundBillBaseResult.getData().getId());
            orderRefundBill.setStatus(TradeStatusEnum.pending);
        } else {
            orderRefundBill.setStatus(TradeStatusEnum.failed);
            orderRefundBill.setPayFailMsg(refundBillBaseResult.getMsg());
        }

        refundBillService.save(orderRefundBill);
        updateById(orderRefunds);
        return HttpResponseResult.succeed(orderRefundBill);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void refundPaymentCallBack(PaymentCallBack data) {
        if (TradeStatusEnum.succeeded.equals(data.getStatus())) {//退款成功
            paymentRefundSucceededHandle(data);
        } else if (TradeStatusEnum.failed.equals(data.getStatus())) {//退款失败
            paymentRefundFailedHandle(data, data.getErrMsg());
        }
    }

    @Override
    public HttpResponseResult<UserOrderRefundBill> orderRefound(String orderNo) {
        UserOrderVo detail = orderService.detail(orderNo, null);

        if (null == detail || CollectionUtils.isEmpty(detail.getOrderDetailList())) {
            return HttpResponseResult.failed("未找到订单信息");
        }
        if (!OrderStatusEnum.PAID.equals(detail.getStatus())) {
            return HttpResponseResult.failed("订单状态异常");
        }

        //查询订单下未退款的所有详情订单
        List<UserOrderDetail> orderDetails = baseMapper.selectOrderRefundDetils(detail.getId());
        if (CollectionUtils.isEmpty(orderDetails)) {
            return HttpResponseResult.failed("订单中没有可退款商品");
        }

        //退款的详情id
        List<Long> detilIds = orderDetails.stream().map(UserOrderDetail::getId).collect(Collectors.toList());

        OrderRefundReq orderRefundReq = new OrderRefundReq();
        orderRefundReq.setOrderId(detail.getId());
        orderRefundReq.setUserId(detail.getUserId());
        orderRefundReq.setReason("测试退款");
        orderRefundReq.setOredrDetilIds(detilIds);
        //退款金额
        BigDecimal actualPrice = BigDecimal.ZERO;
        for (UserOrderDetailVo vo : detail.getOrderDetailList()) {
            Optional<Long> first = detilIds.stream().filter(o -> o.equals(vo.getId())).findFirst();
            if (!first.isPresent()) {
                continue;
            }

            Function<OrderRefundReq, HttpResponseResult<RefundCreateRes>> refundCreateFunction = refundCreate.get(vo.getGoodType());
            if (!Objects.isNull(refundCreateFunction)) {
                orderRefundReq.setOredrDetil(vo);
                HttpResponseResult<RefundCreateRes> apply = refundCreateFunction.apply(orderRefundReq);
                if (apply.getStatus()) {
                    actualPrice = actualPrice.add(apply.getData().getActualPrice());
                }
            } else {
                actualPrice = actualPrice.add(vo.getActualPrice());
            }
        }
        String join = StringUtil.join(detilIds, ",");

        UserOrderRefund orderRefunds = new UserOrderRefund();
        orderRefunds.setUserId(detail.getUserId());
        orderRefunds.setOrderId(detail.getId());
        orderRefunds.setOrderNo(detail.getOrderNo());
        orderRefunds.setOredrDetilIds(join);
        orderRefunds.setStatus(AuthStatusEnum.PASS);
        orderRefunds.setApplyAmount(actualPrice);
        orderRefunds.setActualAmount(actualPrice);
        orderRefunds.setReason("测试退款");
        save(orderRefunds);

        for (UserOrderDetailVo vo : detail.getOrderDetailList()) {
            List<Long> collect = orderRefundReq.getOredrDetilIds().stream().filter(o -> o.equals(vo.getId())).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collect)) {
                Consumer<UserOrderDetailVo> refundAfterConsumer = refundAfter.get(vo.getGoodType());
                if (!Objects.isNull(refundAfterConsumer)) {
                    refundAfterConsumer.accept(vo);
                }
            }
        }
        return doOrderRefundTest(orderRefunds);
    }

    @Transactional(rollbackFor = Exception.class)
    HttpResponseResult<UserOrderRefundBill> doOrderRefund(UserOrderRefund orderRefund) {
        UserOrderPayment payment = orderPaymentService.getOne(Wrappers.<UserOrderPayment>lambdaQuery()
                .eq(UserOrderPayment::getOrderNo, orderRefund.getOrderNo())
                .eq(UserOrderPayment::getStatus, TradeStatusEnum.succeeded)
        );

        if (null == payment || !TradeStatusEnum.succeeded.equals(payment.getStatus())) {
            throw new BizException("订单状态异常");
        }

        RefundBill refundBill = new RefundBill(payment.getOpenType(),
                PaymentClientEnum.valueOf(payment.getPaymentClient()), payment.getPayChannel());
        refundBill.setTradeNo(payment.getTransNo());
        refundBill.setPaymentNo(payment.getPaymentNo());

        //单号生成
        Long billNo = idGeneratorService.generatorId("billNo");
        refundBill.setRefundNo(billNo.toString());

        refundBill.setOrderAmt(payment.getPayAmt());
        refundBill.setRefundAmt(orderRefund.getActualAmount());
        refundBill.setReason(orderRefund.getReason());


        BaseResult<RefundBill> refundBillBaseResult = paymentClient.refundPayment(refundBill);
        log.info("退款返回: {} ", JSONObject.toJSONString(refundBillBaseResult));

        //入退款单表
        UserOrderRefundBill orderRefundBill = new UserOrderRefundBill();
        orderRefundBill.setRefundId(orderRefund.getId());
        orderRefundBill.setBillNo(billNo.toString());
        orderRefundBill.setRefundAmt(orderRefund.getActualAmount());
        if (refundBillBaseResult.getStatus()) {
            orderRefundBill.setTransNo(refundBillBaseResult.getData().getId());
            orderRefundBill.setStatus(TradeStatusEnum.pending);
        } else {
            orderRefundBill.setStatus(TradeStatusEnum.failed);
            orderRefundBill.setPayFailMsg(refundBillBaseResult.getMsg());
        }
        refundBillService.save(orderRefundBill);
        updateById(orderRefund);

        //处理退款业务
        orderRefundSuccessBizHandle(orderRefund.getId());
        return HttpResponseResult.succeed(orderRefundBill);
    }


    @Transactional(rollbackFor = Exception.class)
    public HttpResponseResult<UserOrderRefundBill> doOrderRefundTest(UserOrderRefund orderRefund) {
        UserOrderPayment payment = orderPaymentService.getOne(Wrappers.<UserOrderPayment>lambdaQuery()
                .eq(UserOrderPayment::getOrderNo, orderRefund.getOrderNo())
                .eq(UserOrderPayment::getStatus, TradeStatusEnum.succeeded)
        );

        if (null == payment) {
            throw new BizException("订单状态异常");
        }

        RefundBill refundBill = new RefundBill(payment.getOpenType(),
                PaymentClientEnum.valueOf(payment.getPaymentClient()), payment.getPayChannel());
        refundBill.setTradeNo(payment.getTransNo());
        refundBill.setPaymentNo(payment.getPaymentNo());

        //单号生成
        Long billNo = idGeneratorService.generatorId("billNo");
        //入退款单表
        UserOrderRefundBill orderRefundBill = new UserOrderRefundBill();
        orderRefundBill.setRefundId(orderRefund.getId());
        orderRefundBill.setBillNo(billNo.toString());
        orderRefundBill.setRefundAmt(orderRefund.getActualAmount());
        orderRefundBill.setStatus(TradeStatusEnum.succeeded);
        refundBillService.save(orderRefundBill);
        updateById(orderRefund);

        //处理退款业务
        orderRefundSuccessBizHandle(orderRefund.getId());
        return HttpResponseResult.succeed(orderRefundBill);
    }

    /***
     * 处理回调-退款成功
     * @author liweifan
     * @param: data
     * @updateTime 2022/4/27 15:09
     */
    private void paymentRefundSucceededHandle(PaymentCallBack data) {
        RefundPaymentCallBack refundPaymentCallBack = data.getRefundPaymentCallBack();

        UserOrderRefundBill one = refundBillService.getOne(Wrappers.<UserOrderRefundBill>lambdaQuery().and(
                wrapper -> wrapper.eq(UserOrderRefundBill::getTransNo, refundPaymentCallBack.getTransNo())
                        .or().eq(UserOrderRefundBill::getBillNo, refundPaymentCallBack.getBillNo())
        ));
        //未找到退款单的和已经退款的不能再进行退款
        if (null == one || !TradeStatusEnum.pending.equals(one.getStatus())) {
            return;
        }
        one.setTransNo(refundPaymentCallBack.getTransNo());
        one.setBackRefundAmt(new BigDecimal(refundPaymentCallBack.getRefundAmt()));
        one.setStatus(TradeStatusEnum.succeeded);
        one.setUpdateTime(new Date());
        refundBillService.updateById(one);
    }

    /***
     * 处理回调-退款失败
     * @author liweifan
     * @param: data
     * @updateTime 2022/4/27 15:09
     */
    private void paymentRefundFailedHandle(PaymentCallBack data, String errMsg) {
        RefundPaymentCallBack refundPaymentCallBack = data.getRefundPaymentCallBack();

        UserOrderRefundBill one = refundBillService.getOne(Wrappers.<UserOrderRefundBill>lambdaQuery().and(
                wrapper -> wrapper.eq(UserOrderRefundBill::getTransNo, refundPaymentCallBack.getTransNo())
                        .or().eq(UserOrderRefundBill::getBillNo, refundPaymentCallBack.getBillNo())
        ));

        //未找到退款单的和已经退款的不能再进行退款
        if (null == one || !TradeStatusEnum.pending.equals(one.getStatus())) {
            return;
        }
        one.setTransNo(refundPaymentCallBack.getTransNo());
        one.setBackRefundAmt(new BigDecimal(refundPaymentCallBack.getRefundAmt()));
        one.setStatus(TradeStatusEnum.failed);
        one.setPayFailMsg(errMsg);
        one.setUpdateTime(new Date());
        refundBillService.updateById(one);

        orderRefundFailBizHandle(one.getRefundId());
    }

    /**
     * 处理退款业务
     *
     * @param refundId 退款单id
     */
    @Override
    public void orderRefundSuccessBizHandle(Long refundId) {
        //处理业务
        UserOrderRefund orderRefund = getById(refundId);
        if (!StringUtil.isEmpty(orderRefund.getOredrDetilIds())) {
            List<Long> ids = new ArrayList<>();
            for (String id : orderRefund.getOredrDetilIds().split(",")) {
                ids.add(Long.parseLong(id));
            }
            OrderDetailSearch search = new OrderDetailSearch();
            search.setIds(ids);
            search.setOrderNo(orderRefund.getOrderNo());
            List<UserOrderDetailVo> userOrderDetails = orderDetailService.selectList(search);

            for (UserOrderDetailVo vo : userOrderDetails) {
                Consumer<UserOrderDetailVo> refundAfterConsumer = refundSuccess.get(vo.getGoodType());
                if (!Objects.isNull(refundAfterConsumer)) {
                    refundAfterConsumer.accept(vo);
                }
                accountHandle(vo);
            }


        }
    }

    /**
     * 处理退款后账户
     *
     * @param vo
     */
    private void accountHandle(UserOrderDetailVo vo) {
        //处理老师入账
        List<UserAccountRecord> dataList = userAccountRecordService.selectRecordByOrderDetail(vo);
        for (UserAccountRecord userAccountRecord : dataList) {
            if (PostStatusEnum.WAIT.equals(userAccountRecord.getPostStatus())
                    || PostStatusEnum.FROZEN.equals(userAccountRecord.getPostStatus())) {
                userAccountService.accountChange(userAccountRecord, PostStatusEnum.CANCEL);
            }
        }
        //处理平台入账
        platformCashAccountRecordService.cancelRecord(vo.getOrderNo(),vo.getGoodType().getCode(),vo.getBizId());
    }

    /**
     * 处理退款失败业务
     *
     * @param refundId 退款单id
     */
    private void orderRefundFailBizHandle(Long refundId) {
        //处理业务
        UserOrderRefund orderRefund = getById(refundId);

        if (StringUtil.isEmpty(orderRefund.getOredrDetilIds())) {
            List<Long> ids = new ArrayList<>();
            for (String id : orderRefund.getOredrDetilIds().split(",")) {
                ids.add(Long.parseLong(id));
            }
            OrderDetailSearch search = new OrderDetailSearch();
            search.setIds(ids);
            search.setOrderNo(orderRefund.getOrderNo());
            List<UserOrderDetailVo> userOrderDetails = orderDetailService.selectList(search);

            for (UserOrderDetailVo vo : userOrderDetails) {
                Consumer<UserOrderDetailVo> refundAfterConsumer = refundFailed.get(vo.getGoodType());
                if (!Objects.isNull(refundAfterConsumer)) {
                    refundAfterConsumer.accept(vo);
                }
            }
        }
    }
}