package com.zm.order.tool.server.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.openservices.shade.org.apache.commons.lang3.builder.Diff;
import com.aliyun.openservices.shade.org.apache.commons.lang3.builder.DiffResult;
import com.github.dozermapper.core.Mapper;
import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import com.zm.order.tool.server.component.ShardingKeyGenerator;
import com.zm.order.tool.server.component.ThreadContext;
import com.zm.order.tool.server.constants.CommonConstants;
import com.zm.order.tool.server.dao.*;
import com.zm.order.tool.server.dto.*;
import com.zm.order.tool.server.dto.InnerOrderDiscount;
import com.zm.order.tool.server.enums.BizTypeEnum;
import com.zm.order.tool.server.enums.DeleteTypeEnum;
import com.zm.order.tool.server.enums.OrderItemTypeEnum;
import com.zm.order.tool.server.manager.OrderManager;
import com.zm.order.tool.server.manager.SearchManager;
import com.zm.order.tool.server.model.*;
import com.zm.order.tool.server.query.ItemBatchingQuery;
import com.zm.order.tool.server.request.OrderDetailRequest;
import com.zm.order.tool.server.request.OrderRepairRequest;
import com.zm.order.tool.server.response.OrderNewVO;
import com.zm.order.tool.server.service.ExceptionConstants;
import com.zm.order.tool.server.service.OrderRepairService;
import com.zm.order.tool.server.tempdb.RepairOrderLogDao;
import com.zm.order.tool.server.utils.ConvertUtils;
import com.zm.util.dto.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author zhuxiaofeng
 * @packageName: com.zm.order.tool.server.service.impl
 * @className: OrderReporServiceImpl
 * @date 2022/9/20 14:04
 */
@Service
public class OrderRepairServiceImpl implements OrderRepairService {

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

    @Autowired
    private OrderIndexDao indexDao;
    @Autowired
    private OrderDao orderDao;
    @Autowired
    private OrderDiscountDao discountDao;
    @Autowired
    private OrderItemDao itemDao;
    @Autowired
    private OrderPayDetailsDao payDao;
    @Autowired
    private OrderAddrDao addrDao;
    @Autowired
    private Mapper mapper;
    @Autowired
    private OrderManager manager;
    @Autowired
    private ShardingKeyGenerator keyGenerator;
    @Autowired
    private SearchManager searchManager;
    @Autowired
    private RepairOrderLogDao logDao;

    @Autowired
    private OrderUserRelationDao relationDao;

    @Autowired
    private OrderExtendsDao orderExtendsDao;
    @Autowired
    private OrderItemBatchingDao itemBatchingDao;
    @Override
    public Result<OrderNewVO> orderDetail(OrderDetailRequest request) {
        Result result = new Result();
        try {
            Assert.notNull(request.getOrderNo(), "订单号为空");
            OrderIndex orderIndex = indexDao.selectOne(request.getOrderNo());
            if (Objects.isNull(orderIndex)) {
                return Result.failureData("订单索引不存在");
            }
            String orderNo = request.getOrderNo();
            Long userId = orderIndex.getUserId();
            Order order = orderDao.selectByOrderNo(orderNo, userId);
            if (Objects.isNull(order)) {
                return Result.failureData("订单不存在");
            }
            OrderNewVO orderVO = getOrderVO(orderNo, userId);
            result.setStatus(true);
            result.setData(orderVO);
        } catch (Throwable e) {
            logger.error("OrderRepairServiceImpl[orderDetail] failed!, cause by:{}", e);
            result.setException(ExceptionConstants.SYSTEM_ERROR);
        }
        return result;
    }

    private OrderNewVO getOrderVO (String orderNo, Long userId) {
        Order order = orderDao.selectByOrderNoAll(orderNo, userId);
        OrderNewVO orderVO = mapper.map(order, OrderNewVO.class);
        List<OrderItem> itemList = itemDao.selectByOrderNo(orderNo, userId);
        orderVO.setItemList(itemList);
        List<OrderDiscount> discountList = discountDao.selectByOrderNo(orderNo, userId);
        orderVO.setDiscountList(discountList);
        List<OrderPayDetails> payList = payDao.selectByOrderNo(orderNo, userId);
        orderVO.setPayDetailsList(payList);
        OrderAddr orderAddr = addrDao.selectByOrderNo(orderNo, userId);
        orderVO.setOrderAddr(orderAddr);
        return orderVO;
    }

    @Override
    public Result updateByDiff(OrderRepairRequest request) {
        Result result = new Result();
        OrderNewVO after = request.getOrderData();
        String orderNo = after.getOrderNo();
        Long userId = after.getUserId();
        try {
            StringBuilder diffStr = new StringBuilder();
            OrderNewVO beforeOrder = getOrderVO(orderNo, userId);
            DiffResult diff = after.diff(beforeOrder);
            List<Diff<?>> diffs = diff.getDiffs();
            Map<String, Object> map = new HashMap<>();
            for (Diff<?> di : diffs ) {
                map.put(di.getFieldName(), di.getLeft());
                //活动有变动的key 和 前后值
                logText(diffStr, di.getFieldName(), di.getLeft(), di.getRight(), "order", beforeOrder.getId());
            }

            Order order = JSONObject.parseObject(JSONObject.toJSONString(map), Order.class);
            order.setId(beforeOrder.getId());
            order.setOrderNo(orderNo);
            order.setUserId(userId);
            logger.info("updateByDiff[order],order:{}", order);

            //对比商品
            List<OrderItem> insertItemList = new ArrayList<>();
            List<OrderItem> updateItemList = new ArrayList<>();
            List<OrderItem> delItemList = new ArrayList<>();
            diffItem(beforeOrder, after, insertItemList, updateItemList, delItemList, diffStr);
            logger.info("updateByDiff[itemDiff],insertItemList:{}", insertItemList);
            logger.info("updateByDiff[itemDiff],updateItemList:{}", updateItemList);
            logger.info("updateByDiff[itemDiff],delItemList:{}", delItemList);
            logger.info("updateByDiff[itemDiff],diffStr:{}", diffStr);
            System.out.println(diffStr);

            //对比优惠
            List<OrderDiscount> insertDiscountList = new ArrayList<>();
            List<OrderDiscount> updateDiscountList = new ArrayList<>();
            List<OrderDiscount> delDiscountList = new ArrayList<>();
            diffDiscount(beforeOrder, after, insertDiscountList, updateDiscountList, delDiscountList, diffStr);
            logger.info("updateByDiff[discountDiff],insertDiscountList:{}", insertDiscountList);
            logger.info("updateByDiff[discountDiff],updateDiscountList:{}", updateDiscountList);
            logger.info("updateByDiff[discountDiff],delDiscountList:{}", delDiscountList);
            logger.info("updateByDiff[discountDiff],diffStr:{}", diffStr);

            //对比支付
            List<OrderPayDetails> insertPayList = new ArrayList<>();
            List<OrderPayDetails> updatePayList = new ArrayList<>();
            List<OrderPayDetails> delPayList = new ArrayList<>();
            diffPay(beforeOrder, after, insertPayList, updatePayList, delPayList, diffStr);
            logger.info("updateByDiff[payDiff],insertPayList:{}", insertPayList);
            logger.info("updateByDiff[payDiff],updatePayList:{}", updatePayList);
            logger.info("updateByDiff[payDiff],delPayList:{}", delPayList);
            logger.info("updateByDiff[payDiff],diffStr:{}", diffStr);

            manager.updateOrderByDiff(order,
                    insertItemList, updateItemList, delItemList,
                    insertDiscountList, updateDiscountList, delDiscountList,
                    insertPayList, updatePayList, delPayList);
            
            // 更新订单快照
            Order newOrder = orderDao.selectByOrderNo(orderNo, userId);
            // 商品快照
            List<OrderItem> orderItemList = itemDao.selectByOrderNo(orderNo, userId);
            String itemInfo = newOrder.getItemInfo();
            if (!Objects.equals(CommonConstants.ITEM_FLAG, itemInfo)) {
                List<InnerOrderItem> innerOrderItemList = ConvertUtils.convertList(orderItemList, InnerOrderItem.class);
                if (!CollectionUtils.isEmpty(innerOrderItemList)) {
                    if (innerOrderItemList.size() > 10) {
                        newOrder.setItemInfo(CommonConstants.ITEM_FLAG);
                    } else {
                        newOrder.setItemInfo(JSON.toJSONString(innerOrderItemList));
                    }
                }
            }
            // 优惠快照
            List<OrderDiscount> discountList = discountDao.selectByOrderNo(orderNo, userId);
            String discountInfo = newOrder.getDiscountInfo();
            if (!Objects.equals(CommonConstants.DISCOUNT_FLAG, discountInfo)) {
                List<InnerOrderDiscount> innerDiscountList = ConvertUtils.convertList(discountList, InnerOrderDiscount.class);
                if (!CollectionUtils.isEmpty(innerDiscountList)) {
                    if (innerDiscountList.size() > 10) {
                        newOrder.setDiscountInfo(CommonConstants.DISCOUNT_FLAG);
                    } else {
                        newOrder.setDiscountInfo(JSON.toJSONString(innerDiscountList));
                    }
                }
            }
            // 支付快照
            List<OrderPayDetails> orderPayDetailsList = payDao.selectByOrderNo(orderNo, userId);
            String payInfo = newOrder.getPayDetailInfo();
            if (!Objects.equals(CommonConstants.PAY_FLAG, payInfo)) {
                List<InnerOrderPayDetails> innerPayList = ConvertUtils.convertList(orderPayDetailsList, InnerOrderPayDetails.class);
                if (!CollectionUtils.isEmpty(innerPayList)) {
                    if (innerPayList.size() > 10) {
                        newOrder.setPayDetailInfo(CommonConstants.PAY_FLAG);
                    } else {
                        newOrder.setPayDetailInfo(JSON.toJSONString(innerPayList));
                    }
                }
            }
            orderDao.updateItemInfo(newOrder);

            // 同步Es
            searchManager.indexOrder(newOrder, null);

            //保存操作记录
            saveLog(request, order, diffStr,
                    insertItemList, updateItemList, delItemList,
                    insertDiscountList, updateDiscountList, delDiscountList,
                    insertPayList, updatePayList, delPayList);
            result.setStatus(true);
        } catch (Throwable e) {
            logger.error("OrderRepairServiceImpl[updateByDiff] failed!, cause by:{}", e);
            result.setException(ExceptionConstants.SYSTEM_ERROR);
        }
        return result;
    }

    private void saveLog(OrderRepairRequest request, Order order, StringBuilder diffStr,
                         List<OrderItem> addItemList, List<OrderItem> updateItemList, List<OrderItem> delItemList,
                         List<OrderDiscount> insertDiscountList, List<OrderDiscount> updateDiscountList, List<OrderDiscount> delDiscountList,
                         List<OrderPayDetails> insertPayList, List<OrderPayDetails> updatePayList, List<OrderPayDetails> delPayList){

        RepairOrderLog log = new RepairOrderLog();
        log.setOrderNo(order.getOrderNo());
        log.setUserId(order.getUserId());
        log.setAuthor(request.getAuthor());
        log.setContent(diffStr.toString());
        log.setRemarks(request.getRemarks());
        Map<String, Object> map = new HashMap();
        map.put("order", order);
        map.put("addItemList", addItemList);
        map.put("updateItemList", updateItemList);
        map.put("addDiscountList", insertDiscountList);
        map.put("updateDiscountList", updateDiscountList);
        map.put("addPayList", insertPayList);
        map.put("updatePayList", updatePayList);
        log.setDiff(JSON.toJSONString(map));
        logDao.insert(log);
    }

    //对比商品
    private void diffItem(OrderNewVO beforeOrder, OrderNewVO after, List<OrderItem> insertItemList, List<OrderItem> updateItemList, List<OrderItem> delItemList, StringBuilder diffStr){
        Map<Long, OrderItem> afterItemMap = after.getItemList().stream().collect(Collectors.toMap(OrderItem::getId, Function.identity()));
        Map<Long, OrderItem> beforeItemMap = beforeOrder.getItemList().stream().collect(Collectors.toMap(OrderItem::getId, Function.identity()));

        for (OrderItem item : after.getItemList()) {
            // 新增的商品记录
            if (Objects.isNull(item.getId())) {
                item.setId(keyGenerator.generateSnowflakeNumKey());
                insertItemList.add(item);
                continue;
            }
            //修改的商品记录
            if (Objects.nonNull(item.getId())) {
                if (Objects.isNull(beforeItemMap.get(item.getId()))) {
                    logger.info("updateByDiff[diffItem][itemDataError], orderNo:{}, 原数据没有此order_items主键:{}",
                            beforeOrder.getOrderNo(), item.getId());
                    continue;
                }
                //获取对比后的结果
                DiffResult itemDiff = item.diff(beforeItemMap.get(item.getId()));
                List<Diff<?>> itemDiffs = itemDiff.getDiffs();
                Map<String, Object> itemDiffMap = new HashMap<>();
                for (Diff<?> di : itemDiffs ) {
                    itemDiffMap.put(di.getFieldName(), di.getLeft());
                    //活动有变动的key 和 前后值
                    logText(diffStr, di.getFieldName(), di.getLeft(), di.getRight(), "item", item.getId());
                }
                OrderItem orderItem = JSONObject.parseObject(JSONObject.toJSONString(itemDiffMap), OrderItem.class);
                orderItem.setId(item.getId());
                orderItem.setUserId(item.getUserId());
                orderItem.setOrderNo(item.getOrderNo());
                updateItemList.add(orderItem);
            }
        }
        for (OrderItem item : beforeOrder.getItemList()) {
            // 删除的商品记录
            if (Objects.isNull( afterItemMap.get(item.getId()) )) {
                delItemList.add(item);
            }
        }
    }


    //对比discount
    private void diffDiscount(OrderNewVO beforeOrder, OrderNewVO after,
                              List<OrderDiscount> addDiscountList, List<OrderDiscount> updateDiscountList, List<OrderDiscount> delDiscountList,
                              StringBuilder diffStr){
        Map<Long, OrderDiscount> afterItemMap = after.getDiscountList().stream().collect(Collectors.toMap(OrderDiscount::getId, Function.identity()));
        Map<Long, OrderDiscount> beforeItemMap = beforeOrder.getDiscountList().stream().collect(Collectors.toMap(OrderDiscount::getId, Function.identity()));

        for (OrderDiscount item : after.getDiscountList()) {
            // 新增的优惠记录
            if (Objects.isNull(item.getId())) {
                item.setId(keyGenerator.generateSnowflakeNumKey());
                addDiscountList.add(item);
                continue;
            }
            //修改的优惠记录
            if (Objects.nonNull(item.getId())) {
                if (Objects.isNull(beforeItemMap.get(item.getId()))) {
                    logger.info("updateByDiff[diffDiscount][discountDataError], orderNo:{}, 原数据没有此order_discounts主键:{}",
                            beforeOrder.getOrderNo(), item.getId());
                    continue;
                }
                //获取对比后的结果
                DiffResult itemDiff = item.diff(beforeItemMap.get(item.getId()));
                List<Diff<?>> itemDiffs = itemDiff.getDiffs();
                Map<String, Object> itemDiffMap = new HashMap<>();
                for (Diff<?> di : itemDiffs ) {
                    itemDiffMap.put(di.getFieldName(), di.getLeft());
                    //活动有变动的key 和 前后值
                    logText(diffStr, di.getFieldName(), di.getLeft(), di.getRight(), "discount", item.getId());
                }
                OrderDiscount disocunt = JSONObject.parseObject(JSONObject.toJSONString(itemDiffMap), OrderDiscount.class);
                disocunt.setId(item.getId());
                disocunt.setUserId(item.getUserId());
                disocunt.setOrderNo(item.getOrderNo());
                updateDiscountList.add(disocunt);
            }
        }
        for (OrderDiscount item : beforeOrder.getDiscountList()) {
            // 删除的优惠
            if (Objects.isNull( afterItemMap.get(item.getId()) )) {
                delDiscountList.add(item);
            }
        }
    }


    //对比payDetails
    private void diffPay(OrderNewVO beforeOrder, OrderNewVO after,
                              List<OrderPayDetails> addPayList, List<OrderPayDetails> updatePayList, List<OrderPayDetails> delPayList,
                         StringBuilder diffStr){
        Map<Long, OrderPayDetails> afterItemMap = after.getPayDetailsList().stream().collect(Collectors.toMap(OrderPayDetails::getId, Function.identity()));
        Map<Long, OrderPayDetails> beforeItemMap = beforeOrder.getPayDetailsList().stream().collect(Collectors.toMap(OrderPayDetails::getId, Function.identity()));

        for (OrderPayDetails item : after.getPayDetailsList()) {
            // 新增的支付
            if (Objects.isNull(item.getId())) {
                item.setId(keyGenerator.generateSnowflakeNumKey());
                addPayList.add(item);
                continue;
            }
            //修改的支付
            if (Objects.nonNull(item.getId())) {
                if (Objects.isNull(beforeItemMap.get(item.getId()))) {
                    logger.info("updateByDiff[diffPay][payDataError], orderNo:{}, 原数据没有此order_pay_details主键:{}",
                            beforeOrder.getOrderNo(), item.getId());
                    continue;
                }
                //获取对比后的结果
                DiffResult itemDiff = item.diff(beforeItemMap.get(item.getId()));
                List<Diff<?>> itemDiffs = itemDiff.getDiffs();
                Map<String, Object> itemDiffMap = new HashMap<>();
                for (Diff<?> di : itemDiffs ) {
                    itemDiffMap.put(di.getFieldName(), di.getLeft());
                    //活动有变动的key 和 前后值
                    logText(diffStr, di.getFieldName(), di.getLeft(), di.getRight(), "pay", item.getId());
                }
                OrderPayDetails pay = JSONObject.parseObject(JSONObject.toJSONString(itemDiffMap), OrderPayDetails.class);
                pay.setId(item.getId());
                pay.setUserId(item.getUserId());
                pay.setOrderNo(item.getOrderNo());
                updatePayList.add(pay);
            }
        }
        for (OrderPayDetails item : beforeOrder.getPayDetailsList()) {
            // 删除的支付
            if (Objects.isNull( afterItemMap.get(item.getId()) )) {
                delPayList.add(item);
            }
        }
    }


    public void logText(StringBuilder str, String fieldName, Object left, Object right, String type, Long id) {
        String typeText = "";
        String idText = "";
        switch (type) {
            case "order":
                typeText = "订单表";
                break;
            case "item":
                typeText = "商品表";
                idText = "(主键：" + id + ")";
                break;
            case "discount":
                typeText = "优惠表";
                idText = "(主键：" + id + ")";
                break;
            case "pay":
                typeText = "支付表";
                idText = "(主键：" + id + ")";
                break;
            default:
                break;
        }
        String rightText = "";
        if (Objects.isNull(right)) {
            rightText = "null";
        } else {
            rightText = right.toString();
        }

        str.append("【"+ typeText + "】" + idText + " [" + fieldName + "] 从【" + rightText + "】改成【" + left.toString() + "】;\n");
        System.out.println(str);
    }


    @Override
    public Result<OrderDetailDTO> getOrderDetail(String orderNo, Long userId) {
        Result<OrderDetailDTO> result = new Result<>();
        try {
            // 1.参数校验
//            ExceptionInfo exceptionInfo = helper.checkGetOrderParam(orderNo);
//            if (ExceptionConstants.OK != exceptionInfo) {
//                result.setException(exceptionInfo);
//                return result;
//            }

            OrderIndex index = indexDao.selectOne(orderNo);
            Order order = orderDao.selectByOrderNo(orderNo, index.getUserId());
            ThreadContext.setBizType(order.getBizType());
            if (Objects.isNull(order)) {
                final Integer bizType = ThreadContext.getBizType();
                if (order == null) {
                    result.setException(ExceptionConstants.ORDER_NOT_EXISTS);
                    return result;
                }
            }
            if (Objects.equals(DeleteTypeEnum.ALL_DELETED.getValue(), order.getIsDeleted()) ||
                    Objects.equals(DeleteTypeEnum.SYSTEM_DELETED.getValue(), order.getIsDeleted())) {
                logger.error("[ORDER_BE_DELETED]orderNo:{}, userId:{}", order.getOrderNo(), order.getUserId());
                result.setException(ExceptionConstants.ORDER_NOT_EXISTS);
                return result;
            }
            List<OrderItem> orderItemList = itemDao.selectByOrderNo(order.getOrderNo(), order.getUserId());
            List<OrderDiscount> orderDiscountList = discountDao.selectByOrderNo(order.getOrderNo(), order.getUserId());
            OrderAddr orderAddr = addrDao.selectByOrderNo(order.getOrderNo(), order.getUserId());
            // 2.1 兼容餐饮多人点餐 userId参数为子订单信息
            this.buildSubOrderInfo(order, orderItemList, orderDiscountList, true);
            // 3.组装返回
            OrderDetailDTO orderDetailDTO = this.buildOrderDetail(order, orderItemList, orderDiscountList, orderAddr);
            result.setData(orderDetailDTO);
            result.setStatus(true);
        } catch (Throwable throwable) {
            logger.error("OrderReadServiceImpl[getOrderDetail] failed, request:[orderNo:{}, userId:{}], cause by:{}",
                    orderNo, userId, Throwables.getStackTraceAsString(throwable));
            result.setException(ExceptionConstants.SYSTEM_ERROR);
        }
        return result;
    }

    public OrderDetailDTO buildOrderDetail(Order order, List<OrderItem> orderItemList,
                                           List<OrderDiscount> orderDiscountList, OrderAddr orderAddr) {
        OrderDetailDTO orderDetailDTO = mapper.map(order, OrderDetailDTO.class);
        Long orderId = order.getId();
        Long masterId = checkAndGetOrderId(order);
        if (Objects.nonNull(masterId)) {
            orderId = masterId;
        }
        orderDetailDTO.setOrderId(orderId);
        orderDetailDTO.setPayInfoMap(convert(order.getPayInfo()));
        orderDetailDTO.setPerformanceInfoMap(convert(order.getPerformanceInfo()));
        buildBaseInfo(orderItemList, orderDiscountList, orderAddr, orderDetailDTO, order);
        //订单包含三方扩展字段
        if (order.getExtraMap().containsKey(CommonConstants.IS_THIRD_EXTRA) &&
                Objects.equals(1, order.getExtraMap().get(CommonConstants.IS_THIRD_EXTRA))) {
            OrderExtends orderExtends = orderExtendsDao.selectByOrderNo(order.getOrderNo(), order.getUserId());
            if (Objects.nonNull(orderExtends)) {
                orderDetailDTO.setThirdExtraMap(orderExtends.getThirdExtraMap());
            }
        }
        return orderDetailDTO;
    }

    private void buildBaseInfo(List<OrderItem> orderItemList, List<OrderDiscount> orderDiscountList,
                               OrderAddr orderAddr, OrderDetailDTO orderDetailDTO, Order order) {
        // 构建商品信息
        if (!CollectionUtils.isEmpty(orderItemList)) {
            List<OrderItemDTO> orderItemDtoList = Lists.newArrayListWithCapacity(orderItemList.size());
            orderItemList.forEach(orderItem -> {
                OrderItemDTO orderItemDTO = mapper.map(orderItem, OrderItemDTO.class);
                orderItemDtoList.add(orderItemDTO);
            });
            List<OrderItemDTO> orderItemDTOList = reBuildItemList(orderItemDtoList);
            setItemBatchingInfo(orderItemDTOList);
            orderDetailDTO.setItemList(orderItemDTOList);
        }
        // 构建优惠信息
        if (!CollectionUtils.isEmpty(orderDiscountList)) {
            List<OrderDiscountDTO> orderDiscountDtoList = Lists.newArrayListWithCapacity(orderDiscountList.size());
            orderDiscountList.forEach(orderDiscount -> {
                OrderDiscountDTO orderDiscountDTO = mapper.map(orderDiscount, OrderDiscountDTO.class);
                orderDiscountDtoList.add(orderDiscountDTO);
            });
            orderDetailDTO.setDiscountList(orderDiscountDtoList);
        }
        // 构建地址信息
        OrderAddrDTO orderAddrDto = ConvertUtils.convert(orderAddr, OrderAddrDTO.class);
        orderDetailDTO.setAddr(orderAddrDto);
        // 构建支付信息
        List<OrderPayDetailsDTO> payDetailsList = this.parsePayDetails(order);
        orderDetailDTO.setPayDetailsList(payDetailsList);

    }

    public List<OrderPayDetailsDTO> parsePayDetails(Order order) {
        return ConvertUtils.convertList(this.parsePayList(order), OrderPayDetailsDTO.class);
    }

    public List<OrderPayDetails> parsePayList(Order order) {
        List<OrderPayDetails> payDetailsList;
        String payDetailInfo = order.getPayDetailInfo();
        if (!StringUtils.isEmpty(payDetailInfo) && !Objects.equals(payDetailInfo, CommonConstants.PAY_FLAG)) {
            payDetailsList = JSON.parseArray(payDetailInfo, OrderPayDetails.class);
        } else {
            payDetailsList = payDao.selectByOrderNo(order.getOrderNo(), order.getUserId());
        }
        return payDetailsList;
    }

    /**
     * 特殊处理套餐商品模型
     * @param itemList
     * @return:
     * @Date: 2021/3/12 3:40 下午
     */
    public List<OrderItemDTO> reBuildItemList(List<OrderItemDTO> itemList) {
        List<OrderItemDTO> newItemList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(itemList)) {
            for (OrderItemDTO orderItemDTO : itemList) {
                if (CommonConstants.SHOW_ITEM_TYPES.containsKey(orderItemDTO.getItemType())) {
                    newItemList.add(orderItemDTO);
                }
                if (Objects.equals(orderItemDTO.getItemType(), OrderItemTypeEnum.SET_MEAL_ITEM.getCode())) {
                    List<OrderItemDTO> setMealList = new ArrayList<>(itemList.size());
                    for (OrderItemDTO item : itemList) {
                        if (Objects.equals(item.getOwnerId(), orderItemDTO.getId())
                                && Objects.equals(item.getItemType(), OrderItemTypeEnum.SET_MEAL_SUB_ITEM.getCode())) {
                            this.parseBatching(item);
                            setMealList.add(item);
                        }
                    }
                    orderItemDTO.setSetMealItemList(setMealList);
                    newItemList.add(orderItemDTO);
                }
            }
        }
        return newItemList;
    }

    public void setItemBatchingInfo(List<OrderItemDTO> orderItemDTOList) {
        if (!CollectionUtils.isEmpty(orderItemDTOList)) {
            orderItemDTOList.forEach(this::parseBatching);
        }
    }

    private ItemBatchingQuery buildBatchingQuery(OrderItemDTO item) {
        ItemBatchingQuery query = new ItemBatchingQuery();
        query.setUserId(item.getUserId());
        query.setOrderItemId(item.getId());
        query.setPageNo(1);
        query.setPageSize(100);
        return query;
    }

    private void parseBatching(OrderItemDTO item) {
        if (Objects.equals(item.getBatchingInfo(), CommonConstants.ITEM_FLAG)) {
            ItemBatchingQuery query = buildBatchingQuery(item);
            List<OrderItemBatching> batchingList = itemBatchingDao.selectList(query);
            item.setItemBatchingList(ConvertUtils.convertList(batchingList, OrderItemBatchingDTO.class));
        } else {
            item.setItemBatchingList(JSON.parseArray(item.getBatchingInfo(), OrderItemBatchingDTO.class));
        }
    }

    private Map<String, Object> convert(String info) {
        try {
            if (!StringUtils.isEmpty(info)) {
                return JSON.parseObject(info, Map.class);
            }
        } catch (Throwable throwable) {
            logger.error("convert info:{} failed, cause by:{}", info, Throwables.getStackTraceAsString(throwable));
        }
        return null;
    }

    /**
     * 多人点餐
     * 获取orderId
     * @param order
     * @return:
     * @Date: 2020/10/21 6:10 PM
     */
    private Long checkAndGetOrderId(Order order) {
        Long masetId = null;
        if (this.isMultiUser(order, ThreadContext.getBizType())) {
            Map<String, Object> extraMap = order.getExtraMap();
            if (!CollectionUtils.isEmpty(extraMap) && !StringUtils.isEmpty(extraMap.get(CommonConstants.MASTER_ID))) {
                masetId = Long.valueOf(extraMap.get(CommonConstants.MASTER_ID).toString());
            }
        }
        return masetId;
    }

    public void buildSubOrderInfo(Order order, List<OrderItem> itemList, List<OrderDiscount> discountList,
                                  boolean queryDiscountFlag) {
        if (order == null || !this.isMultiUser(order, ThreadContext.getBizType())) {
            return;
        }
        OrderUserRelation relation = relationDao.selectRoot(order.getOrderNo());
        // 只有子订单才需要重新赋值查询
        if (relation == null || Objects.equals(relation.getUserId(), order.getUserId())) {
            return;
        }
        List<OrderItem> orderItems = itemDao.selectByOrderNo(order.getOrderNo(), relation.getUserId());
        if (!CollectionUtils.isEmpty(orderItems)) {
            if (Objects.isNull(itemList)) {
                itemList = new ArrayList<>(orderItems.size());
            }
            itemList.addAll(orderItems);
        }
        // 优惠信息不一定需要查询
        if (queryDiscountFlag) {
            List<OrderDiscount> orderDiscounts = discountDao.selectByOrderNo(order.getOrderNo(), relation.getUserId());
            if (!CollectionUtils.isEmpty(orderDiscounts)) {
                // 只判断null,如果集合是[]，可以填充数据
                if (discountList != null) {
                    discountList.addAll(orderDiscounts);
                }
            }
        }
    }

    public boolean isMultiUser(Order order, Integer bizType) {
        if (order != null) {
            // 单一场景：餐饮-多人点餐业务
            if (CommonConstants.MULTI_BIZ_TYPES.contains(bizType)
                    && CommonConstants.MULTI_USER_ORDER_LIST.contains(order.getOrderSubType())) {
                return true;
            }
            // 兼容烘焙多人点餐场景
            if (Objects.equals(BizTypeEnum.BAKING.getType(), bizType)
                    && Objects.equals(CommonConstants.BAKING_MULTIPLE_USER, order.getOrderSubType())) {
                return true;
            }
        }
        return false;
    }
}
