package com.zm.order.tool.server.helper;

import com.alibaba.fastjson.JSON;
import com.github.dozermapper.core.Mapper;
import com.google.common.collect.Lists;
import com.zm.order.tool.server.component.BusinessHandlerHolder;
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.constants.ExceptionConstants;
import com.zm.order.tool.server.dao.OrderItemDao;
import com.zm.order.tool.server.dao.OrderUserRelationDao;
import com.zm.order.tool.server.dto.*;
import com.zm.order.tool.server.enums.CommentTypeEnum;
import com.zm.order.tool.server.enums.DiscountLevelEnum;
import com.zm.order.tool.server.enums.RoleEnum;
import com.zm.order.tool.server.model.InnerOrderDiscount;
import com.zm.order.tool.server.model.*;
import com.zm.order.tool.server.query.SearchOrderQuery;
import com.zm.order.tool.server.request.UpdateRefundItemRequest;
import com.zm.order.tool.server.request.UpdateRefundsRequest;
import com.zm.util.dto.ExceptionInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.*;

/**
 * @Description 订单写服务辅助类 用于参数校验 数据组装 数据转换
 * @Author: ph
 * @Date: 2019/11/12 11:03
 */
@Component
public class OrderWriteServiceHelper {

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

    @Autowired
    private Mapper mapper;

    @Autowired
    private OrderItemDao orderItemDao;

    @Autowired
    private ShardingKeyGenerator keyGenerator;

    @Autowired
    private OrderUserRelationDao relationDao;

    @Autowired
    private BusinessHandlerHolder businessHandlerHolder;

    private static final String CANCEL_STATUS_TEXT = "已取消";

    private static final String COMPLETE_STATUS_TEXT = "已完成";

    private static final String COMPLETED_AT = "completedAt";

    private static final String ORDER_NO = "orderNo";

    private static final String USER_ID = "userId";

    private static final String SELLER_ID = "sellerId";

    private static final String ORDERS = "orders";

    private static final String EXPRESS_INFO = "expressInfo";

    private static final String EXPRESS_NUMBER = "expressNumber";

    /**
     * 订单已关闭
     */
    private static final Integer ORDER_CLOSE_STATUS = 6;

    public List<OrderItem> getItemList(Order order) {
        List<OrderItem> itemList;
        if (StringUtils.isEmpty(order.getItemInfo()) || Objects.equals(CommonConstants.ITEM_FLAG, order.getItemInfo())) {
            itemList = orderItemDao.selectByOrderNo(order.getOrderNo(), order.getUserId());
        } else {
            itemList = JSON.parseArray(order.getItemInfo(), OrderItem.class);
        }
        return itemList;
    }

    public Refund buildUpdateRefund(UpdateRefundsRequest request, Refund refund) {
        Refund update = new Refund();
        update.setId(refund.getId());
        if (Objects.nonNull(request.getAmount())) {
            update.setAmount(request.getAmount());
        }
        if (Objects.nonNull(request.getRefundAmount())) {
            update.setRefundAmount(request.getRefundAmount());
        }
        if (Objects.nonNull(request.getWalletAmount())) {
            update.setWalletAmount(request.getWalletAmount());
        }
        if (Objects.nonNull(request.getStatus())) {
            update.setStatus(request.getStatus());
        }
        if (Objects.nonNull(request.getDealAt())) {
            update.setDealAt(request.getDealAt());
        }
        if (!StringUtils.isEmpty(request.getExtraMap())) {
            Map<String, Object> extraMap = refund.getExtraMap();
            Map<String, Object> map = JSON.parseObject(request.getExtraMap(), Map.class);
            extraMap.putAll(map);
            update.setExtraMap(extraMap);
        }
        return update;
    }

    public RefundItem buildUpdateRefundItem(UpdateRefundItemRequest request, RefundItem refundItem) {
        RefundItem update = new RefundItem();
        update.setId(refundItem.getId());
        if (Objects.nonNull(request.getDiscountAmount())) {
            update.setDiscountAmount(request.getDiscountAmount());
        }
        if (Objects.nonNull(request.getRefundAmount())) {
            update.setRefundAmount(request.getRefundAmount());
        }
        if (!StringUtils.isEmpty(request.getExtraMap())) {
            Map<String, Object> extraMap = refundItem.getExtraMap();
            Map<String, Object> map = JSON.parseObject(request.getExtraMap(), Map.class);
            extraMap.putAll(map);
            update.setExtraMap(extraMap);
        }
        return update;
    }

    public ExceptionInfo checkCreateOrderParam(OrderCreateDTO orderCreateDTO) {
        if (Objects.isNull(orderCreateDTO)) {
            return ExceptionConstants.PARAM_IS_EMPTY;
        }
        if (StringUtils.isEmpty(orderCreateDTO.getOrderNo())) {
            return ExceptionConstants.PARAM_ORDER_NO_IS_EMPTY;
        }
        if (Objects.isNull(orderCreateDTO.getUserId())) {
            return ExceptionConstants.PARAM_USER_ID_IS_EMPTY;
        }
        if (Objects.isNull(orderCreateDTO.getBizType())) {
            return ExceptionConstants.PARAM_BIZ_TYPE_IS_EMPTY;
        }
        if (Objects.isNull(orderCreateDTO.getActualAmount())) {
            return ExceptionConstants.PARAM_ACTUAL_AMOUNT_IS_EMPTY;
        }
        if (Objects.isNull(orderCreateDTO.getOrderType())) {
            return ExceptionConstants.PARAM_ORDER_TYPE_IS_EMPTY;
        }
        if (Objects.isNull(orderCreateDTO.getSellerId())) {
            return ExceptionConstants.PARAM_SELLER_ID_IS_EMPTY;
        }
        if (Objects.isNull(orderCreateDTO.getSource())) {
            return ExceptionConstants.PARAM_SOURCE_IS_EMPTY;
        }
        if (Objects.isNull(orderCreateDTO.getSourceNo())) {
            return ExceptionConstants.PARAM_SOURCE_NO_IS_EMPTY;
        }
        if (Objects.isNull(orderCreateDTO.getTotalAmount())) {
            return ExceptionConstants.PARAM_TOTAL_AMOUNT_IS_EMPTY;
        }
        if (Objects.isNull(orderCreateDTO.getDiscountAmount())) {
            return ExceptionConstants.PARAM_DISCOUNT_AMOUNT_IS_EMPTY;
        }
        if (Objects.isNull(orderCreateDTO.getFreightAmount())) {
            return ExceptionConstants.PARAM_FREIGHT_AMOUNT_IS_EMPTY;
        }
        if (Objects.isNull(orderCreateDTO.getIsImmediatePerformance())) {
            return ExceptionConstants.PARAM_IS_IMMEDIATE_PERFORMANCE_IS_EMPTY;
        }
        if (Objects.isNull(orderCreateDTO.getItemAmount())) {
            return ExceptionConstants.PARAM_ITEM_AMOUNT_IS_EMPTY;
        }
        if (Objects.isNull(orderCreateDTO.getPayModel())) {
            return ExceptionConstants.PARAM_PAY_MODEL_IS_EMPTY;
        }
        if (Objects.isNull(orderCreateDTO.getStatus())) {
            return ExceptionConstants.PARAM_ORDER_STATUS_IS_EMPTY;
        }
        if (!CollectionUtils.isEmpty(orderCreateDTO.getItemList())) {
            List<OrderItemDTO> list = orderCreateDTO.getItemList();
            for (OrderItemDTO item : list) {
                if (Objects.isNull(item.getNum())) {
                    return ExceptionConstants.PARAM_NUM_IS_EMPTY;
                }
                if (!CollectionUtils.isEmpty(item.getDiscountList())) {
                    List<OrderDiscountDTO> discountList = item.getDiscountList();
                    ExceptionInfo exceptionInfo = checkDiscountList(discountList);
                    if (Objects.nonNull(exceptionInfo)) {
                        return exceptionInfo;
                    }
                }
            }
        }
        if (!CollectionUtils.isEmpty(orderCreateDTO.getOrderDiscountList())) {
            List<OrderDiscountDTO> list = orderCreateDTO.getOrderDiscountList();
            ExceptionInfo exceptionInfo = checkDiscountList(list);
            if (Objects.nonNull(exceptionInfo)) {
                return exceptionInfo;
            }
        }
        return ExceptionConstants.OK;
    }

    private ExceptionInfo checkDiscountList(List<OrderDiscountDTO> list) {
        for (OrderDiscountDTO discount : list) {
            if (Objects.isNull(discount.getDiscountId())) {
                return ExceptionConstants.PARAM_DISCOUNT_ID_IS_EMPTY;
            }
            if (StringUtils.isEmpty(discount.getDiscountName())) {
                return ExceptionConstants.PARAM_DISCOUNT_NAME_IS_EMPTY;
            }
            if (Objects.isNull(discount.getDiscountType())) {
                return ExceptionConstants.PARAM_DISCOUNT_TYPE_IS_EMPTY;
            }
            if (Objects.isNull(discount.getDiscountAmount())) {
                return ExceptionConstants.PARAM_DISCOUNT_AMOUNT_IS_EMPTY;
            }
        }
        return null;
    }


    public ExceptionInfo checkOperateOrder(OrderOperateDTO orderOperateDTO) {
        if (Objects.isNull(orderOperateDTO)) {
            return ExceptionConstants.PARAM_IS_EMPTY;
        }
        if (StringUtils.isEmpty(orderOperateDTO.getOrderNo())) {
            return ExceptionConstants.PARAM_ORDER_NO_IS_EMPTY;
        }
        if (Objects.isNull(orderOperateDTO.getUserId())) {
            return ExceptionConstants.PARAM_USER_ID_IS_EMPTY;
        }
        if (StringUtils.isEmpty(orderOperateDTO.getOperation())) {
            return ExceptionConstants.PARAM_OPERATION_IS_EMPTY;
        }
        if (Objects.isNull(orderOperateDTO.getRole())) {
            return ExceptionConstants.PARAM_ROLE_IS_EMPTY;
        }
        if (Objects.isNull(orderOperateDTO.getOperator())) {
            return ExceptionConstants.PARAM_OPERATOR_IS_EMPTY;
        }
        return ExceptionConstants.OK;
    }

    public ExceptionInfo checkOperateOrderParam(OrderOperateDTO orderOperateDTO) {
        if (Objects.isNull(orderOperateDTO)) {
            return ExceptionConstants.PARAM_IS_EMPTY;
        }
        if (StringUtils.isEmpty(orderOperateDTO.getOrderNo())) {
            return ExceptionConstants.PARAM_ORDER_NO_IS_EMPTY;
        }
        if (StringUtils.isEmpty(orderOperateDTO.getOperation())) {
            return ExceptionConstants.PARAM_OPERATION_IS_EMPTY;
        }
        if (Objects.isNull(orderOperateDTO.getRole())) {
            return ExceptionConstants.PARAM_ROLE_IS_EMPTY;
        }
        if (Objects.isNull(orderOperateDTO.getOperator())) {
            return ExceptionConstants.PARAM_OPERATOR_IS_EMPTY;
        }
        return ExceptionConstants.OK;
    }

    public ExceptionInfo checkAutoCancelOrderParam(OrderOperateDTO orderOperateDTO) {
        if (Objects.isNull(orderOperateDTO)) {
            return ExceptionConstants.PARAM_IS_EMPTY;
        }
        if (StringUtils.isEmpty(orderOperateDTO.getOrderNo())) {
            return ExceptionConstants.PARAM_ORDER_NO_IS_EMPTY;
        }
        if (Objects.isNull(orderOperateDTO.getUserId())) {
            return ExceptionConstants.PARAM_USER_ID_IS_EMPTY;
        }
        if (StringUtils.isEmpty(orderOperateDTO.getOperation())) {
            return ExceptionConstants.PARAM_OPERATION_IS_EMPTY;
        }
        if (Objects.isNull(orderOperateDTO.getRole())) {
            return ExceptionConstants.PARAM_ROLE_IS_EMPTY;
        }
        if (Objects.isNull(orderOperateDTO.getOperator())) {
            return ExceptionConstants.PARAM_OPERATOR_IS_EMPTY;
        }
        return ExceptionConstants.OK;
    }

    public ExceptionInfo checkAutoCompleteOrderParam(OrderOperateDTO orderOperateDTO) {
        if (Objects.isNull(orderOperateDTO)) {
            return ExceptionConstants.PARAM_IS_EMPTY;
        }
        if (StringUtils.isEmpty(orderOperateDTO.getOrderNo())) {
            return ExceptionConstants.PARAM_ORDER_NO_IS_EMPTY;
        }
        if (Objects.isNull(orderOperateDTO.getUserId())) {
            return ExceptionConstants.PARAM_USER_ID_IS_EMPTY;
        }
        if (StringUtils.isEmpty(orderOperateDTO.getOperation())) {
            return ExceptionConstants.PARAM_OPERATION_IS_EMPTY;
        }
        if (Objects.isNull(orderOperateDTO.getRole())) {
            return ExceptionConstants.PARAM_ROLE_IS_EMPTY;
        }
        if (Objects.isNull(orderOperateDTO.getOperator())) {
            return ExceptionConstants.PARAM_OPERATOR_IS_EMPTY;
        }
        return ExceptionConstants.OK;
    }

    public ExceptionInfo checkPerformanceOrderParam(OrderPerformanceDTO orderPerformanceDTO) {
        if (Objects.isNull(orderPerformanceDTO)) {
            return ExceptionConstants.PARAM_IS_EMPTY;
        }
        if (StringUtils.isEmpty(orderPerformanceDTO.getOrderNo())) {
            return ExceptionConstants.PARAM_ORDER_NO_IS_EMPTY;
        }
        if (Objects.isNull(orderPerformanceDTO.getUserId())) {
            return ExceptionConstants.PARAM_USER_ID_IS_EMPTY;
        }
        if (Objects.isNull(orderPerformanceDTO.getPerformanceType())) {
            return ExceptionConstants.PARAM_PERFORMANCE_TYPE_IS_EMPTY;
        }
        return checkOperateOrder(orderPerformanceDTO);
    }

    public ExceptionInfo checkAddOrderDiscountParam(OrderAddDiscountDTO orderAddDiscountDTO) {

        if (Objects.isNull(orderAddDiscountDTO) || CollectionUtils.isEmpty(orderAddDiscountDTO.getOrderDiscountList())) {
            return ExceptionConstants.PARAM_IS_EMPTY;
        }

        if (Objects.isNull(orderAddDiscountDTO.getRole())) {
            return ExceptionConstants.PARAM_ROLE_IS_EMPTY;
        }
        if (StringUtils.isEmpty(orderAddDiscountDTO.getOperation())) {
            return ExceptionConstants.PARAM_OPERATION_IS_EMPTY;
        }
        if (Objects.isNull(orderAddDiscountDTO.getOperator())) {
            return ExceptionConstants.PARAM_OPERATOR_IS_EMPTY;
        }
        if (Objects.equals(orderAddDiscountDTO.getRole(), RoleEnum.USER)) {
            if (Objects.isNull(orderAddDiscountDTO.getOrderNo())) {
                return ExceptionConstants.PARAM_ORDER_NO_IS_EMPTY;
            }
            if (Objects.isNull(orderAddDiscountDTO.getUserId())) {
                return ExceptionConstants.PARAM_USER_ID_IS_EMPTY;
            }
        }
        if (Objects.equals(orderAddDiscountDTO.getRole(), RoleEnum.SELLER)) {
            if (Objects.isNull(orderAddDiscountDTO.getOrderNo())) {
                return ExceptionConstants.PARAM_ORDER_NO_IS_EMPTY;
            }
        }
        return ExceptionConstants.OK;
    }


    public Order buildOrder(OrderCreateDTO orderCreateDTO) {
        Order order = mapper.map(orderCreateDTO, Order.class);
        order.setId(keyGenerator.generateSnowflakeNumKey());
        order = completeOrder(order);
        return order;
    }

    public List<OrderDiscount> buildOrderDiscount(OrderAddDiscountDTO orderAddDiscountDTO, Order order) {
        List<OrderDiscount> discountList = Lists.newArrayList();
        List<OrderDiscountDTO> orderDiscountList = orderAddDiscountDTO.getOrderDiscountList();
        Integer bizType = ThreadContext.getBizType();
        if (!CollectionUtils.isEmpty(orderDiscountList)) {
            for (OrderDiscountDTO orderDiscountDTO : orderDiscountList) {
                OrderDiscount orderDiscount = mapper.map(orderDiscountDTO, OrderDiscount.class);
                orderDiscount.setId(keyGenerator.generateSnowflakeNumKey());
                orderDiscount.setUserId(order.getUserId());
                orderDiscount.setOrderNo(order.getOrderNo());
                orderDiscount.setBizType(bizType != null ? bizType : 0);
                orderDiscount.setSellerId(order.getSellerId());
                //构建默认值
                orderDiscount = orderDiscountInsert(orderDiscount);
                discountList.add(orderDiscount);
            }
        }
        return discountList;

    }

    public List<OrderDiscount> buildOrderDisCountList(OrderAdjustItemDTO orderAdjustItemDTO, Order order) {
        List<OrderDiscount> discountList = Lists.newArrayList();
        List<OrderDiscountDTO> orderDiscountList = orderAdjustItemDTO.getOrderDiscountList();
        Integer bizType = ThreadContext.getBizType();
        if (!CollectionUtils.isEmpty(orderDiscountList)) {
            orderDiscountList.forEach(orderDiscountDTO -> {
                OrderDiscount orderDiscount = mapper.map(orderDiscountDTO, OrderDiscount.class);
                orderDiscount.setDiscountLevel(DiscountLevelEnum.ORDER.getLevel());
                orderDiscount.setOrderNo(order.getOrderNo());
                orderDiscount.setUserId(order.getUserId());
                orderDiscount.setId(keyGenerator.generateSnowflakeNumKey());
                orderDiscount.setBizType(bizType != null ? bizType : 0);
                //构建默认值
                orderDiscount = orderDiscountInsert(orderDiscount);
                discountList.add(orderDiscount);
            });
        }
        return discountList;
    }

    public List<OrderItem> buildOrderItemList(OrderAdjustItemDTO orderAdjustItemDTO, Order order) {
        List<OrderItem> orderItemList = Lists.newArrayList();
        List<OrderItemDTO> orderItemDtoList = orderAdjustItemDTO.getAddItemList();
        Integer bizType = ThreadContext.getBizType();
        if (!CollectionUtils.isEmpty(orderItemDtoList)) {
            orderItemDtoList.forEach(orderItemDTO -> {
                OrderItem orderItem = mapper.map(orderItemDTO, OrderItem.class);
                orderItem.setOrderNo(order.getOrderNo());
                orderItem.setUserId(order.getUserId());
                orderItem.setId(keyGenerator.generateSnowflakeNumKey());
                orderItem.setBizType(bizType != null ? bizType : 0);
                //  构建默认值
                orderItem = orderItemInsert(orderItem);
                orderItemList.add(orderItem);
            });
        }
        return orderItemList;
    }


    public List<OrderItemBatching> buildItemBatchingList(List<OrderItem> addItemList, Order order) {
        if (CollectionUtils.isEmpty(addItemList)) {
            return Collections.EMPTY_LIST;
        }
        List<OrderItemBatching> batchingList = new ArrayList<>(addItemList.size());
        for (OrderItem orderItem : addItemList) {
            if (!StringUtils.isEmpty(orderItem.getBatchingInfo())) {
                List<OrderItemBatching> itemBatchingList =
                        JSON.parseArray(orderItem.getBatchingInfo(), OrderItemBatching.class);
                if (!CollectionUtils.isEmpty(itemBatchingList)) {
                    itemBatchingList.forEach(batching -> {
                        setDefaultValue(batching, order);
                        batchingList.add(batching);
                    });
                }
            }
        }
        return batchingList;
    }

    private void setDefaultValue(OrderItemBatching batching, Order order) {
        batching.setOrderNo(order.getOrderNo());
        batching.setUserId(order.getUserId());
        batching.setSellerId(order.getSellerId());
        batching.setStoreId(order.getStoreId());
    }


    public List<OrderDiscount> buildOrderDisCountList(OrderCreateDTO orderCreateDTO, Order order) {
        List<OrderDiscount> discountList = Lists.newArrayList();
        List<OrderDiscountDTO> orderDiscountList = CollectionUtils.isEmpty(orderCreateDTO.getOrderDiscountList()) ?
                orderCreateDTO.getDiscountList() : orderCreateDTO.getOrderDiscountList();
        List<InnerOrderDiscount> innerOrderDiscountList = Lists.newArrayListWithCapacity(discountList.size());
        if (!CollectionUtils.isEmpty(orderDiscountList)) {
            orderDiscountList.forEach(orderDiscountDTO -> {
                InnerOrderDiscount innerOrderDiscount = mapper.map(orderDiscountDTO, InnerOrderDiscount.class);
                innerOrderDiscountList.add(innerOrderDiscount);
                OrderDiscount orderDiscount = mapper.map(orderDiscountDTO, OrderDiscount.class);
                orderDiscount.setBizType(orderCreateDTO.getBizType());
                orderDiscount.setDiscountLevel(DiscountLevelEnum.ORDER.getLevel());
                orderDiscount.setOrderNo(orderCreateDTO.getOrderNo());
                orderDiscount.setUserId(orderCreateDTO.getUserId());
                orderDiscount.setId(keyGenerator.generateSnowflakeNumKey());
                orderDiscount.setSellerId(orderCreateDTO.getSellerId());
                orderDiscount.setCreatedAt(order.getCreatedAt());
                orderDiscount.setUpdatedAt(order.getUpdatedAt());
                //构建默认值
                orderDiscount = orderDiscountInsert(orderDiscount);
                discountList.add(orderDiscount);
            });
            order.setDiscountInfo(JSON.toJSONString(innerOrderDiscountList));
        }
        return discountList;
    }

    public List<OrderItem> buildOrderItem(OrderCreateDTO orderCreateDTO, Order order) {
        List<OrderItem> orderItemList = Lists.newArrayList();
        List<OrderItemDTO> itemList = orderCreateDTO.getItemList();
        List<InnerOrderItem> innerOrderItemList = Lists.newArrayListWithCapacity(orderItemList.size());
        if (!CollectionUtils.isEmpty(itemList)) {
            itemList.forEach(orderItemDTO -> {
                OrderItem orderItem = mapper.map(orderItemDTO, OrderItem.class);
                if (Objects.isNull(orderItemDTO.getMemberPrice())) {
                    orderItem.setMemberPrice(-1);
                }
                orderItem.setCreatedAt(orderCreateDTO.getCreatedAt());
                orderItem.setBizType(orderCreateDTO.getBizType());
                orderItem.setOrderNo(orderCreateDTO.getOrderNo());
                orderItem.setUserId(orderCreateDTO.getUserId());
                orderItem.setId(keyGenerator.generateSnowflakeNumKey());
                // 构建默认值
                if (Objects.isNull(orderItem.getOrderAt())) {
                    orderItem.setOrderAt(new Date());
                }
                if (Objects.isNull(orderItem.getPaidAmount())) {
                    orderItem.setPaidAmount(0);
                }
                //  构建默认值
                orderItem = orderItemInsert(orderItem);
                orderItemList.add(orderItem);
                InnerOrderItem innerOrderItem = mapper.map(orderItem, InnerOrderItem.class);
                innerOrderItemList.add(innerOrderItem);
            });
            if (innerOrderItemList.size() > CommonConstants.MAX_ITEM_SIZE) {
                order.setItemInfo(CommonConstants.ITEM_FLAG);
            } else {
                order.setItemInfo(JSON.toJSONString(innerOrderItemList));
            }
        }
        return orderItemList;
    }

    public OrderAddr buildOrderAddr(OrderCreateDTO orderCreateDTO, Order order) {
        OrderAddrDTO orderAddrDTO = orderCreateDTO.getAddr();
        if (Objects.isNull(orderAddrDTO)) {
            return null;
        }
        if (StringUtils.isEmpty(orderAddrDTO.getAcceptName()) && StringUtils.isEmpty(orderAddrDTO.getStreet())) {
            return null;
        }
        OrderAddr orderAddr = mapper.map(orderAddrDTO, OrderAddr.class);
        orderAddr.setId(keyGenerator.generateSnowflakeNumKey());
        orderAddr.setOrderNo(orderCreateDTO.getOrderNo());
        orderAddr.setCreatedAt(orderCreateDTO.getCreatedAt());
        orderAddr.setUpdatedAt(orderCreateDTO.getUpdatedAt());
        orderAddr.setUserId(orderCreateDTO.getUserId());
        orderAddr.setSellerId(Objects.nonNull(orderCreateDTO.getSellerId()) ? orderCreateDTO.getSellerId() : 0L);
        if (Objects.isNull(orderAddrDTO.getSex())) {
            orderAddr.setSex(0);
        }
        if (Objects.isNull(orderAddrDTO.getProvince())) {
            orderAddr.setProvince(0);
        }
        if (Objects.isNull(orderAddrDTO.getCity())) {
            orderAddr.setCity(0);
        }
        if (Objects.isNull(orderAddrDTO.getArea())) {
            orderAddr.setArea(0);
        }
        if (Objects.isNull(orderAddrDTO.getLabel())) {
            orderAddr.setLabel(0);
        }

        if (orderAddr != null && order != null) {
            order.setAddrInfo(JSON.toJSONString(orderAddr));
        }
        return orderAddr;
    }


    public BaseCreateOrderDTO buildOrderHolder(Order order, List<OrderItem> itemList,
                                             List<OrderDiscount> discountList, OrderCreateDTO orderCreateDTO,
                                             OrderAddr orderAddr, List<OrderItemBatching> itemBatchingList,
                                             List<OrderPayDetails> payDetailsList ) {
        BaseCreateOrderDTO orderDTO = new BaseCreateOrderDTO();
        orderDTO.setOrder(order);
        orderDTO.setItemList(itemList);
        orderDTO.setDiscountList(discountList);
        orderDTO.setOperateDTO(orderCreateDTO);
        orderDTO.setOrderAddr(orderAddr);
        orderDTO.setItemBatchingList(itemBatchingList);
        orderDTO.setPayDetailsList(payDetailsList);
        return orderDTO;
    }


    public List<OrderPayDetails> buildOrderPayDetails(OrderCreateDTO orderCreateDTO, Order order) {
        List<OrderPayDetailsDTO> payDetailsDTOList = orderCreateDTO.getPayDetailsList();
        if (CollectionUtils.isEmpty(payDetailsDTOList)) {
            return Collections.EMPTY_LIST;
        }
        List<OrderPayDetails> payDetailsList = new ArrayList<>(payDetailsDTOList.size());
        List<InnerOrderPayDetails> innerOrderPayDetailsList = new ArrayList<>(payDetailsDTOList.size());
        for (OrderPayDetailsDTO payDetailDto : payDetailsDTOList) {
            OrderPayDetails payDetail = mapper.map(payDetailDto, OrderPayDetails.class);
            setPayDetailsParam(order, payDetail);
            payDetailsList.add(payDetail);
            innerOrderPayDetailsList.add(mapper.map(payDetail, InnerOrderPayDetails.class));
        }
        setPayDetailInfo(null, order, innerOrderPayDetailsList);
        return payDetailsList;
    }

    private void setPayDetailInfo(Order order, Order update, List<InnerOrderPayDetails> payDetailsList) {
        if (order == null) {
            setPayDetails(update, payDetailsList);
            return;
        }
        String payDetailInfo = order.getPayDetailInfo();
        if (StringUtils.isEmpty(payDetailInfo)) {
            setPayDetails(update, payDetailsList);
            return;
        }
        // 追加支付信息
        if (!Objects.equals(payDetailInfo, CommonConstants.PAY_FLAG)) {
            List<InnerOrderPayDetails> payDetailsListDo = JSON.parseArray(payDetailInfo, InnerOrderPayDetails.class);
            payDetailsList.addAll(payDetailsListDo);
            setPayDetails(update, payDetailsList);
        } else {
            // 如果payDetailInfo已经是"PF"了，置空，避免再次更新一次
            update.setPayDetailInfo(null);
        }
    }

    private void setPayDetails(Order order, List<InnerOrderPayDetails> payDetailsList) {
        if (payDetailsList.size() > CommonConstants.MAX_ITEM_SIZE) {
            order.setPayDetailInfo(CommonConstants.PAY_FLAG);
        } else {
            order.setPayDetailInfo(JSON.toJSONString(payDetailsList));
        }
    }

    private void setPayDetailsParam(Order order, OrderPayDetails payDetail) {
        payDetail.setId(keyGenerator.generateSnowflakeNumKey());
        payDetail.setOrderNo(order.getOrderNo());
        payDetail.setUserId(order.getUserId());
        payDetail.setOrderAt(order.getOrderAt());
        payDetail.setSellerId(order.getSellerId());
        payDetail.setStoreId(order.getStoreId());
        payDetail.setOrderType(order.getOrderType());
        payDetail.setSource(Objects.nonNull(order.getSource()) ? order.getSource() : 0);
        if (StringUtils.isEmpty(payDetail.getPayNo())) {
            payDetail.setPayNo("");
        }
        if (StringUtils.isEmpty(payDetail.getThirdPayNo())) {
            payDetail.setThirdPayNo("");
        }
    }

    public List<OrderItemBatching> buildItemBatching(OrderCreateDTO orderCreateDTO, List<OrderItem> itemList) {
        if (CollectionUtils.isEmpty(itemList)) {
            return Collections.EMPTY_LIST;
        }
        List<OrderItemBatching> itemBatchingList = new ArrayList<>();
        itemList.forEach(item -> {
            String batchingInfo = item.getBatchingInfo();
            if (!StringUtils.isEmpty(batchingInfo)) {
                List<OrderItemBatching> batchingList = JSON.parseArray(batchingInfo, OrderItemBatching.class);
                if (!CollectionUtils.isEmpty(batchingList)) {
                    batchingList.forEach(batching -> {
                        OrderItemBatching itemBatching = mapper.map(batching, OrderItemBatching.class);
                        buildDefaultValue(itemBatching, orderCreateDTO);
                        itemBatchingList.add(itemBatching);
                    });
                }
            }
        });
        return itemBatchingList;
    }

    private void buildDefaultValue(OrderItemBatching itemBatching, OrderCreateDTO orderCreateDTO) {
        itemBatching.setId(keyGenerator.generateSnowflakeNumKey());
        itemBatching.setOrderNo(orderCreateDTO.getOrderNo());
        itemBatching.setUserId(orderCreateDTO.getUserId());
        itemBatching.setSellerId(orderCreateDTO.getSellerId());
        itemBatching.setStoreId(orderCreateDTO.getStoreId());
        if (StringUtils.isEmpty(itemBatching.getCode())) {
            itemBatching.setCode("");
        }
    }


    public Order buildPerformanceUpdate(Order order, Integer status, OrderPerformanceDTO orderPerformanceDTO) {
        Order update = new Order();
        update.setId(order.getId());
        update.setUserId(order.getUserId());
        update.setStatus(status);
        update.setPerformanceType(orderPerformanceDTO.getPerformanceType());
        update.setPerformancePlatform(orderPerformanceDTO.getPerformancePlatform());
        if (!StringUtils.isEmpty(order.getPerformanceInfo()) && !CollectionUtils.isEmpty(orderPerformanceDTO.getPerformanceInfoMap())) {
            Map<String, Object> performanceInfoMap = JSON.parseObject(order.getPerformanceInfo(), Map.class);
            performanceInfoMap.putAll(orderPerformanceDTO.getPerformanceInfoMap());
            update.setPerformanceInfo(JSON.toJSONString(performanceInfoMap));
        }
        update.setVersion(order.getVersion());
        return update;
    }


    public SearchOrderQuery buildSearchOrderQuery(OrderAddDiscountDTO orderAddDiscountDTO) {
        SearchOrderQuery searchOrderQuery = new SearchOrderQuery();
        searchOrderQuery.setOrderNo(orderAddDiscountDTO.getOrderNo());
        return searchOrderQuery;
    }

    public List<OrderPayDetails> buildOrderPayDetails(OrderOperateDTO orderOperateDTO, Order order, Order update) {
        List<OrderPayDetailsDTO> payDetailsDTOList = orderOperateDTO.getPayDetailsList();
        if (CollectionUtils.isEmpty(payDetailsDTOList)) {
            return Collections.EMPTY_LIST;
        }
        List<OrderPayDetails> payDetailsList = new ArrayList<>(payDetailsDTOList.size());
        List<InnerOrderPayDetails> innerOrderPayDetailsList = new ArrayList<>(payDetailsList.size());
        for (OrderPayDetailsDTO payDetailDto : payDetailsDTOList) {
            OrderPayDetails payDetail = mapper.map(payDetailDto, OrderPayDetails.class);
            setPayDetailsParam(order, payDetail);
            payDetailsList.add(payDetail);
            innerOrderPayDetailsList.add(mapper.map(payDetailDto, InnerOrderPayDetails.class));
        }
        setPayDetailInfo(order, update, innerOrderPayDetailsList);
        return payDetailsList;
    }


    public Order completeOrder(Order order) {
        if (Objects.isNull(order.getOrderSubType())) {
            order.setOrderSubType(0);
        }
        if (Objects.isNull(order.getAddrId())) {
            order.setAddrId(0);
        }
        if (Objects.isNull(order.getSource())) {
            order.setSource(0);
        }
        if (Objects.isNull(order.getPayModel())) {
            order.setPayModel(0);
        }
        if (Objects.isNull(order.getItemAmount())) {
            order.setItemAmount(0);
        }
        if (Objects.isNull(order.getCostAmount())) {
            order.setCostAmount(0);
        }
        if (Objects.isNull(order.getPackAmount())) {
            order.setPackAmount(0);
        }
        if (Objects.isNull(order.getFreightAmount())) {
            order.setFreightAmount(0);
        }
        if (Objects.isNull(order.getDiscountAmount())) {
            order.setDiscountAmount(0);
        }
        if (Objects.isNull(order.getPayAmount())) {
            order.setPayAmount(0);
        }
        if (Objects.isNull(order.getChangeAmount())) {
            order.setChangeAmount(0);
        }
        if (Objects.isNull(order.getInvoiceType())) {
            order.setInvoiceType(0);
        }
        if (Objects.isNull(order.getIsImmediatePerformance())) {
            order.setIsImmediatePerformance(0);
        }
        if (Objects.isNull(order.getPerformanceType())) {
            order.setPerformanceType(0);
        }
        if (Objects.isNull(order.getStatus())) {
            order.setStatus(0);
        }
        if (Objects.isNull(order.getPerformanceStatus())) {
            order.setPerformanceStatus(0);
        }
        if (Objects.isNull(order.getPayStatus())) {
            order.setPayStatus(0);
        }
        if (Objects.isNull(order.getIsReceipt())) {
            order.setIsReceipt(0);
        }
        if (Objects.isNull(order.getPayer())) {
            order.setPayer(0L);
        }
        if (Objects.isNull(order.getPayType())) {
            order.setPayType(0);
        }
        if (Objects.isNull(order.getIsAlone())) {
            order.setIsAlone(0);
        }
        if (Objects.isNull(order.getAfterSaleStatus())) {
            order.setAfterSaleStatus(0);
        }
        if (Objects.isNull(order.getReceiveStatus())) {
            order.setReceiveStatus(0);
        }
        if (Objects.isNull(order.getCommentStatus())) {
            order.setCommentStatus(0);
        }
        if (Objects.isNull(order.getOrderAt())) {
            order.setOrderAt(new Date());
        }
        completeOrder1(order);
        return order;
    }

    private void completeOrder1(Order order) {
        if (Objects.isNull(order.getFromSystem())) {
            order.setFromSystem(0);
        }
        if (Objects.isNull(order.getBizSubType())) {
            order.setBizSubType(0);
        }
        if (Objects.isNull(order.getPayFlag())) {
            order.setPayFlag(0);
        }
        if (Objects.isNull(order.getStoreId())) {
            order.setStoreId(0L);
        }
        order.setIsDeleted(0);
        order.setVersion(1);
        Map<String, Object> extraMap = order.getExtraMap();
        if (CollectionUtils.isEmpty(extraMap)) {
            extraMap = new HashMap<>(1);
        }
        order.setExtraMap(extraMap);

        if (Objects.isNull(order.getRefundFlag())) {
            order.setRefundFlag(0);
        }
    }


    public OrderItem orderItemInsert(OrderItem orderItem) {
        if (Objects.isNull(orderItem.getMarketPrice())) {
            orderItem.setMarketPrice(0);
        }
        if (Objects.isNull(orderItem.getCostPrice())) {
            orderItem.setCostPrice(0);
        }
        if (Objects.isNull(orderItem.getMemberPrice())) {
            orderItem.setMemberPrice(0);
        }
        if (Objects.isNull(orderItem.getItemPrice())) {
            orderItem.setItemPrice(0);
        }
        if (Objects.isNull(orderItem.getNum())) {
            orderItem.setNum(new BigDecimal(0));
        }
        if (Objects.isNull(orderItem.getDiscountAmount())) {
            orderItem.setDiscountAmount(0);
        }
        if (Objects.isNull(orderItem.getPackAmount())) {
            orderItem.setPackAmount(0);
        }
        if (Objects.isNull(orderItem.getGoodsId())) {
            orderItem.setGoodsId(0L);
        }
        if (Objects.isNull(orderItem.getActivityId())) {
            orderItem.setActivityId(0L);
        }
        if (Objects.isNull(orderItem.getIsTimeDiscount())) {
            orderItem.setIsTimeDiscount(0);
        }
        if (Objects.isNull(orderItem.getIsGift())) {
            orderItem.setIsGift(0);
        }
        if (Objects.isNull(orderItem.getUserId())) {
            orderItem.setUserId(0L);
        }
        if (Objects.isNull(orderItem.getStatus())) {
            orderItem.setStatus(0);
        }
        if (Objects.isNull(orderItem.getOrderAt())) {
            orderItem.setOrderAt(new Date());
        }
        if (Objects.isNull(orderItem.getItemType())) {
            orderItem.setItemType(0);
        }
        return orderItem;
    }

    private OrderDiscount orderDiscountInsert(OrderDiscount orderDiscount) {
        if (Objects.isNull(orderDiscount.getDiscountLevel())) {
            orderDiscount.setDiscountLevel(0);
        }
        if (Objects.isNull(orderDiscount.getDiscountType())) {
            orderDiscount.setDiscountType(0);
        }
        if (Objects.isNull(orderDiscount.getDiscountAmount())) {
            orderDiscount.setDiscountAmount(0);
        }
        if (Objects.isNull(orderDiscount.getUserId())) {
            orderDiscount.setUserId(0L);
        }
        return orderDiscount;
    }


    public List<OrderItem> converter(Order order) {
        List<OrderItem> orderItemList = Lists.newArrayList();
        if (order != null) {
            orderItemList = orderItemDao.selectByOrderNo(order.getOrderNo(), order.getUserId());
        }
        return orderItemList;
    }


    /**
     * 参数聚合 [param polymerize]
     *
     * @param before
     * @param after
     * @return: com.zm.order.biz.model.Order
     * @Date: 2020/4/20 11:57 AM
     */
    private Order paramPolymerize(Order before, Order after) {
        try {
            if (Objects.nonNull(before) && Objects.nonNull(after)) {
                Field[] fields = after.getClass().getDeclaredFields();
                for (int i = 0; i < fields.length; i++) {
                    fields[i].setAccessible(true);
                    if (fields[i].get(after) != null) {
                        fields[i].set(before, fields[i].get(after));
                    }
                }
            }
        } catch (IllegalAccessException e) {
            logger.error("OrderWriteServiceHelper[paramPolymerize] polymerize failed,request1:{},request2:{},cause by:{}",
                    before, after, e);
            throw new RuntimeException("同步es数据转换异常");
        }
        return before;
    }

    public OrderPerformanceDTO convertPerformanceInfo(OrderCreateDTO orderCreateDTO) {
        OrderPerformanceDTO performanceDTO = new OrderPerformanceDTO();
        if (orderCreateDTO != null) {
            performanceDTO.setPerformanceType(orderCreateDTO.getPerformanceType());
            Map<String, Object> tempPerformanceInfo = orderCreateDTO.getTempPerformanceInfo();
            if (!CollectionUtils.isEmpty(tempPerformanceInfo)) {
                tempPerformanceInfo.put(ORDER_NO, orderCreateDTO.getOrderNo());
                tempPerformanceInfo.put(USER_ID, orderCreateDTO.getUserId());
                tempPerformanceInfo.put(SELLER_ID, orderCreateDTO.getSellerId());
            }
            performanceDTO.setPerformanceInfoMap(tempPerformanceInfo);
        }
        return performanceDTO;
    }


    public List<Long> mergeItem(List<Long> deleteItemList, List<InnerOrderItem> innerItemList) {
        List<Long> adjustItemList = new ArrayList<>();
        Iterator<InnerOrderItem> iterator = innerItemList.iterator();
        while (iterator.hasNext()) {
            InnerOrderItem orderItem = iterator.next();
            if (deleteItemList.contains(orderItem.getId())) {
                adjustItemList.add(orderItem.getId());
                iterator.remove();
            }
        }
        return adjustItemList;
    }

    public Order buildUpdateParam(Order order, List<InnerOrderItem> itemList) {
        Order update = new Order();
        update.setId(order.getId());
        update.setUserId(order.getUserId());
        if (itemList.size() < 10) {
            update.setItemInfo(JSON.toJSONString(itemList));
        }
        update.setVersion(order.getVersion());
        return update;
    }

    public void buildUpdateCommentCountForDel(OrderCommentCount orderCommentCount, OrderComment orderComment){
        orderCommentCount.setCommentCount(orderCommentCount.getCommentCount()-1);
        if(CommentTypeEnum.GOOD_COMMENT.getType().equals(orderComment.getCommentType())){
            Integer goodCount = orderCommentCount.getGoodCount() - 1;
            if (goodCount < 0) {
                goodCount = 0;
            }
            orderCommentCount.setGoodCount(goodCount);
        }
        if(CommentTypeEnum.BAD_COMMENT.getType().equals(orderComment.getCommentType())){
            Integer badCount = orderCommentCount.getBadCount() - 1;
            if (badCount < 0) {
                badCount = 0;
            }
            orderCommentCount.setBadCount(badCount);
        }
        if(CommentTypeEnum.MIDDLE_COMMENT.getType().equals(orderComment.getCommentType())){
            Integer middleCount = orderCommentCount.getMiddleCount() - 1;
            if (middleCount < 0) {
                middleCount = 0;
            }
            orderCommentCount.setMiddleCount(middleCount);
        }
        if(Objects.equals(1, orderComment.getSellerReply())){
            Integer replyCount = orderCommentCount.getReplyCount() - 1;
            if (replyCount < 0) {
                replyCount = 0;
            }
            orderCommentCount.setReplyCount(replyCount);
        }
        if(Objects.equals(1, orderComment.getQuality())){
            Integer qualityCount = orderCommentCount.getQualityCount() - 1;
            if (qualityCount < 0) {
                qualityCount = 0;
            }
            orderCommentCount.setQualityCount(qualityCount);
        }
        if(Objects.equals(1, orderComment.getExistImage())){
            Integer imageCount = orderCommentCount.getImageCount() - 1;
            if (imageCount < 0) {
                imageCount = 0;
            }
            orderCommentCount.setImageCount(imageCount);
        }
        if(Objects.equals(1, orderComment.getExistRecommend())){
            Integer recommendCount = orderCommentCount.getRecommendCount() - 1;
            if (recommendCount < 0) {
                recommendCount = 0;
            }
            orderCommentCount.setRecommendCount(recommendCount);
        }
    }

    public List<String> addElement(String orderNo, String mobile) {
        List<String> likeSearch = new ArrayList<>(2);
        try {
            // 手机号截取后四位支持搜索
            if (!StringUtils.isEmpty(mobile)) {
                String suffix;
                if (mobile.contains(",")) {
                    int idx = mobile.indexOf(",");
                    suffix = mobile.substring(idx - 4, idx);
                } else {
                    suffix = mobile.substring(mobile.length() - 4);
                }
                likeSearch.add(suffix);
            }
            // 订单号截取后六位支持搜索
            if (!StringUtils.isEmpty(orderNo)) {
                likeSearch.add(orderNo.substring(orderNo.length() - 6));
            }
        } catch (Exception e) {
            logger.error("[buildLikeSearch]failed! orderNo:{}, cause by:{}", orderNo, e);
        }
        return likeSearch;
    }

    public void parseItem(List<OrderItem> itemList, List<String> searchCondition, Set<Integer> itemTypeSet,
                          Set<String> itemIdList, Set<String> itemNameList, Set<String> itemBarcodeList) {
        for (OrderItem item : itemList) {
            if (!StringUtils.isEmpty(item.getItemName())) {
                itemNameList.add(item.getItemName());
                searchCondition.add(item.getItemName());
            }
            if (Objects.nonNull(item.getItemId())) {
                itemIdList.add(item.getItemId());
                searchCondition.add(item.getItemId());
            }
            if (Objects.nonNull(item.getItemType())) {
                itemTypeSet.add(item.getItemType());
            }
            if (!StringUtils.isEmpty(item.getItemBarcode())) {
                itemBarcodeList.add(item.getItemBarcode());
            }
        }
    }

}
