package com.ghy.order.service.impl;

import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson.JSONObject;
import com.ghy.common.adapay.model.AdapayStatusEnum;
import com.ghy.common.adapay.model.AdpCode;
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.domain.AjaxResult;
import com.ghy.common.core.text.Convert;
import com.ghy.common.enums.AdapayOrderType;
import com.ghy.common.enums.OrderStatus;
import com.ghy.common.enums.PayStatus;
import com.ghy.common.enums.RefundType;
import com.ghy.common.utils.AdapayUtils;
import com.ghy.common.utils.DateUtils;
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.OrderMasterCount;
import com.ghy.order.mapper.OrderMasterMapper;
import com.ghy.order.pojo.dto.OrderMasterStatisticsDTO;
import com.ghy.order.request.AppOrderRequest;
import com.ghy.order.request.OrderChangePriceReq;
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.domain.OrderTimeoutRecord;
import com.ghy.payment.mapper.OrderFineRecordMapper;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

/**
 * 商品模块实现类
 *
 * @author clunt
 */
@Service
public class OrderMasterServiceImpl implements OrderMasterService {

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

    @Resource
    private ThreadPoolTaskExecutor executor;
    @Resource
    private AdapayService adapayService;
    @Resource
    private OrderMasterMapper orderMasterMapper;
    @Resource
    private OrderDetailService orderDetailService;
    @Resource
    private OrderGoodsService orderGoodsService;
    @Resource
    private FinancialMasterService financialMasterService;
    @Resource
    private FinancialDetailService financialDetailService;
    @Resource
    private FinancialChangeRecordService financialChangeRecordService;
    @Resource
    private OrderFineRecordMapper orderFineRecordMapper;

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

    private final static ThreadLocal<SimpleDateFormat> dateFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyyMMddHHmmss"));

    // 这里没有使用redis 暂时将这个查询统计实体放入内存吧。默认调用的时候直接更新他就可以了。
    private final OrderMasterStatisticsDTO statisticsDTO = new OrderMasterStatisticsDTO();
    private final OrderMasterStatisticsDTO statisticsDTOByNow = new OrderMasterStatisticsDTO();

    @Override
    public synchronized String createOrderCode() {
        INDEX.compareAndSet(9999L, 1L);
        // 得到的CODE长度相同
        return "om" + dateFormat.get().format(new Date()) + String.format("%04d", INDEX.getAndIncrement());
    }

    @Override
    public OrderMaster createMasterOrder(AppOrderRequest appOrderRequest) {
        return null;
    }

    @Override
    public int insertOrderMaster(OrderMaster orderMaster) {
        return orderMasterMapper.insertOrderMaster(orderMaster);
    }

    @Override
    public int updateOrderMaster(OrderMaster orderMaster) {
        OrderMaster oldOrder = this.selectById(orderMaster.getId());
        if ((orderMaster.getOrderStatus() != null && !Objects.equals(oldOrder.getOrderStatus(), orderMaster.getOrderStatus()))
            || orderMaster.getExpectTimeStart() != null && orderMaster.getExpectTimeStart().compareTo(new Date()) > 0) {
         
                orderMaster.setTimeout(0);
            
        }
        return orderMasterMapper.updateOrderMaster(orderMaster);
    }

    @Override
    public int saveMasterWorkerRemark(Long orderMasterId, String workerRemark) {
        logger.info("保存主单师傅备注，主单ID：{}，师傅备注：{}", orderMasterId, workerRemark);

        OrderMaster orderMaster = new OrderMaster();
        orderMaster.setId(orderMasterId);
        orderMaster.setWorkerRemark(workerRemark);

        int result = orderMasterMapper.updateOrderMaster(orderMaster);
        logger.info("更新主单师傅备注，主单ID：{}，结果：{}", orderMasterId, result);

        return result;
    }

    @Override
    public List<OrderMaster> selectOrderMasterList(OrderMaster orderMaster) {
        return orderMasterMapper.selectOrderMasterList(orderMaster);
    }

    @Override
    public Long countOrderMasterList(OrderMaster orderMaster) {
        // 如果查询的是服务订单，则设置标识以排除商品主单id有值的数据
        if (orderMaster.getOrderType() != null && orderMaster.getOrderType() == 0 
                && "customer".equals(orderMaster.getFrom())) {
            orderMaster.setExcludeGoodsOrder(true);
        }
        
        return orderMasterMapper.countOrderMasterList(orderMaster);
    }

    @Override
    public Long selectOrderMasterCount(OrderMaster orderMaster) {
        Long count = orderMasterMapper.selectOrderMasterCount(orderMaster);
        return count;
    }

    @Override
    public OrderMaster selectById(Long orderMasterId) {
        return orderMasterMapper.selectById(orderMasterId);
    }

    @Override
    public OrderMaster selectByCode(String orderMasterCode) {
        return orderMasterMapper.selectByCode(orderMasterCode);
    }

    @Override
    public int deleteOrderMasterByIds(String ids) {
        Long[] orderMasterIds = Convert.toLongArray(ids);
        return orderMasterMapper.deleteOrderMasterByIds(orderMasterIds);
    }

    @Override
    public String checkOrderMasterCodeUnique(OrderMaster orderMaster) {
        long orderMasterId = orderMaster.getId() == null ? -1L : orderMaster.getId();
        OrderMaster info = orderMasterMapper.checkOrderMasterCodeUnique(orderMaster.getCode());
        if (info != null && info.getId() != orderMasterId) {
            return UserConstants.ORDER_CODE_NOT_UNIQUE;
        }
        return UserConstants.ORDER_CODE_UNIQUE;
    }

    @Override
    public int updateStatus(Long orderMasterId, int orderStatus) {
        return orderMasterMapper.updateStatus(orderMasterId, orderStatus);
    }

    /**
     * 主订单完成
     * 由定时器触发 而不是由用户触发（用户只能对子订单操作完成）
     * 当所有的子订单完成后 定时器进入此方法
     * 1.修改主订单状态
     * 2.对提成、分销、罚款、手续费等类型的财务单分销和提现
     *
     * @param orderMasterId 主订单ID
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    // 暂时先用 synchronized 来避免重复提交
    public synchronized void finish(Long orderMasterId) throws BaseAdaPayException {
        // 校验订单
        OrderMaster orderMaster = selectById(orderMasterId);
        Assert.notNull(orderMaster, "订单不存在");
        List<OrderDetail> orderDetails = orderDetailService.selectByOrderMasterId(orderMasterId);
        for (OrderDetail orderDetail : orderDetails) {
            if (orderDetail.getOrderStatus() < 5) {
                logger.info("主订单[id={}]存在未完成的子订单", orderMasterId);
                return;
            }
        }
        FinancialMaster financialMaster = financialMasterService.selectByOrderMasterId(orderMasterId);
        Assert.notNull(financialMaster, String.format("主订单[id=%d]找不到对应的主财务单", orderMasterId));
        if (financialMaster.getPayStatus() != 1) {
            logger.info("主订单[id={}]未支付", orderMasterId);
            return;
        }
        PaymentDTO payment = financialMasterService.selectPaymentById(financialMaster.getPaymentId());
        Assert.notNull(payment, String.format("主订单[id=%d]找不到支付记录", orderMasterId));

        // 修改主订单状态
       // updateStatus(orderMasterId, OrderStatus.FINISH_CHECK.code());

        if (BigDecimal.ZERO.compareTo(financialMaster.getPayMoney()) > -1) {
            logger.info("订单[code={}]支付金额<=0，不需要分账", orderMaster.getCode());
            // 支付金额<=0的话 不需要走下面的流程了
            return;
        }

        // 用子财务单组成分账信息
        List<FinancialDetail> financialDetails = financialDetailService.selectByFinancialMasterId(financialMaster.getId());
        // 确认支付总金额
        BigDecimal confirmAmt = BigDecimal.ZERO;

        // 大师傅/店铺提成=订单总金额 - 上门师傅结单金额 - 平台提成 - 订单超时罚金 - 分销金额 - 退款金额 - 订单加价
        BigDecimal bigWorkerAmt = financialMaster.getServerMoney();

        // key:memberId(分账账户ID) value:分账金额
        HashMap<String, BigDecimal> memberMap = new HashMap<>();

        for (FinancialDetail financialDetail : financialDetails) {
            if (BigDecimal.ZERO.compareTo(financialDetail.getPayMoney()) > -1) {
                continue;
            }
            String memberId;
            switch (financialDetail.getFinancialDetailType()) {
                case 0:
                    // 上门师傅的财务单单独确认分账了 不在这里分
                    break;
                case 1:
                    // 大师傅/店铺提成
                    // 没有大师傅/店铺提成了 不再考虑这个case 2023/04/17
                    break;
                case 2:
                    // 平台提成 并且是手续费承担方
                case 5:
                    // 订单超时罚金 归平台所有
                    memberMap.merge("0", financialDetail.getPayMoney(), BigDecimal::add);
                    confirmAmt = confirmAmt.add(financialDetail.getPayMoney());
                    break;
                case 3:
                    // 分销
                    Long payeeId = financialDetail.getPayeeId();
                    if (payeeId != null) {
                        memberId = AdapayUtils.getCustomerMemberId(payeeId, orderMaster.getDeptId());
                        // 如果有分销人 那这笔钱就是分销人的
                        memberMap.merge(memberId, financialDetail.getPayMoney(), BigDecimal::add);
                    } else {
                        // 如果没有分销人 那这笔钱就分到平台账户
                        memberMap.merge("0", financialDetail.getPayMoney(), BigDecimal::add);
                    }
                    confirmAmt = confirmAmt.add(financialDetail.getPayMoney());
                    break;
                case 4:
                    // 退款金额
                    break;
                default:
                    break;
            }
        }

        // 超时罚金
        BigDecimal fineMoney = BigDecimal.ZERO;
        // 查询师傅的超时扣款记录
        List<OrderTimeoutRecord> fineRecords = orderFineRecordMapper.selectUnFine(orderMaster.getWorkerId(), orderMaster.getDeptId());
        ArrayList<Long> fineIds = new ArrayList<>();
        for (OrderTimeoutRecord fineRecord : fineRecords) {
            // 抵扣超时罚金 这里的罚金是按创建时间升序排列的 优先抵扣最早的罚金
            if (fineMoney.add(fineRecord.getPayMoney()).compareTo(bigWorkerAmt) > 0) {
                // 加价单金额不足以抵扣罚金
                logger.info("主订单[{}]的服务金额[{}]不足以抵扣罚金{}元", orderMasterId, bigWorkerAmt, fineRecord.getPayMoney());
                break;
            } else {
                // 抵扣罚金
                logger.info("主订单[{}]的服务金额抵扣罚金{}元", orderMasterId, fineRecord.getPayMoney());
                fineMoney = fineMoney.add(fineRecord.getPayMoney());
                // 被抵扣的罚金记录ID先存下来，分账成功后修改状态
                fineIds.add(fineRecord.getId());
            }
        }

        // 大师傅的MemberId
        String masterWorkerMemberId = AdapayUtils.getWorkerMemberId(orderMaster.getWorkerId(), orderMaster.getDeptId());
        // 罚金分给平台账户
        memberMap.merge("0", fineMoney, BigDecimal::add);
        // 大师傅服务金额减去罚金后剩下的钱 如果小于等于0元 就不用分账给大师傅了
        BigDecimal bigWorkerAmtSubtractFine = bigWorkerAmt.subtract(fineMoney);
        if (BigDecimal.ZERO.compareTo(bigWorkerAmtSubtractFine) < 0) {
            memberMap.put(masterWorkerMemberId, bigWorkerAmtSubtractFine);
        }
        confirmAmt = confirmAmt.add(bigWorkerAmt);

        // 分账账户
        ArrayList<DivMember> divMembers = new ArrayList<>();
        for (Map.Entry<String, BigDecimal> entry : memberMap.entrySet()) {
            String memberId = entry.getKey();
            BigDecimal money = entry.getValue();
            String amount = AdapayUtils.bigDecimalToString(money);
            if ("0".equals(memberId)) {
                // 0是平台账户 承担手续费
                divMembers.add(new DivMember("0", amount, true));
            } else {
                divMembers.add(new DivMember(memberId, amount, false));
            }
        }

        logger.info("订单[code={}]发起分账", orderMaster.getCode());
        JSONObject response = adapayService.paymentConfirm(orderMaster.getDeptId(), payment.getId(), orderMaster.getCode() + System.currentTimeMillis(),
                AdapayUtils.bigDecimalToString(confirmAmt), divMembers, null, null);

        boolean status = AdapayStatusEnum.pending.code.equals(response.getString("status")) ||
                AdapayStatusEnum.succeeded.code.equals(response.getString("status"));

        if (!status) {
            // 如果确认支付失败
            logger.error("主订单[{}]分账失败: {}", orderMaster.getId(), response.toJSONString());
            if (AdpCode.CONFIRM_AMT_OVER_LIMIT.equals(response.getString("error_code"))) {
                // 如果是金额超限的话 可能已经分过帐了 就不回滚了
                return;
            } else {
                throw new BaseAdaPayException(response.getString("code"), response.getString("message"));
            }
        }

        // 分账成功 把罚金状态改为已扣除
        fineIds.forEach(fineRecordId -> orderFineRecordMapper.updateFineStatus(fineRecordId, 1));

        // 走到这里确认支付和分账都成功了 异步进入自动提现流程
        logger.info("订单[code={}]开始自动提现", orderMaster.getCode());
        divMembers.forEach(member -> executor.execute(() -> {
            String memberId = member.getMemberId();
            if ("0".equals(member.getMemberId())) {
                // 平台的钱不用自动提现
                return;
            }
            String amount = member.getAmount();
            try {
                String drawCashId = drawCash(orderMaster.getDeptId(), memberId, amount);

                // 判断是否为大师傅的提现
                if (masterWorkerMemberId.equals(memberId)) {
                    // 给大师傅的子单设置提现状态和提现时间 丢到线程池里执行 避免影响原业务逻辑 2023/5/18
                    executor.execute(() -> {
                        for (OrderDetail orderDetail : orderDetails) {
                            if (orderMaster.getWorkerId().equals(orderDetail.getWorkerId())) {
                                OrderDetail odUpdate = new OrderDetail();
                                odUpdate.setId(orderDetail.getId());
                                odUpdate.setDrawCashTime(new Date());
                                odUpdate.setDrawCashStatus(1);
                                odUpdate.setDrawCashId(drawCashId);
                                orderDetailService.updateOrderDetail(odUpdate);
                            }
                        }
                    });
                }
            } catch (BaseAdaPayException e) {
                logger.error("自动发起提现失败: orderMasterId={}, memberId={}, cashAmt={}", orderMasterId, memberId, amount, e);
            }
        }));
//        //主订单提现成功 修改主订单状态为提现中
        orderMaster.setWithdrawn(1);
        updateOrderMaster(orderMaster);
    }

    /**
     * 发起提现
     *
     * @param deptId   公司ID
     * @param memberId Adapay实名账户ID
     * @param amount   提现金额
     */
    private String drawCash(Long deptId, String memberId, String amount) throws BaseAdaPayException {
        String orderNo = AdapayUtils.createOrderNo(AdapayOrderType.DRAW_CASH);
        JSONObject response = adapayService.drawCash(deptId, orderNo, "T1", amount, memberId, "订单结算", null);

        boolean status = AdapayStatusEnum.pending.code.equals(response.getString("status")) ||
                AdapayStatusEnum.succeeded.code.equals(response.getString("status"));
        if (status) {
            return response.getString("id");
        } else {
            //如果提现失败 把信息记录到error日志里
            logger.error("提现失败: deptId={}, memberId={}, amount={}, 失败原因:{}", deptId, memberId, amount, response.getString("error_msg"));
            return null;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void applyForCancel(Long orderMasterId) throws BaseAdaPayException {
        OrderMaster orderMaster = selectById(orderMasterId);
        Assert.notNull(orderMaster, "找不到对应的订单");
        switch (orderMaster.getOrderStatus()) {
            case 0: // 待接单状态可直接取消
            case 1: // 待排期状态可直接取消
                // 把主订单状态设置为已取消
                updateStatus(orderMasterId, OrderStatus.CANCEL.code());
                // 把所有子订单状态设置为已取消
                OrderDetail update = new OrderDetail();
                update.setOrderMasterId(orderMasterId);
                update.setOrderStatus(OrderStatus.CANCEL.code());
                orderDetailService.updateByOrderMasterId(update);
                // 发起退款
                refund(orderMaster);
                break;
            case 2: // 待上门状态需要师傅同意才能取消
                updateStatus(orderMasterId, OrderStatus.GOING_CANCEL.code());
                break;
            case 3: // 服务中状态需要师傅同意才能取消
                updateStatus(orderMasterId, OrderStatus.SERVER_CANCEL.code());
                break;
            case 4: // 待确认状态需要师傅同意才能取消
                updateStatus(orderMasterId, OrderStatus.FINISH_CHECK_CANCEL.code());
                break;
            default: // 其他状态不可取消
                throw new IllegalArgumentException("这个订单不能取消了");
        }
    }

    @Override
    public void cancelAgree(Long orderMasterId, Integer agree) {
        OrderMaster orderMaster = selectById(orderMasterId);
        Assert.notNull(orderMaster, "找不到对应的订单");
        if (Integer.valueOf(1).equals(agree)) {
            // 师傅同意取消订单
            if (OrderStatus.FINISH.code() == orderMaster.getOrderStatus() || OrderStatus.CANCEL.code() == orderMaster.getOrderStatus()) {
                logger.info("订单[id={}]状态不正确，orderStatus={}", orderMasterId, orderMaster.getOrderStatus());
                return;
            }
            logger.info("主订单取消 orderMasterId = {}", orderMasterId);
            // 把主订单状态设置为已取消
            updateStatus(orderMasterId, OrderStatus.CANCEL.code());
            // 把所有子订单状态设置为已取消
            OrderDetail update = new OrderDetail();
            update.setOrderMasterId(orderMasterId);
            update.setOrderStatus(OrderStatus.CANCEL.code());
            orderDetailService.updateByOrderMasterId(update);
            // 发起退款
            try {
                refund(orderMaster);
            } catch (BaseAdaPayException e) {
                logger.error("订单[code={}]退款失败", orderMaster.getCode(), e);
            }
        } else {
            // 师傅不同意取消订单
            Integer orderStatus = orderMaster.getOrderStatus();
            // 修改主订单状态为原来的状态
            updateStatus(orderMasterId, Math.abs(orderStatus));
        }
    }

    @Override
    public List<OrderMaster> selectByStatus(List<Integer> status) {
        if (CollectionUtils.isEmpty(status)) {
            return Collections.emptyList();
        }
        return orderMasterMapper.selectByStatus(status);
    }

    /**
     * 主订单发起退款
     *
     * @param orderMaster 主订单
     */
    private void refund(OrderMaster orderMaster) throws BaseAdaPayException {
        Assert.notNull(orderMaster, "找不到对应的订单");
        Long orderMasterId = orderMaster.getId();
        FinancialMaster financialMaster = financialMasterService.selectByOrderMasterId(orderMasterId);
        Assert.notNull(financialMaster, "找不到订单");
        boolean paid = PayStatus.PAID.getCode().equals(financialMaster.getPayStatus()) ||
                PayStatus.PAYED_ADD.getCode().equals(financialMaster.getPayStatus());

        // 改支付状态 如果是已支付改退款中 如果是未支付改为取消
        updatePayStatus(orderMasterId, paid ? PayStatus.REVERSING.getCode() : PayStatus.CANCEL.getCode());
        // 改子订单的支付状态
        OrderDetail odUpdate = new OrderDetail();
        odUpdate.setOrderMasterId(orderMasterId);
        odUpdate.setPayStatus(paid ? PayStatus.REVERSING.getCode() : PayStatus.CANCEL.getCode());
        orderDetailService.updateByOrderMasterId(odUpdate);

        // 主订单金额=订单原价+加价
        BigDecimal payMoney = financialMaster.getPayMoney();
        List<FinancialChangeRecord> fcrList = financialChangeRecordService.selectByMasterId(orderMasterId);
        for (FinancialChangeRecord fcr : fcrList) {
            // 把已支付的加价单退了 并从主单金额里减去
            if (financialChangeRecordService.refund(orderMaster.getDeptId(), fcr.getId())) {
                payMoney = payMoney.subtract(fcr.getChangeMoney());
            }
        }

        // 修改主财务单状态
        financialMasterService.updatePayStatus(financialMaster.getId(), paid ? PayStatus.REVERSING.getCode() : PayStatus.CANCEL.getCode());
        // 修改子财务单状态
        List<FinancialDetail> fdList = financialDetailService.selectByFinancialMasterId(financialMaster.getId());
        for (FinancialDetail fd : fdList) {
            if (PayStatus.PAID.getCode().equals(fd.getPayStatus())) {
                financialDetailService.updatePayStatus(fd.getId(), paid ? PayStatus.REVERSING.getCode() : PayStatus.CANCEL.getCode());
            }
        }

        if (payMoney.compareTo(BigDecimal.ZERO) < 1) {
            logger.info("主订单[{}]无需退款 reverseAmt={}", orderMasterId, payMoney);
        }

        if (!paid) {
            logger.info("主订单[{}]未支付，无需退款", orderMasterId);
            return;
        }
        Assert.hasText(financialMaster.getPaymentId(), "找不到订单的支付记录，请联系管理员");
        // 退款
        String reverseAmt = payMoney.setScale(2, RoundingMode.DOWN).toString();
        JSONObject response = adapayService.payReverse(orderMaster.getDeptId(), financialMaster.getPaymentId(), reverseAmt, RefundType.ROM);
        if (AdapayStatusEnum.succeeded.code.equals(response.getString("status")) ||
                AdapayStatusEnum.pending.code.equals(response.getString("status"))) {
            // 保存reverseId
            String reverseId = response.getString("id");
            FinancialMaster fm2up = new FinancialMaster();
            fm2up.setId(financialMaster.getId());
            fm2up.setReverseId(reverseId);
            financialMasterService.updateFinancialMaster(fm2up);
        } else {
            logger.error("主订单[{}]退款失败: {}", orderMasterId, response);
        }
    }

    @Override
    public List<OrderMaster> selectUnfinished() {
        return orderMasterMapper.selectUnfinished();
    }

    @Override
    public List<OrderMaster> selectByIds(Collection<Long> masterIds) {
        if (CollectionUtils.isEmpty(masterIds)) {
            return new ArrayList<>();
        }
        return orderMasterMapper.selectByIds(masterIds);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updatePayStatus(Long orderMasterId, Integer payStatus) {
        OrderDetail orderDetail = new OrderDetail();
        orderDetail.setOrderMasterId(orderMasterId);
        orderDetail.setPayStatus(PayStatus.PAID.getCode());
        orderDetail.setPayTime(new Date());
        orderDetailService.updateByOrderMasterId(orderDetail);
        return orderMasterMapper.updatePayStatus(orderMasterId, payStatus);
    }

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

    @Override
    public boolean isAllAssign(Long orderMasterId) {
        OrderMaster orderMaster = orderMasterMapper.selectById(orderMasterId);
        Assert.notNull(orderMaster, "OrderMaster is null!!!");
        // 先判断主订单是否派完单
        List<OrderGoods> masterGoods = orderGoodsService.selectByOrderMasterId(orderMasterId);
        long masterCount = masterGoods.stream().mapToInt(OrderGoods::getGoodsNum).sum();
        long detailCount = orderDetailService.selectByOrderMasterId(orderMasterId).stream().mapToInt(x -> {
            List<OrderGoods> detailGoods = orderGoodsService.selectByOrderDetailId(x.getId());
            return detailGoods.stream().mapToInt(OrderGoods::getGoodsNum).sum();
        }).sum();
        return masterCount == detailCount;
    }

    @Override
    public int updateTimeout(Long id, int timeout) {
        return orderMasterMapper.updateTimeout(id, timeout, null);
    }

    @Override
    public int updateCreateTime(Long id) {
        return orderMasterMapper.updateCreateTime(id);
    }

    @Override
    public int updateTimeout(Long id, int timeout, int timeoutFineTimes) {
        return orderMasterMapper.updateTimeout(id, timeout, timeoutFineTimes);
    }

    @Override
    public int removeWorker(Long id) {
        return orderMasterMapper.removeWorker(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int reject(OrderMaster orderMaster) {
        // 删主单的 workerId
        int i1 = orderMasterMapper.removeWorker(orderMaster.getId());
        // 删子单对应的 OrderGoods
        List<OrderDetail> orderDetails = orderDetailService.selectByOrderMasterId(orderMaster.getId());
        orderDetails.forEach(x -> orderGoodsService.deleteByOrderDetailId(x.getId()));
        // 删子单
        orderDetailService.deleteByMaster(orderMaster.getId());
        return 1;
    }

    @Override
    public OrderMasterCount differentStatusOrderCount(OrderMaster orderMaster) {
        return orderMasterMapper.differentStatusOrderCount(orderMaster);
    }

    @Override
    public AjaxResult batchChangePrice(OrderChangePriceReq changePriceReq) {
        BigDecimal changePrice = new BigDecimal(changePriceReq.getChangePrice());
        String [] idStr = changePriceReq.getOrderIds().split(",");
        List<Long> idsList = new ArrayList<>();
        for (String id : idStr){
            idsList.add(Long.parseLong(id));
        }
        List<OrderMaster> orderMasters = orderMasterMapper.selectByIds(idsList);
        long statusCount = orderMasters.stream().filter(x->x.getOrderStatus() != 1 && x.getOrderStatus() != 2).count();
        if(statusCount > 0){
            return AjaxResult.error("请不要选择不符合状态的订单!");
        }
        for (OrderMaster model : orderMasters) {
            FinancialMaster financialMaster = financialMasterService.selectByOrderMasterId(model.getId());
            if (NumberUtil.isGreater(changePrice, financialMaster.getServerMoney())) {
                // 补充付款 todo 插入改价表数据
            }else {
                // 减少大师傅所得 todo 插入改价表数据
            }
            financialMaster.setServerMoney(changePrice);
            financialMasterService.updateFinancialMaster(financialMaster);
        }
        return AjaxResult.success();
    }

    @Override
    public OrderMasterStatisticsDTO orderStatisticsReturn() {
        return statisticsDTO;
    }

    @Override
    public OrderMasterStatisticsDTO orderStatisticsDispose() {
        // 根据时间返回查询
        List<OrderMaster> orderMasters = orderMasterMapper.searchByOrderStartTime(null, null);
        // 订单数据统计
        if (orderMasters != null && !orderMasters.isEmpty()) {
            // 根据map数据进行数据分类处理 根据订单状态类型进行数据分类处理。
            Map<Integer, List<OrderMaster>> masterOrderMap = orderMasters.stream().collect(Collectors.groupingBy(OrderMaster::getOrderStatus));
            // 循环订单状态类型进行状态类型   switch进行归类处理。
            for (Integer orderStateKey : masterOrderMap.keySet()) {
                /**
                 *     GOING_CANCEL(-2, "待上门时申请取消"),
                 *     SERVER_CANCEL(-3, "服务中申请取消"),
                 *     FINISH_CHECK_CANCEL(-4, "待确认时申请取消"),
                 *
                 *     RECEIVE(0, "待接单"),
                 *     PLAIN(1, "待排期"),
                 *     GOING(2, "待上门"),
                 *     SERVER(3, "服务中"),
                 *     FINISH_CHECK(4, "待确认"),
                 *     FINISH(5, "已完成"),
                 *     CANCEL(6, "已取消");
                 */
                OrderStatus orderStatus = OrderStatus.parse(orderStateKey);
                if (ObjectUtils.isNotNull(orderStatus)) {
                    switch (orderStatus) {
                        case CANCEL:
                            statisticsDTO.setCancelNumber(masterOrderMap.get(orderStateKey).size());
                            break;
                        case FINISH:
                            statisticsDTO.setFinishNumber(masterOrderMap.get(orderStateKey).size());
                            break;
                        case FINISH_CHECK:
                            statisticsDTO.setFinishCheckNumber(masterOrderMap.get(orderStateKey).size());
                            break;
                        case SERVER:
                            statisticsDTO.setServerNumber(masterOrderMap.get(orderStateKey).size());
                            break;
                        case GOING:
                            statisticsDTO.setGoingNumber(masterOrderMap.get(orderStateKey).size());
                            break;
                        case PLAIN:
                            statisticsDTO.setPlainNumber(masterOrderMap.get(orderStateKey).size());
                            break;
                        case RECEIVE:
                            statisticsDTO.setReceiveNumber(masterOrderMap.get(orderStateKey).size());
                            break;
                        case GOING_CANCEL:
                            statisticsDTO.setGoingCancelNumber(masterOrderMap.get(orderStateKey).size());
                            break;
                        case SERVER_CANCEL:
                            statisticsDTO.setServerCancelNumber(masterOrderMap.get(orderStateKey).size());
                            break;
                        case FINISH_CHECK_CANCEL:
                            statisticsDTO.setFinishCheckCancelNumber(masterOrderMap.get(orderStateKey).size());
                            break;
                        default:
                            break;
                    }
                }
            }
            // 总数
            statisticsDTO.setTotalOrderNumber(orderMasters.size());
        }
        return statisticsDTO;
    }

    @Override
    public OrderMasterStatisticsDTO orderStatisticsReturnByNow() {
        return statisticsDTOByNow;
    }

    @Override
    public OrderMasterStatisticsDTO orderStatisticsDisposeByNow() {
        // 拿到当前时间
        Long time = System.currentTimeMillis();
        // 根据时间返回查询
        List<OrderMaster> orderMasters = orderMasterMapper.searchByOrderStartTime(DateUtils.getDayStartTime(time), DateUtils.getDayEndTime(time));
        // 订单数据统计
        if (orderMasters != null && !orderMasters.isEmpty()) {
            // 根据map数据进行数据分类处理 根据订单状态类型进行数据分类处理。
            Map<Integer, List<OrderMaster>> masterOrderMap = orderMasters.stream().collect(Collectors.groupingBy(OrderMaster::getOrderStatus));
            // 循环订单状态类型进行状态类型   switch进行归类处理。
            for (Integer orderStateKey : masterOrderMap.keySet()) {
                /**
                 *     GOING_CANCEL(-2, "待上门时申请取消"),
                 *     SERVER_CANCEL(-3, "服务中申请取消"),
                 *     FINISH_CHECK_CANCEL(-4, "待确认时申请取消"),
                 *
                 *     RECEIVE(0, "待接单"),
                 *     PLAIN(1, "待排期"),
                 *     GOING(2, "待上门"),
                 *     SERVER(3, "服务中"),
                 *     FINISH_CHECK(4, "待确认"),
                 *     FINISH(5, "已完成"),
                 *     CANCEL(6, "已取消");
                 */
                OrderStatus orderStatus = OrderStatus.parse(orderStateKey);
                if (ObjectUtils.isNotNull(orderStatus)) {
                    switch (orderStatus) {
                        case CANCEL:
                            statisticsDTOByNow.setCancelNumber(masterOrderMap.get(orderStateKey).size());
                            break;
                        case FINISH:
                            statisticsDTOByNow.setFinishNumber(masterOrderMap.get(orderStateKey).size());
                            break;
                        case FINISH_CHECK:
                            statisticsDTOByNow.setFinishCheckNumber(masterOrderMap.get(orderStateKey).size());
                            break;
                        case SERVER:
                            statisticsDTOByNow.setServerNumber(masterOrderMap.get(orderStateKey).size());
                            break;
                        case GOING:
                            statisticsDTOByNow.setGoingNumber(masterOrderMap.get(orderStateKey).size());
                            break;
                        case PLAIN:
                            statisticsDTOByNow.setPlainNumber(masterOrderMap.get(orderStateKey).size());
                            break;
                        case RECEIVE:
                            statisticsDTOByNow.setReceiveNumber(masterOrderMap.get(orderStateKey).size());
                            break;
                        case GOING_CANCEL:
                            statisticsDTOByNow.setGoingCancelNumber(masterOrderMap.get(orderStateKey).size());
                            break;
                        case SERVER_CANCEL:
                            statisticsDTOByNow.setServerCancelNumber(masterOrderMap.get(orderStateKey).size());
                            break;
                        case FINISH_CHECK_CANCEL:
                            statisticsDTOByNow.setFinishCheckCancelNumber(masterOrderMap.get(orderStateKey).size());
                            break;
                        default:
                            break;
                    }
                }
            }
            // 总数
            statisticsDTOByNow.setTotalOrderNumber(orderMasters.size());
        }
        return statisticsDTO;
    }

    @Override
    public int updateOrderMasterAddressById(OrderMaster orderMaster) {
        logger.info("传入的更新订单地址对应的数据{}",orderMaster);
        return orderMasterMapper.updateOrderMasterAddressById(orderMaster);
    }

    @Override
    public int returnOrder(Long orderMasterId, String returnReason, String returnReasonDetail, String returnImages) {
        logger.info("主单退单，订单ID：{}，退单原因：{}，退单原因详情：{}，退单图片：{}",
                   orderMasterId, returnReason, returnReasonDetail, returnImages);

        OrderMaster orderMaster = new OrderMaster();
        orderMaster.setId(orderMasterId);
        orderMaster.setReturnReason(returnReason);
        orderMaster.setReturnReasonDetail(returnReasonDetail);
        orderMaster.setReturnImages(returnImages);

        return orderMasterMapper.updateOrderMaster(orderMaster);
    }

    @Override
    public OrderMaster selectByGoodsOrderMasterId(Long goodsOrderMasterId) {
        return orderMasterMapper.selectByGoodsOrderMasterId(goodsOrderMasterId);
    }

}
