package com.ghy.order.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.ghy.common.adapay.AdapayErrorCode;
import com.ghy.common.adapay.model.AdapayStatusEnum;
import com.ghy.common.adapay.model.DivMember;
import com.ghy.common.adapay.model.PaymentDTO;
import com.ghy.common.constant.UserConstants;
import com.ghy.common.core.text.Convert;
import com.ghy.common.enums.*;
import com.ghy.common.exception.base.BaseException;
import com.ghy.common.utils.AdapayUtils;
import com.ghy.common.utils.ObjectUtils;
import com.ghy.order.domain.OrderDetail;
import com.ghy.order.domain.OrderGoods;
import com.ghy.order.domain.OrderMaster;
import com.ghy.order.domain.OrderStatusCount;
import com.ghy.order.mapper.OrderDetailMapper;
import com.ghy.order.mapper.OrderMasterMapper;
import com.ghy.order.service.OrderDetailService;
import com.ghy.order.service.OrderGoodsService;
import com.ghy.order.service.OrderMasterService;
import com.ghy.payment.domain.FinancialChangeRecord;
import com.ghy.payment.domain.FinancialDetail;
import com.ghy.payment.domain.FinancialMaster;
import com.ghy.payment.service.AdapayService;
import com.ghy.payment.service.FinancialChangeRecordService;
import com.ghy.payment.service.FinancialDetailService;
import com.ghy.payment.service.FinancialMasterService;
import com.huifu.adapay.core.exception.BaseAdaPayException;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.*;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

import static java.time.temporal.ChronoField.*;

@Service
public class OrderDetailServiceImpl implements OrderDetailService {

    private static final Logger logger = LoggerFactory.getLogger(OrderDetailServiceImpl.class);

    private static final AtomicLong INDEX = new AtomicLong(1L);

    public static final DateTimeFormatter MINI_FORMATTER = new DateTimeFormatterBuilder()
            .appendValue(YEAR, 4).appendValue(MONTH_OF_YEAR, 2)
            .appendValue(DAY_OF_MONTH, 2).appendValue(HOUR_OF_DAY, 2)
            .appendValue(MINUTE_OF_HOUR, 2).appendValue(SECOND_OF_MINUTE, 2).toFormatter();

    @Resource
    private ThreadPoolTaskExecutor executor;
    @Resource
    private OrderDetailMapper orderDetailMapper;
    @Resource
    private OrderMasterMapper orderMasterMapper;
    @Resource
    private AdapayService adapayService;
    @Resource
    private OrderMasterService orderMasterService;
    @Resource
    private FinancialMasterService financialMasterService;
    @Resource
    private FinancialDetailService financialDetailService;
    @Resource
    private FinancialChangeRecordService financialChangeRecordService;
    @Resource
    private OrderGoodsService orderGoodsService;

    // Adapay 手续费率 默认0.008
    @Value("${adapay.fee_rate:0.008}")
    private String feeRate;

    @Override
    public int insertOrderDetail(OrderDetail orderDetail) {
        return orderDetailMapper.insertOrderDetail(orderDetail);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateOrderDetail(OrderDetail orderDetail) {
        if (orderDetail.getOrderStatus() == null) {
            return orderDetailMapper.updateOrderDetail(orderDetail);
        }
        int orderStatus = orderDetail.getOrderStatus();
        boolean flag = Boolean.TRUE;
        // 查子单信息
        OrderDetail originOrderDetail = this.orderDetailMapper.selectById(orderDetail.getId());
        int result = orderDetailMapper.updateOrderDetail(orderDetail);
        // 查询主单关联商品
        List<OrderGoods> masterOrderGoodsList = orderGoodsService.selectByOrderMasterId(originOrderDetail.getOrderMasterId());
        Map<Long, OrderGoods> masterGoodsMap = masterOrderGoodsList.stream().collect(Collectors.toMap(OrderGoods::getGoodsStandardId, obj -> obj));
        // 子单修改从服务中到确认中需要修改已服务商品数量，从确认中到服务中需要重置已服务商品数量
        if (OrderStatus.FINISH_CHECK.code() == orderDetail.getOrderStatus() && originOrderDetail.getOrderStatus() < OrderStatus.FINISH_CHECK.code()) {
            List<OrderGoods> orderGoodsList = orderGoodsService.selectByOrderDetailId(orderDetail.getId());
            orderGoodsList.stream().forEach(orderGoods -> {
                orderGoods.setServerGoodsNum(orderGoods.getGoodsNum());
                orderGoodsService.updateOrderGoods(orderGoods);
                // 主单关联商品相应修改已服务数量
                Integer masterServerGoodsNum = masterGoodsMap.get(orderGoods.getGoodsStandardId()).getServerGoodsNum();
                masterGoodsMap.get(orderGoods.getGoodsStandardId()).setServerGoodsNum(masterServerGoodsNum += orderGoods.getServerGoodsNum());
            });
        } else if (OrderStatus.FINISH_CHECK.code() == originOrderDetail.getOrderStatus() && orderDetail.getOrderStatus() < OrderStatus.FINISH_CHECK.code()) {
            List<OrderGoods> orderGoodsList = orderGoodsService.selectByOrderDetailId(orderDetail.getId());
            orderGoodsList.stream().forEach(orderGoods -> {
                orderGoods.setServerGoodsNum(0);
                orderGoodsService.updateOrderGoods(orderGoods);
                // 主单关联商品相应修改已服务数量
                Integer masterServerGoodsNum = masterGoodsMap.get(orderGoods.getGoodsStandardId()).getServerGoodsNum();
                masterGoodsMap.get(orderGoods.getGoodsStandardId()).setServerGoodsNum(masterServerGoodsNum -= orderGoods.getGoodsNum());
            });
        }
        // 更新主单关联商品
        masterOrderGoodsList.stream().forEach(masterOrderGoods -> {
            orderGoodsService.updateOrderGoods(masterOrderGoods);
        });

        OrderDetail detailInfo = this.orderDetailMapper.selectById(orderDetail.getId());
        // 判断是否需要更新主单状态.即是否有
        // 1.更新大于当前  detail 1/2/3
        for (OrderDetail detail : orderDetailMapper.selectByOrderMasterId(detailInfo.getOrderMasterId())) {
            if (detail.getOrderStatus() < orderStatus) {
                flag = false;
                break;
            }
        }
        // 判断主单是否全部派单
        boolean allAssign = orderMasterService.isAllAssign(detailInfo.getOrderMasterId());
        if (flag && allAssign) {
            OrderMaster orderMaster = orderMasterMapper.selectById(detailInfo.getOrderMasterId());
            if (ObjectUtils.isEmpty(orderDetail.getExpectTimeStart())) {
                orderMaster.setOrderStatus(orderStatus);
                orderMasterMapper.updateOrderMaster(orderMaster);
            }
        }
        return result;
    }

    @Override
    public List<OrderDetail> selectOrderDetailList(OrderDetail orderDetail) {
        return orderDetailMapper.selectOrderDetailList(orderDetail);
    }

    @Override
    public OrderDetail selectById(Long orderDetailId) {
        return orderDetailMapper.selectById(orderDetailId);
    }

    @Override
    public List<OrderDetail> selectByOrderMasterId(Long orderMasterId) {
        return orderDetailMapper.selectByOrderMasterId(orderMasterId);
    }

    @Override
    public int deleteOrderDetailByIds(String ids) {
        Long[] orderDetailIds = Convert.toLongArray(ids);
        return orderDetailMapper.deleteOrderDetailByIds(orderDetailIds);
    }

    @Override
    public String checkOrderDetailCodeUnique(OrderDetail orderDetail) {
        long orderDetailId = orderDetail.getId() == null ? -1L : orderDetail.getId();
        OrderDetail info = orderDetailMapper.checkOrderDetailCodeUnique(orderDetail.getCode());
        if (info != null && info.getId() != orderDetailId) {
            return UserConstants.ORDER_CODE_NOT_UNIQUE;
        }
        return UserConstants.ORDER_CODE_UNIQUE;
    }

    @Override
    public synchronized String createCode() {
        INDEX.compareAndSet(9999L, 1L);
        LocalDateTime now = LocalDateTime.now();
        // 得到的CODE长度相同
        return "od" + now.format(MINI_FORMATTER) + String.format("%04d", INDEX.getAndIncrement());
    }

    @Override
    public Map<Long, List<OrderDetail>> byOrderIdInMap(List<Long> orderIdList) {
        Map<Long, List<OrderDetail>> longByOrderDetailListMap = new HashMap<>();
        if (orderIdList != null && orderIdList.size() > 0) {
            List<OrderDetail> orderDetailList = orderDetailMapper.getByOrderIdList(orderIdList);
            if (orderDetailList != null && orderDetailList.size() > 0) {
                for (OrderDetail orderDetail : orderDetailList) {
                    List<OrderDetail> orderDetailListByMapCrw = longByOrderDetailListMap.get(orderDetail.getOrderMasterId());
                    if (orderDetailListByMapCrw != null && orderDetailListByMapCrw.size() > 0) {
                        List<OrderDetail> orderDetailListByMapNew = new ArrayList<>();
                        orderDetailListByMapNew.add(orderDetail);
                        longByOrderDetailListMap.put(orderDetail.getOrderMasterId(), orderDetailListByMapNew);
                    } else {
                        List<OrderDetail> orderDetailListByMapNew = new ArrayList<>();
                        orderDetailListByMapNew.add(orderDetail);
                        longByOrderDetailListMap.put(orderDetail.getOrderMasterId(), orderDetailListByMapNew);
                    }
                }
            }
        }
        return longByOrderDetailListMap;
    }

    @Override
    public void applyForCancel(Long orderDetailId) throws BaseAdaPayException {
        OrderDetail orderDetail = selectById(orderDetailId);
        Assert.notNull(orderDetail, "找不到对应的子订单");

        switch (orderDetail.getOrderStatus()) {
            case 0:
            case 1: // 待接单和待排期状态可直接取消
                cancel(orderDetailId);
                break;
            case 2: // 待上门状态需要师傅同意才能取消
                orderDetailMapper.updateStatus(orderDetailId, OrderStatus.GOING_CANCEL.code());
                logger.info("Set OrderDetail[{}].orderStatus = {}", orderDetailId, OrderStatus.GOING_CANCEL.code());
                break;
            case 3: // 服务中状态需要师傅同意才能取消
                orderDetailMapper.updateStatus(orderDetailId, OrderStatus.SERVER_CANCEL.code());
                logger.info("Set OrderDetail[{}].orderStatus = {}", orderDetailId, OrderStatus.SERVER_CANCEL.code());
                break;
            case 4: // 待确认状态需要师傅同意才能取消
                orderDetailMapper.updateStatus(orderDetailId, OrderStatus.FINISH_CHECK_CANCEL.code());
                logger.info("Set OrderDetail[{}].orderStatus = {}", orderDetailId, OrderStatus.FINISH_CHECK_CANCEL.code());
                break;
            default: // 其他状态不可取消
                throw new IllegalArgumentException("这个子订单不能取消了");
        }
    }

    /**
     * 子订单取消
     *
     * @param orderDetailId 子订单ID
     */
    @Transactional(rollbackFor = Exception.class)
    public void cancel(long orderDetailId) throws BaseAdaPayException {
        logger.info("子订单取消 orderDetailId = {}", orderDetailId);
        OrderDetail orderDetail = selectById(orderDetailId);
        Assert.notNull(orderDetail, "找不到对应的子订单");
        if (OrderStatus.FINISH.code() == orderDetail.getOrderStatus() || OrderStatus.CANCEL.code() == orderDetail.getOrderStatus()) {
            logger.info("子订单[id={}]状态不正确，orderStatus={}", orderDetailId, orderDetail.getOrderStatus());
            return;
        }
        // 更新子订单状态
        orderDetailMapper.updateStatus(orderDetailId, OrderStatus.CANCEL.code());
        logger.info("Set OrderDetail[{}].orderStatus = {}", orderDetailId, OrderStatus.CANCEL.code());
        // 查询出所有的子订单  就走主订单取消流程
        List<OrderDetail> orderDetails = orderDetailMapper.selectByOrderMasterId(orderDetail.getOrderMasterId());
        // 判断是否是已付款的订单,未付款不需要退款
        FinancialMaster financialMaster = financialMasterService.selectByOrderMasterId(orderDetail.getOrderMasterId());
        Assert.notNull(financialMaster, "找不到对应的财务单");
        // 发起退款
        refund(orderDetail);
        // 如果除了这个子订单以外 没有其它未取消的订单
        boolean allCancel = true;
        for (OrderDetail od : orderDetails) {
            if (!od.getOrderStatus().equals(OrderStatus.CANCEL.code())) {
                allCancel = false;
                break;
            }
        }
        // 判断主单是否全部派单
        boolean allAssign = orderMasterService.isAllAssign(orderDetail.getOrderMasterId());
        // 如果主单已经全部派单 并且 所有单都已经取消
        if (allAssign && allCancel) {
            logger.info("主订单[id={}]下所有的子订单都被取消 直接进入主订单取消流程", orderDetail.getOrderMasterId());
            orderMasterService.cancelAgree(orderDetail.getOrderMasterId(), 1);
        }
    }

    /**
     * 子单全额退款
     *
     * @param orderDetail
     * @throws BaseAdaPayException
     */
    public void refund(OrderDetail orderDetail) throws BaseAdaPayException {
        Long orderDetailId = orderDetail.getId();
        OrderMaster orderMaster = orderMasterMapper.selectById(orderDetail.getOrderMasterId());
        Assert.notNull(orderMaster, "OrderMaster is null !");
        FinancialMaster financialMaster = financialMasterService.selectByOrderMasterId(orderMaster.getId());
        Assert.notNull(financialMaster, "FinancialMaster is null !");
        FinancialDetail financialDetail = financialDetailService.selectByOrderDetailId(orderDetailId);
        Assert.notNull(financialMaster, "找不到支付记录");
        boolean paid = PayStatus.PAID.getCode().equals(financialMaster.getPayStatus()) ||
                PayStatus.PAYED_ADD.getCode().equals(financialMaster.getPayStatus());

        // 主财务单金额
        BigDecimal masterMoney = financialMaster.getPayMoney();
        // 子财务单金额
        BigDecimal detailMoney = financialDetail.getPayMoney();

        List<FinancialChangeRecord> fcrList = financialChangeRecordService.selectByDetailIds(orderDetailId.toString());
        // 先把这个子单的加价单全退了
        for (FinancialChangeRecord fcr : fcrList) {
            if (PayStatus.PAID.getCode().equals(fcr.getPayStatus()) || PayStatus.PAYED_ADD.getCode().equals(fcr.getPayStatus())) {
                executor.execute(() -> financialChangeRecordService.refund(orderMaster.getDeptId(), fcr.getId()));
                // 主/子财务单里也加上了加价单的金额 所以这里减掉
                masterMoney = masterMoney.subtract(fcr.getChangeMoney());
                detailMoney = detailMoney.subtract(fcr.getChangeMoney());
            }
        }

        // detailMoney ≤ 0 不需要退款
        if (BigDecimal.ZERO.compareTo(detailMoney) > -1) {
            logger.info("子订单[{}]不需要退款 payMoney={}元", orderDetail.getId(), detailMoney);
            // 更新子财务单金额和状态
            financialDetail.setPayStatus(paid ? PayStatus.REFUND.getCode() : PayStatus.CANCEL.getCode());
            financialDetail.setPayMoney(detailMoney);
            financialDetailService.updateFinancialDetail(financialDetail);

            // 更新主财务单金额
            financialMaster.setPayMoney(masterMoney);
            financialMasterService.updateFinancialMaster(financialMaster);
            return;
        }

        // 更新子财务单金额和状态 如果是已支付改退款中 如果是未支付改为取消
        financialDetail.setPayMoney(detailMoney);
        financialDetail.setPayStatus(paid ? PayStatus.REVERSING.getCode() : PayStatus.CANCEL.getCode());
        financialDetailService.updateFinancialDetail(financialDetail);

        // 更新主财务单金额
        financialMaster.setPayMoney(masterMoney.subtract(detailMoney));
        financialMasterService.updateFinancialMaster(financialMaster);

        if (!paid) {
            logger.info("子订单[id={}]未支付 不需要退款", orderDetailId);
            return;
        }
        Assert.hasText(financialMaster.getPaymentId(), "找不到订单的支付记录，请联系管理员");
        // 发起退款
        String refundAmt = AdapayUtils.bigDecimalToString(detailMoney);
        logger.info("子订单[id={}]发起退款: refundAmt={}元", orderDetailId, refundAmt);
        JSONObject response = adapayService.payReverse(orderMaster.getDeptId(), financialMaster.getPaymentId(), refundAmt, RefundType.ROD);
        boolean status = AdapayStatusEnum.pending.code.equals(response.getString("status")) ||
                AdapayStatusEnum.succeeded.code.equals(response.getString("status"));
        // 如果退款失败 这里携带失败原因抛出异常 回滚订单状态
        Assert.isTrue(status, response.getString("error_msg"));
        logger.info("子订单[id={}]退款成功", orderDetailId);
        executor.execute(() -> {
            String reverseId = response.getString("id");
            FinancialDetail fd2update = new FinancialDetail();
            fd2update.setId(financialDetail.getId());
            fd2update.setReverseId(reverseId);
            financialDetailService.updateFinancialDetail(fd2update);
        });

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelAgree(Long orderDetailId, Integer agree) throws BaseAdaPayException {
        OrderDetail orderDetail = selectById(orderDetailId);
        Assert.notNull(orderDetail, "找不到对应的子订单");
        if (Integer.valueOf(1).equals(agree)) {
            // 师傅同意取消订单
            cancel(orderDetailId);
        } else {
            // 师傅不同意取消订单
            Integer orderStatus = orderDetail.getOrderStatus();
            // 修改主订单状态为原来的状态
            orderDetailMapper.updateStatus(orderDetailId, Math.abs(orderStatus));
        }
    }

    @Override
    public void updateByOrderMasterId(OrderDetail orderDetail) {
        orderDetailMapper.updateByOrderMasterId(orderDetail);
    }

    @Override
    public List<OrderDetail> selectByStatus(List<Integer> status) {
        Assert.isTrue(!CollectionUtils.isEmpty(status), "订单状态为空");
        return orderDetailMapper.selectByStatus(status);
    }

    /**
     * 子订单确认完成 暂时先用 synchronized 来避免重复提交
     * 1.修改子订单状态为 OrderStatus.FINISH.code
     * 2.将子订单对应的子财务单确认分账
     * 3.提现至银行卡
     *
     * @param orderDetailId 子订单ID
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized void finish(Long orderDetailId) throws BaseAdaPayException {
        // 校验订单
        OrderDetail orderDetail = selectById(orderDetailId);
        if (orderDetail == null) {
            throw new BaseException("找不到对应的子订单");
        }
        String odCode = orderDetail.getCode();
        Assert.isTrue(!orderDetail.getOrderStatus().equals(OrderStatus.FINISH.code()), "订单已经是完成状态");
        FinancialMaster financialMaster = financialMasterService.selectByOrderMasterId(orderDetail.getOrderMasterId());
        if (financialMaster == null) {
            throw new BaseException("找不到主财务单");
        }
        PaymentDTO payment = financialMasterService.selectPaymentById(financialMaster.getPaymentId());
        if (payment == null) {
            throw new BaseException("找不到支付记录");
        }
        // 子订单对应的子财务单只有一条 直接取出
        FinancialDetail financialDetail = financialDetailService.selectByOrderDetailId(orderDetailId);
        if (financialDetail == null) {
            throw new BaseException("FinancialDetail is null!!!");
        }
        if (financialDetail.getPayStatus() != 1) {
            throw new BaseException("订单不是“已支付”状态");
        }

        // 修改子订单状态为完成
        updateStatus(orderDetailId, OrderStatus.FINISH.code());

        Long financialMasterId = financialDetail.getFinancialMasterId();
        // 找到 type=平台抽成 的子财务单 用来承担手续费
        List<FinancialDetail> details = financialDetailService.selectByFinancialMasterIdAndType(financialMasterId, FinancialDetailType.PLATFORM_FEE.getCode());
        FinancialDetail platformFeeFD = details.get(0);
        FinancialDetail fdUpdate = new FinancialDetail();
        fdUpdate.setId(platformFeeFD.getId());
        fdUpdate.setPayMoney(platformFeeFD.getPayMoney());
        logger.debug("子订单[code={}]的完单流程开始", odCode);

        // 加价单手续费补偿成功与否
        boolean compensate = false;
        // 加价单手续费
        BigDecimal feeAmt = null;
        // 待提现金额
        BigDecimal dtx = BigDecimal.ZERO;
        // 加价金额
        BigDecimal addPrice;
        // 子单收款人的memberId
        String memberId = AdapayUtils.getWorkerMemberId(financialDetail.getPayeeId(), financialDetail.getDeptId());

        // --------------------- 改价单分账部分 start ---------------------
        // 查询子订单的加价记录
        List<FinancialChangeRecord> financialChangeRecords = financialChangeRecordService.selectByDetailIds(String.valueOf(orderDetailId));
        if (CollectionUtils.isNotEmpty(financialChangeRecords)) {
            // 改价记录只会有一条 直接取出
            FinancialChangeRecord fcRecord = financialChangeRecords.get(0);
            boolean paid = PayStatus.PAID.getCode().equals(fcRecord.getPayStatus());
            boolean payedAdd = PayStatus.PAYED_ADD.getCode().equals(fcRecord.getPayStatus());
            if (paid || payedAdd) {
                ArrayList<DivMember> divMembers = new ArrayList<>();
                addPrice = fcRecord.getChangeMoney();
                // 待提现金额里加入改价单金额
                dtx = dtx.add(fcRecord.getChangeMoney());
                // 这里先自己承担手续费 后面再用平台抽成来补偿
                DivMember divMember = new DivMember(memberId, AdapayUtils.bigDecimalToString(fcRecord.getChangeMoney()), true);
                divMembers.add(divMember);
                //调用分账
                logger.info("子订单[code={}]的[改价单]发起分账", odCode);
                JSONObject response = adapayService.paymentConfirm(financialDetail.getDeptId(), fcRecord.getRemark(),
                        payment.getOrderNo() + "_" + System.currentTimeMillis(),
                        AdapayUtils.bigDecimalToString(fcRecord.getChangeMoney()), divMembers, null, null);
                if (AdapayStatusEnum.succeeded.code.equals(response.getString("status"))) { // 分账成功
                    logger.info("子订单[code={}]的[改价单]分账成功", odCode);
                    // 这是被扣掉的手续费 按理说这里肯定大于0
                    String fee_amt = response.getString("fee_amt");
                    feeAmt = new BigDecimal(fee_amt);
                    if (feeAmt.compareTo(platformFeeFD.getPayMoney()) < 0 && !"0.00".equals(fee_amt)) {
                        // 当 0.00<改价单的手续费<=平台抽成金额 时
                        // 用平台抽成来补偿改价单的手续费 修改平台抽成子财务单金额
                        fdUpdate.setPayMoney(fdUpdate.getPayMoney().subtract(feeAmt));
                        int i = financialDetailService.updateFinancialDetail(fdUpdate);
                        compensate = i > 0;
                    } else {
                        logger.warn("主订单[code={}]的平台抽成金额不足以承担子订单[code={}]的[改价单]的手续费",
                                orderDetail.getOrderMasterCode(), odCode);
                        // 平台抽成不足以承担改价单手续费了 那没办法了只能自己承担
                        // 待提现金额里减去改价单手续费
                        dtx = dtx.subtract(feeAmt);
                    }
                } else { // 分账失败
                    if (AdapayErrorCode.CONFIRM_AMT_OVER_LIMIT.equals(response.getString("error_code"))) {
                        // 当前确认金额 > 支付金额 - 已支付确认金额 - 已支付撤销金额
                        // 这里有两种可能 1.可能是之前算错了手续费的旧订单
                        // 2.可能是之前执行过完单流程 改价单分账成功了 但是子财务单分账失败了
                        // 所以直接跳过
                        logger.info("子订单[code={}] 跳过[改价单]分账", odCode);
                    } else {
                        logger.error("子订单[code={}]的[改价单 paymentId={}]分账失败: {}", odCode, fcRecord.getRemark(), response.toJSONString());
                        // 其它错误抛异常
                        throw new IllegalArgumentException(response.getString("error_msg"));
                    }
                }
            } else {
                addPrice = BigDecimal.ZERO;
            }
        } else {
            addPrice = BigDecimal.ZERO;
        }
        // --------------------- 改价单分账部分 end ---------------------

        // --------------------- 子财务单分账部分 start ---------------------
        // 分账账户信息

        ArrayList<DivMember> divMembers = new ArrayList<>();
        // 子单的实际金额
        BigDecimal fdPayMoney = financialDetail.getPayMoney().subtract(addPrice);
        // 实际要分账的金额(子单的实际金额 + 平台补偿改价单手续费)
        BigDecimal payMoney;
        if (compensate) {
            // 平台补偿改价单手续费
            payMoney = fdPayMoney.add(feeAmt);
        } else {
            // 平台不补偿改价单手续费
            payMoney = fdPayMoney;
        }
        if (BigDecimal.ZERO.compareTo(payMoney) > -1) {
            logger.info("子财务单[code={}] 应支付金额={} 不需要分账", financialDetail.getCode(), payMoney);
        } else {
            // 接单师傅的分账信息
            String payMoneyS = AdapayUtils.bigDecimalToString(payMoney);
            DivMember divMember = new DivMember(memberId, payMoneyS, false);
            divMembers.add(divMember);

            // 计算本次分账的手续费 保留两位小数(向上取整)
            BigDecimal fee = payMoney.multiply(new BigDecimal(feeRate)).setScale(2, RoundingMode.UP);
            // 平台的分账信息 用来承担手续费
            DivMember feeDivMember = new DivMember("0", fee.toString(), true);
            divMembers.add(feeDivMember);

            logger.info("子订单[code={}]发起分账", odCode);
            JSONObject response = adapayService.paymentConfirm(financialDetail.getDeptId(), payment.getId(), payment.getOrderNo() + "_" + System.currentTimeMillis(),
                    fee.add(payMoney).toString(), divMembers, null, null);
            boolean status = AdapayStatusEnum.succeeded.code.equals(response.getString("status"));
            // 如果确认支付失败 这里抛出异常 回滚订单状态
            Assert.isTrue(status, response.toString());
            // 待提现金额里加入子财务单金额
            dtx = dtx.add(fdPayMoney);

            // 修改平台抽成子财务单金额 减去手续费
            fdUpdate.setPayMoney(fdUpdate.getPayMoney().subtract(fee));
            financialDetailService.updateFinancialDetail(fdUpdate);
        }
        // --------------------- 子财务单分账部分 end ---------------------

        // --------------------- 自动提现流程 start ---------------------
        // 走到这里确认分账成功了 进入自动提现流程
        logger.info("子订单[code={}]开始自动提现", odCode);
        if (BigDecimal.ZERO.compareTo(dtx) > -1) {
            logger.info("子订单[code={}] 待提现金额={} 无需提现", odCode, dtx);
        } else {
            // 待提现金额
            String cashAmt = AdapayUtils.bigDecimalToString(dtx);
            executor.execute(() -> drawCash(orderDetailId, financialDetail.getDeptId(), memberId, cashAmt));
        }
        // --------------------- 自动提现流程 end ---------------------
    }

    /**
     * 子订单分账后提现
     *
     * @param orderDetailId 子订单ID
     * @param deptId        企业ID
     * @param memberId      Adapay用户ID
     * @param cashAmt       提现金额
     */
    private void drawCash(Long orderDetailId, Long deptId, String memberId, String cashAmt) {
        String orderNo = AdapayUtils.createOrderNo(AdapayOrderType.DRAW_CASH);
        JSONObject drawCashResponse;
        try {
            drawCashResponse = adapayService.drawCash(deptId, orderNo, "T1",
                    cashAmt, memberId, "订单结算", null);
        } catch (BaseAdaPayException e) {
            logger.error("自动发起提现失败: 子订单id={}, deptId={}", orderDetailId, cashAmt);
            return;
        }
        boolean drawCashStatus = AdapayStatusEnum.pending.code.equals(drawCashResponse.getString("status")) ||
                AdapayStatusEnum.succeeded.code.equals(drawCashResponse.getString("status"));
        if (drawCashStatus) {
            // 提现成功
            logger.info("子订单[id={}]自动提现成功", orderDetailId);
            // 修改订单状态
            OrderDetail odUpdate = new OrderDetail();
            odUpdate.setId(orderDetailId);
            odUpdate.setDrawCashTime(new Date());
            odUpdate.setDrawCashStatus(1);
            // 保存提现ID 用于同步Adapay提现状态
            odUpdate.setDrawCashId(drawCashResponse.getString("id"));
            orderDetailMapper.updateOrderDetail(odUpdate);
        } else {
            // 提现失败 把信息记录到error日志里
            logger.error("自动发起提现失败: 子订单id={}, deptId={} 失败信息: {}", orderDetailId, cashAmt, drawCashResponse.toJSONString());
        }
    }

    @Override
    public Long countOrderDetailList(OrderDetail orderDetail) {
        return orderDetailMapper.countOrderDetailList(orderDetail);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int changePrice(Long orderDetailId, BigDecimal changeMoney, Integer type, String remark) throws
            Exception {
        OrderDetail orderDetail = orderDetailMapper.selectById(orderDetailId);
        if (orderDetail == null) {
            throw new BaseException("子单不存在!");
        }
        FinancialChangeRecord param = new FinancialChangeRecord();
        param.setPayStatus(0);
        param.setOrderDetailId(orderDetailId);
        List<FinancialChangeRecord> list = financialChangeRecordService.selectFinancialChangeRecordList(param);
        FinancialChangeRecord financialChangeRecord;
        int affectedRows = 0;
        if (changeMoney.compareTo(BigDecimal.ZERO) == 0) {
            // 入参中的加价金额为空则直接删除未支付的加价记录
            if (list.size() > 0) {
                financialChangeRecord = list.get(0);
                affectedRows = financialChangeRecordService.deleteFinancialChangeRecordById(financialChangeRecord.getId());
            }
        } else if (list.size() > 0) {
            // 修改现有
            financialChangeRecord = list.get(0);
            financialChangeRecord.setChangeMoney(changeMoney);
            financialChangeRecord.setType(type);
            financialChangeRecord.setRemark(remark);
            affectedRows = financialChangeRecordService.update(financialChangeRecord);
        } else {
            // 创建改单记录
            financialChangeRecord = new FinancialChangeRecord();
            financialChangeRecord.setOrderDetailId(orderDetailId);
            financialChangeRecord.setOrderMasterId(orderDetail.getOrderMasterId());
            financialChangeRecord.setChangeMoney(changeMoney);
            financialChangeRecord.setStatus(0);
            financialChangeRecord.setPayStatus(0);
            financialChangeRecord.setType(type);
            financialChangeRecord.setRemark(remark);
            affectedRows = financialChangeRecordService.insert(financialChangeRecord);
        }
        if (changeMoney.compareTo(BigDecimal.ZERO) != 0 && affectedRows != 1) {
            throw new Exception("加价记录新增或者修改失败");
        }

        return affectedRows;
    }

    @Override
    public int sureChange(Long financialChangeRecordId) {
        return 0;
    }

    @Override
    public FinancialChangeRecord getChangedPriceRecord(Long orderDetailId) {
        FinancialChangeRecord param = new FinancialChangeRecord();
        param.setOrderDetailId(orderDetailId);
        List<FinancialChangeRecord> list = financialChangeRecordService.selectFinancialChangeRecordList(param);
        if (!CollectionUtils.isEmpty(list)) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public List<OrderStatusCount> statusCount() {
        return orderDetailMapper.statusCount();
    }

    @Override
    public int updateDrawCashStatus(String drawCashId, int drawCashStatus, Date arrivalTime) {
        return orderDetailMapper.updateDrawCashStatus(drawCashId, drawCashStatus, arrivalTime);
    }

    @Override
    public void refundSucceeded(String reverseId) {
        financialDetailService.refundSucceeded(reverseId);
    }

    @Override
    public int updateStatus(Long id, int status) {
        for (OrderStatus os : OrderStatus.values()) {
            if (status == os.code()) {
                return orderDetailMapper.updateStatus(id, status);
            }
        }
        throw new IllegalArgumentException("Unknown OrderStatus: " + status);
    }
}
