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

import com.alibaba.fastjson.JSON;
import com.github.dozermapper.core.Mapper;
import com.google.common.collect.Lists;
import com.zm.order.tool.server.component.ShardingKeyGenerator;
import com.zm.order.tool.server.constants.WuYinStoreMapConst;
import com.zm.order.tool.server.dao.*;
import com.zm.order.tool.server.manager.*;
import com.zm.order.tool.server.message.BatchSyncEsMessage;
import com.zm.order.tool.server.model.*;
import com.zm.order.tool.server.query.OrderQuery;
import com.zm.order.tool.server.service.ThirdOrderTransfer2Service;
import com.zm.order.tool.server.tempdb.*;
import com.zm.order.tool.server.utils.CommonUtils;
import com.zm.order.tool.server.utils.DateUtils;
import com.zm.util.dto.Result;
import org.apache.lucene.util.NamedThreadFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author nianchang
 * @ClassName ThirdOrderServiceImpl
 * @date 2021/11/08 10:56 上午
 */
@Service
@SuppressWarnings("all")
public class ThirdOrderTransferService2Impl implements ThirdOrderTransfer2Service, InitializingBean {

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

    @Autowired
    private ThirdApiMessage thirdApiMessage;

    @Autowired
    private ThirdOrderDao thirdOrderDao;

    @Autowired
    private ShardingKeyGenerator keyGenerator;
    @Autowired
    private OrderDao orderDao;
    @Autowired
    private OrderItemDao orderItemDao;
    @Autowired
    private OrderDiscountDao discountDao;
    @Autowired
    private OrderPayDetailsDao payDao;
    @Autowired
    private SearchManager searchManager;
    @Autowired
    private OrderIndexDao indexDao;
    @Autowired
    private SourceNoIndexDao sourceNoIndexDao;

    private BlockingQueue workQueue;

    private ExecutorService executorService;
    @Autowired
    private UserCustomerDao customerDao;

    @Autowired
    private Mapper mapper;
    @Autowired
    private OrderOperationDao operationDao;


    @Autowired
    private AsyncMessageManager messageManager;

    @Autowired
    private OrderItemBatchingDao batchingDao;

    @Autowired
    private OrderExtendsDao orderExtendsDao;

    @Autowired
    private ItemProductionDao itemProductionDao;

    @Autowired
    private OrderAddrDao addrDao;

    @Autowired
    private OrderBaoZhuDao zhuDao;

    @Autowired
    private OrderBaoZhuItemDao zhuItemDao;

    @Autowired
    private OrderBaoZhuPayDao zhuPayDao;

    @Autowired
    private OrderBaoZhuDiscountDao zhuDiscountDao;

    @Autowired
    private RefundDao refundDao;

    @Autowired
    private RedisManager redisManager;

    @Autowired
    private OrderPayDetailsDao payDetailsDao;

    @Autowired
    private OrderRefundDetailsDao detailsDao;

    @Autowired
    private RefundItemDao refundItemDao;

    @Autowired
    private OrderRefundDetailsDao refundDetailsDao;

    @Autowired
    private WuyinUserDao wuyinUserDao;

    @Autowired
    private CommonManager commonManager;

    @Value("${new.sharding.db.size}")
    private int dbSize;

    @Value("${new.sharding.tb.size}")
    private int tbSize;

    //迁出店铺名称：吾饮良品0001区域 店铺ID:217793 线上
    private Long oldSellerId = 217793L;
    //迁入店铺名称：吾饮良品总部 店铺ID:215923 线上
    private Long newSellerId = 215923L;

//    private Long oldSellerId = 11209L;
//    private Long newSellerId = 11476L;

    /**
     * 多线程配置
     */
    @Override
    public void afterPropertiesSet() {
        int coreSize = Runtime.getRuntime().availableProcessors();
        workQueue = new ArrayBlockingQueue(100);
        executorService = new ThreadPoolExecutor(9, 9, 1, TimeUnit.MINUTES,
                workQueue, new NamedThreadFactory("seller-change-transfer"),
                new ThreadPoolExecutor.AbortPolicy());
    }

    @Override
    public void wuyinChange() {
        try {
            int total = 0;
            int size = 200;
            OrderQuery query = new OrderQuery();
            query.setSellerId(oldSellerId);
            query.setSize(size);
            for (int i = 0; i < dbSize; i++) {
                for (int j = 0; j < tbSize; j++) {
                    Long lastId = null;
                    for (; ; ) {
                        query.setLastId(lastId);
                        List<Order> orderList = commonManager.selectWuyin(query, i, j);
                        if (CollectionUtils.isEmpty(orderList)) {
                            break;
                        }
                        while (workQueue.remainingCapacity() < 80) {
                            logger.info("wuYinOrderWorkQueue size:{}", workQueue.size());
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        int finalI = i;
                        int finalJ = j;
                        executorService.submit(() -> {
                            doWuyinChange(orderList, finalI, finalJ);
                        });

                        total += orderList.size();
                        lastId = orderList.get(orderList.size() - 1).getId();
                        logger.info("wuyinChange[running]lastId:{}, total:{}, i:{}, j:{}",
                                lastId, total, i, j);
                        if (orderList.size() < size) {
                            break;
                        }
                        Result<String> redisData = redisManager.get("wuyinChange_order_data_20240910");
                        if (redisData.isStatus() && Objects.nonNull(redisData.getData())) {
                            return;
                        }
                    }
                }
            }
            logger.info("wuyinChange[end], total:{}", total);
        } catch (Exception e) {
            logger.error("wuyinChange[error]!cause by:{}", e);
        }
    }

    @Autowired
    private ShardingAlgorithmManager shardManager;

    private Long mapNewStoreId(Long oldStoreId) {
        if (oldStoreId == 0L) {
            return oldStoreId;
        }
        if (!WuYinStoreMapConst.map.containsKey(oldStoreId)) {
            logger.info("wuyinChange[doWuyinChange][newStoreNull], oldStoreId:{}", oldStoreId);
            return oldStoreId;
        }
        return WuYinStoreMapConst.map.get(oldStoreId);
    }

    @Autowired
    private OrderCommentDao orderCommentDao;

    @Autowired
    private OrderItemCommentDao orderItemCommentDao;

    @Autowired
    private OrderCommentDetailsDao orderCommentDetailsDao;

    @Autowired
    private RecommendItemDao recommendItemDao;

    private static int newUserNullCount = 0;
    private static int newStoreNullCount = 0;
    private static int successCount = 0;
    private static int totalCount = 0;

    private void doWuyinChange(List<Order> orderList, int i, int j) {
        for (Order order : orderList) {
            Long oldUserId = order.getUserId();
            String orderNo = order.getOrderNo();
            totalCount++;
            try {
                logger.info("wuyinChange[doWuyinChange][start],totalCount:{}, orderNo:{}", totalCount, order.getOrderNo());
                Long newUserId;
                if (oldUserId <= 0L) {
                    newUserId = oldUserId;
                } else {
                    WuyinUser newUser = wuyinUserDao.selectOne(oldUserId);
                    // 新用户id为空，退出；
                    if (Objects.isNull(newUser) || Objects.isNull(newUser.getNewUserId())) {
                        newUserNullCount++;
                        logger.info("wuyinChange[doWuyinChange][newUserNull], oldUserId:{}, orderNo:{},newUserNullCount：{}",
                                oldUserId, orderNo, newUserNullCount);
                        continue;
                    }
                    newUserId = newUser.getNewUserId();
                }

                Long newStoreId = WuYinStoreMapConst.map.get(order.getStoreId());
                if (Objects.isNull(newStoreId)) {
                    newStoreNullCount++;
                    logger.info("wuyinChange[doWuyinChange][newStoreNullCount], oldStoreId:{}, orderNo:{},newStoreNullCount：{}",
                            order.getStoreId(), orderNo, newUserNullCount);
                    continue;
                }
                boolean compareIndex = shardManager.compareIndex(oldUserId, newUserId);
                //新老用户id 不在同一张表
                if (!compareIndex) {
                    // 先删除原记录后新增
                    orderDao.delete(order.getId(), oldUserId, -1);
                    buildOrder(order, newUserId, newStoreId);
                    orderDao.insert(order);

                    List<OrderItem> itemList = orderItemDao.selectByOrderNo(orderNo, oldUserId);
                    if (!CollectionUtils.isEmpty(itemList)) {
                        orderItemDao.deleteByOrderNo(oldUserId, orderNo);
                        buildOrderItem(itemList, newUserId, newStoreId);
                        orderItemDao.insertList(itemList);
                    }
                    List<OrderPayDetails> orderPayDetailsList = payDao.selectByOrderNo(orderNo, oldUserId);
                    if (!CollectionUtils.isEmpty(orderPayDetailsList)) {
                        payDao.deleteByOrderNo(orderNo, oldUserId);
                        buildOrderPay(orderPayDetailsList, newUserId, newStoreId);
                        payDao.insertList(orderPayDetailsList);
                    }
                    List<OrderDiscount> discountList = discountDao.selectByOrderNo(orderNo, oldUserId);
                    if (!CollectionUtils.isEmpty(discountList)) {
                        discountDao.deleteByOrderNo(orderNo, oldUserId);
                        buildOrderDiscount(discountList, newUserId, newStoreId);
                        discountDao.inserts(discountList);
                    }
                    OrderAddr orderAddr = addrDao.selectByOrderNo(orderNo, oldUserId);
                    if (Objects.nonNull(orderAddr)) {
                        addrDao.deleteByOrderNo(orderNo, oldUserId);
                        buildOrderAddr(orderAddr, newUserId, newStoreId);
                        addrDao.insert(orderAddr);
                    }
                    List<OrderItemBatching> batchingList = batchingDao.selectByOrderNo(orderNo, oldUserId);
                    if (!CollectionUtils.isEmpty(batchingList)) {
                        batchingDao.deleteByOrderNo(orderNo, oldUserId);
                        buildOrderItemBatching(batchingList, newUserId, newStoreId);
                        batchingDao.insertList(batchingList);
                    }
                    List<ItemProduction> itemProductions = itemProductionDao.selectByOrderNo(orderNo, oldUserId);
                    if (!CollectionUtils.isEmpty(itemProductions)) {
                        itemProductionDao.deleteByOrderNo(orderNo, oldUserId);
                        buildOrderItemPro(itemProductions, newUserId, newStoreId);
                        itemProductionDao.insertList(itemProductions);
                    }
                    OrderExtends orderExtends = orderExtendsDao.selectByOrderNo(orderNo, oldUserId);
                    if (Objects.nonNull(orderExtends)) {
                        orderExtendsDao.deleteByOrderNo(orderNo, oldUserId);
                        buildOrderExt(orderExtends, newUserId, newStoreId);
                        orderExtendsDao.insert(orderExtends);
                    }
                    logger.info("wuyinChange[doWuyinChange][compareIndex][noSame], oldUserId:{}, newUserId:{}, orderNo:{}", oldUserId, newUserId, orderNo);
                }
                //在同一张表 更新userId，保留主键
                if (compareIndex) {
                    Order update = new Order();
                    update.setId(order.getId());
                    update.setSellerId(newSellerId);
                    update.setUserId(order.getUserId());
                    update.setStoreId(newStoreId);
                    Map<String, Object> extraMap = order.getExtraMap();
                    extraMap.put("sellerChangeflag", 1);
                    extraMap.put("historySellerId", order.getSellerId());
                    extraMap.put("historyStoreId", order.getStoreId());
                    extraMap.put("historyUserId", order.getUserId());
                    update.setExtraMap(extraMap);
                    update.setNewUserId(newUserId);
                    update.setSellerRemarks("迁移订单");
                    orderDao.updateWuyinSeller(update);
                    orderItemDao.updateSellerUser(newSellerId, oldUserId, newUserId, orderNo);
                    payDao.updateSellerUser(newSellerId, newStoreId, oldUserId, newUserId, orderNo);
                    discountDao.updateSellerUser(newSellerId, oldUserId, newUserId, orderNo);
                    addrDao.updateSellerUser(newSellerId, oldUserId, newUserId, orderNo);
                    batchingDao.updateSellerUser(newSellerId, newStoreId, oldUserId, newUserId, orderNo);
                    itemProductionDao.updateSellerUser(newSellerId, newStoreId, oldUserId, newUserId, orderNo);
                    orderExtendsDao.updateSellerUser(oldUserId, newUserId, orderNo);
                    logger.info("wuyinChange[doWuyinChange][compareIndex][same], oldUserId:{}, newUserId:{}, orderNo:{}", oldUserId, newUserId, orderNo);
                }

                //sellerId 分表  先删除后新增
                // order_comment, order_comment_details  , order_item_comment ,
                // 无数据不处理 order_comment_likes,  order_relations , comment_recommend_items item_recommends  order_line_up_records
                List<OrderComment> orderCommentList = orderCommentDao.selectByOrderNo(orderNo, oldSellerId);
                if (!CollectionUtils.isEmpty(orderCommentList)) {
                    orderCommentDao.deleteByOrderNo(orderNo, oldSellerId);
                    buildItemList(orderCommentList, newUserId, newStoreId);
                    orderCommentDao.insertList(orderCommentList);
                }
                List<OrderCommentDetails> orderCommentDetails = orderCommentDetailsDao.selectByOrderNo(orderNo, oldSellerId);
                if (!CollectionUtils.isEmpty(orderCommentDetails)) {
                    orderCommentDetailsDao.deleteByOrderNo(orderNo, oldSellerId);
                    buildCommentDetailList(orderCommentDetails, newUserId, newStoreId);
                    orderCommentDetailsDao.insertList(orderCommentDetails);
                }
                List<OrderItemComment> itemCommentList = orderItemCommentDao.selectByOrderNoNew(orderNo, oldSellerId);
                if (!CollectionUtils.isEmpty(itemCommentList)) {
                    orderItemCommentDao.deleteByOrderNo(orderNo, oldSellerId);
                    buildItemCommentList(itemCommentList, newUserId, newStoreId);
                    orderItemCommentDao.replaceList(itemCommentList);
                }

                // 订单号分表 直接更新
                indexDao.updateSellerUser(oldUserId, newUserId, orderNo);
                sourceNoIndexDao.updateSellerUser(newSellerId, oldUserId, newUserId, order.getSourceNo());

                // 单表直接更新
                refundDao.updateSellerUser(newSellerId, newStoreId, oldUserId, newUserId, orderNo);
                refundItemDao.updateSellerUser(newSellerId, newStoreId, oldUserId, newUserId, orderNo);
                refundDetailsDao.updateSellerUser(newSellerId, newStoreId, oldUserId, newUserId, orderNo);

                Order newOrder = orderDao.selectById(order.getId(), newUserId);
                //同步ES
                searchManager.indexOrder(newOrder);
                syncRefund(orderNo, newUserId);
            // order_line_up_records_count 不处理
                successCount++;
                logger.info("wuyinChange[doWuyinChange][success], totalCount:{}, orderNo:{}, successCount：{}, TheadName:{}",
                        totalCount, orderNo, successCount, Thread.currentThread().getName());
            } catch (Throwable e) {
                logger.error("wuyinChange[error][doWuyinChange] failed!, orderNo:{}, cause by:{}", orderNo, e);
            }
        }

    }

    private void syncRefund(String orderNo, Long newUserId){
        try {
            List<Refund> refundList = refundDao.selectByOrderNo(orderNo);
            List<RefundIndex> l = new ArrayList<>();
            for (Refund refund : refundList) {
                RefundIndex index = mapper.map(refund, RefundIndex.class);
                index.setDocId(refund.getId());
                l.add(index);
            }
            searchManager.indexRefundMsg(l);
        } catch (Throwable e) {
            logger.error("wuyinChange[error][syncRefund] failed!, cause by:{}", e);
        }

    }

    private void buildOrder(Order order, Long newUserId, Long newStoreId) {
        order.setUserId(newUserId);
        order.setStoreId(newStoreId);
        order.setSellerId(newSellerId);
        order.setSellerRemarks("迁移订单");

        Map<String, Object> extraMap = order.getExtraMap();
        extraMap.put("sellerChangeflag", 1);
        extraMap.put("historySellerId", order.getSellerId());
        extraMap.put("historyStoreId", order.getStoreId());
        extraMap.put("historyUserId", order.getUserId());
        order.setExtraMap(extraMap);
    }

    private void buildOrderAddr(OrderAddr addr, Long newUserId, Long newStoreId) {
        addr.setId(keyGenerator.generateSnowflakeNumKey());
        addr.setUserId(newUserId);
        addr.setSellerId(newSellerId);
    }

    private void buildOrderExt(OrderExtends addr, Long newUserId, Long newStoreId) {
        addr.setId(keyGenerator.generateSnowflakeNumKey());
        addr.setUserId(newUserId);
    }

    private void buildOrderItem(List<OrderItem> itemList, Long newUserId, Long newStoreId) {
        for (OrderItem item : itemList) {
            item.setUserId(newUserId);
            item.setSellerId(newSellerId);
        }
    }

    private void buildOrderPay(List<OrderPayDetails> payList, Long newUserId, Long newStoreId) {
        for (OrderPayDetails item : payList) {
            item.setId(keyGenerator.generateSnowflakeNumKey());
            item.setUserId(newUserId);
            item.setSellerId(newSellerId);
            item.setStoreId(newStoreId);
        }
    }

    private void buildOrderDiscount(List<OrderDiscount> discountList, Long newUserId, Long newStoreId) {
        for (OrderDiscount item : discountList) {
            item.setId(keyGenerator.generateSnowflakeNumKey());
            item.setUserId(newUserId);
            item.setSellerId(newSellerId);
        }
    }

    private void buildOrderItemBatching(List<OrderItemBatching> discountList, Long newUserId, Long newStoreId) {
        for (OrderItemBatching item : discountList) {
            item.setId(keyGenerator.generateSnowflakeNumKey());
            item.setUserId(newUserId);
            item.setSellerId(newSellerId);
            item.setStoreId(newStoreId);
        }
    }

    private void buildOrderItemPro(List<ItemProduction> discountList, Long newUserId, Long newStoreId) {
        for (ItemProduction item : discountList) {
            item.setId(keyGenerator.generateSnowflakeNumKey());
            item.setUserId(newUserId);
            item.setSellerId(newSellerId);
            item.setStoreId(newStoreId);
        }
    }

    private void buildItemList(List<OrderComment> orderCommentList, Long newUserId, Long newStoreId) {
        for (OrderComment orderComment : orderCommentList) {
            orderComment.setId(keyGenerator.generateSnowflakeNumKey());
            orderComment.setUserId(newUserId);
            orderComment.setStoreId(newStoreId);
            orderComment.setSellerId(newSellerId);
        }
    }

    private void buildCommentDetailList(List<OrderCommentDetails> orderCommentDetailsList, Long newUserId, Long newStoreId) {
        for (OrderCommentDetails orderCommentDetails : orderCommentDetailsList) {
            orderCommentDetails.setId(keyGenerator.generateSnowflakeNumKey());
            orderCommentDetails.setUserId(newUserId);
            orderCommentDetails.setStoreId(newStoreId);
            orderCommentDetails.setSellerId(newSellerId);
        }
    }

    private void buildItemCommentList(List<OrderItemComment> itemCommentList, Long newUserId, Long newStoreId) {
        for (OrderItemComment itemComment : itemCommentList) {
            itemComment.setId(keyGenerator.generateSnowflakeNumKey());
            itemComment.setUserId(newUserId);
            itemComment.setStoreId(newStoreId);
            itemComment.setSellerId(newSellerId);
        }
    }

    //pro
    //private Long baozhuSellerId = 215923L;

    //beta
    private Long baozhuSellerId = 11488L;

    @Override
    public void baozhuOrder() {
        try {
            logger.info("baozhuOrder[start]");
            Long lastId = 0L;
            int count = 0;
            int size = 200;
            for (; ; ) {
                List<OrderBaoZhu> list = zhuDao.selectOrderList(lastId, size);
                if (CollectionUtils.isEmpty(list)) {
                    break;
                }
                Result<String> redisData = redisManager.get("stop-baozhu-Order");
                if (redisData.isStatus() && Objects.nonNull(redisData.getData())) {
                    return;
                }
                while (workQueue.remainingCapacity() < 80) {
                    logger.info("baozhuOrderWorkQueue size:{}", workQueue.size());
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                executorService.submit(() -> {
                    doTransfer(list);
                });

                lastId = list.get(list.size() - 1).getId();
                count = count + list.size();
                logger.info("baozhuOrder[running], count:{},lastId:{}", count, lastId);
                if (list.size() < size) {
                    break;
                }
            }
            logger.info("baozhuOrder[end], count:{},lastId:{}", count, lastId);

        } catch (Throwable e) {
            logger.error("baozhuOrder[execute] failed!, cause by:{}", e);
        }
    }

    @Override
    public void delBaozhuOrder() {
        try {
            Long lastId = 0L;
            int size = 200;
            int count = 0;
            int orderCount = 0;
            for (; ; ) {
                List<OrderBaoZhu> list = zhuDao.selectList(lastId, size);
                if (CollectionUtils.isEmpty(list)) {
                    break;
                }
                while (workQueue.remainingCapacity() < 50) {
                    logger.info("delbaozhuOrderWorkQueue size:{}", workQueue.size());
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                executorService.submit(() -> {
                    doDel(list);
                });
                lastId = list.get(list.size() - 1).getId();
                count = count + list.size();
                logger.info("delbaozhuOrder,count:{},lastId:{}, orderCount:{}", count, lastId, orderCount);
                if (list.size() < size) {
                    break;
                }
            }
        } catch (Throwable e) {
            logger.error("TempOrderServiceImplSync[delbaozhuOrder] failed!, cause by:{}", e);
        }
    }

    private BatchSyncEsMessage buildMessage(Order order) {
        BatchSyncEsMessage message = new BatchSyncEsMessage();
        message.setUserId(order.getUserId());
        message.setId(order.getId());
        return message;
    }


    private void buildZhuPayDetail(OrderBaoZhu thirdOrder, Order order, List<OrderPayDetails> payList) {
        if (order.getPayStatus() == 0) {
            return;
        }
        List<InnerOrderPayDetails> innerPayList = new ArrayList<>();

        List<OrderBaoZhuPay> orderBaoZhuPays = zhuPayDao.selectByOrderNo(order.getOrderNo(), thirdOrder.getPayStatusTxt());
        if (CollectionUtils.isEmpty(orderBaoZhuPays)) {
            OrderPayDetails orderPayDetails = buildPayDetail(thirdOrder, order);
            innerPayList.add(mapper.map(orderPayDetails, InnerOrderPayDetails.class));
            payList.add(orderPayDetails);
        } else {
            for (OrderBaoZhuPay pay : orderBaoZhuPays) {
                OrderPayDetails orderPayDetails = buildPayDetail(thirdOrder, order);
                orderPayDetails.setPayAt(pay.getPayAt());
                orderPayDetails.setThirdPayNo(pay.getShopNo());
                orderPayDetails.setPayNo(pay.getPayNo());
                if (Objects.nonNull(pay.getAmount())) {
                    BigDecimal multiply = pay.getAmount().multiply(new BigDecimal(100));
                    int payAmount = Double.valueOf(multiply.toString()).intValue();
                    orderPayDetails.setAmount(payAmount);
                }
                buildPayType(pay, orderPayDetails, order);
                payList.add(orderPayDetails);
                innerPayList.add(mapper.map(orderPayDetails, InnerOrderPayDetails.class));
            }
        }
        order.setPayDetailInfo(JSON.toJSONString(innerPayList));
    }

    private void buildPayType(OrderBaoZhuPay pay, OrderPayDetails orderPayDetails, Order order) {
        orderPayDetails.setPayType(64);
        order.setPayType(64);
        if (Objects.nonNull(pay.getPayType())) {
            if (pay.getPayType().equals("微信")) {
                orderPayDetails.setPayType(1);
                order.setPayType(1);
            }
            if (pay.getPayType().equals("支付宝")) {
                orderPayDetails.setPayType(2);
                order.setPayType(2);
            }
            if (pay.getPayType().equals("现金")) {
                orderPayDetails.setPayType(12);
                order.setPayType(12);
            }
            if (pay.getPayType().equals("储值卡")) {
                orderPayDetails.setPayType(4);
                order.setPayType(4);
            }
            if (pay.getPayType().equals("寶珠小程序外卖")) {
                orderPayDetails.setPayType(7);
                order.setPayType(7);
            }
            if (pay.getPayType().equals("美团团购券")) {
                orderPayDetails.setPayType(25);
                order.setPayType(2);
            }
            if (pay.getPayType().equals("美团外卖")) {
                orderPayDetails.setPayType(25);
                order.setPayType(25);
            }
            if (pay.getPayType().equals("云闪付(自)")) {
                orderPayDetails.setPayType(15);
                order.setPayType(15);
            }
            if (pay.getPayType().equals("银联云闪付")) {
                orderPayDetails.setPayType(15);
                order.setPayType(15);
            }
//            if(pay.getPayType().equals("饿了么")){
//                orderPayDetails.setPayType(1);
//                order.setPayType(1);
//            }
        }
    }


    private OrderPayDetails buildPayDetail(OrderBaoZhu thirdOrder, Order order) {
        OrderPayDetails payDetails = new OrderPayDetails();
        payDetails.setId(keyGenerator.generateSnowflakeNumKey());
        payDetails.setOrderNo(order.getOrderNo());
        payDetails.setUserId(order.getUserId());
        payDetails.setAmount(order.getPayAmount());
        payDetails.setPayType(order.getPayType());
        payDetails.setStoreId(order.getStoreId());
        payDetails.setSellerId(order.getSellerId());
        payDetails.setOrderAt(order.getOrderAt());
        payDetails.setPayAt(order.getOrderAt());
        payDetails.setOrderType(order.getOrderType());
        payDetails.setSource(order.getSource());
        payDetails.setBizType(order.getBizType());
        payDetails.setPerformanceType(order.getPerformanceType());
        payDetails.setPayNo("");
        payDetails.setThirdPayNo("");
        Map<String, Object> map = new HashMap();
        map.put("historyOrder", 1);
        payDetails.setExtraMap(map);
//        String payDetailInfo = JSON.toJSONString(Arrays.asList(mapper.map(payDetails, InnerOrderPayDetails.class)));
//        order.setPayDetailInfo(payDetailInfo);
        return payDetails;
    }

    private OrderIndex buildOrderIndex(Order order) {
        OrderIndex index = new OrderIndex();
        index.setId(keyGenerator.generateSnowflakeNumKey());
        index.setOrderNo(order.getOrderNo());
        index.setUserId(order.getUserId());
        index.setBizType(5);
        index.setOrderId(order.getId());
        return index;
    }

    private Order buildOrder(OrderBaoZhu item) {
        Long userId = 0L;
        Order order = new Order();
        order.setId(keyGenerator.generateSnowflakeNumKey());
        order.setOrderNo(item.getOrderNo());
        order.setUserId(userId);
        order.setDiscountAmount(0);
        order.setActualAmount(0);
        order.setPayAmount(0);
        order.setItemAmount(0);
        order.setPayStatus(1);
        order.setStatus(70);
        order.setSource(0);
        order.setBizSubType(0);
        order.setPackAmount(0);
        order.setChangeAmount(0);
        order.setPayModel(0);
        order.setIsAlone(0);
        order.setInvoiceType(0);
        order.setAfterSaleStatus(0);
        order.setReceiveStatus(0);
        order.setPerformanceStatus(0);
        order.setCommentStatus(0);
        order.setPerformanceType(0);
        order.setIsReceipt(0);
        order.setIsImmediatePerformance(0);
        order.setSourceNo("");
        order.setBizType(5);
        order.setFromSystem(0);
        order.setOrderSubType(0);
        order.setIsDeleted(0);
        order.setAddrId(0);
        order.setAddrInfo("");
        order.setSyncFlag(0);
        order.setVersion(1);
        order.setPayFlag(1);
        order.setPayer(userId);
        order.setMobile("");
        order.setSellerId(baozhuSellerId);
        order.setStoreId(0L);
        order.setOrderAt(item.getOrderAt());
        order.setCreatedAt(item.getOrderAt());
        order.setPayAt(item.getOrderAt());
        order.setCompletedAt(item.getOrderAt());
        order.setPayType(0);
        order.setOrderType(1);
        order.setRefundFlag(0);
        order.setUpdatedAt(new Date());
        order.setFreightAmount(0);
        Map<String, Object> map = new HashMap();
        map.put("historyOrder", 1);
        Map<String, Object> userInfoMap = new HashMap();
        userInfoMap.put("phone", "");
        userInfoMap.put("openId", "");
        userInfoMap.put("userName", "");
        userInfoMap.put("userId", userId);
        map.put("userInfo", userInfoMap);
        order.setExtraMap(map);

        Map<String, Object> payInfoMap = new HashMap();
        payInfoMap.put("amount", order.getPayAmount() / 100);
        payInfoMap.put("useWallet", 0);
        payInfoMap.put("walletAmount", 0);
        payInfoMap.put("payDetailsList", Lists.newArrayList("在线支付: ¥" + order.getPayAmount() / 100));
        order.setPayInfo(JSON.toJSONString(payInfoMap));
        convert(order, item);
        //订单总金额
        if (Objects.nonNull(item.getTotalAmount())) {
            BigDecimal multiply = item.getTotalAmount().multiply(new BigDecimal(100));
            int intTotalAmount = Double.valueOf(multiply.toString()).intValue();
            order.setTotalAmount(intTotalAmount);
            order.setItemAmount(intTotalAmount);
        }
        //商户优惠金额、平台优惠
        int intShopDiscountAmount = 0;
        int intPlatformDiscountAmount = 0;
        if (Objects.nonNull(item.getShopDiscountAmount())) {
            BigDecimal multiply = item.getShopDiscountAmount().multiply(new BigDecimal(100));
            intShopDiscountAmount = Double.valueOf(multiply.toString()).intValue();
        }
        if (Objects.nonNull(item.getPlatformDiscountAmount())) {
            BigDecimal multiply = item.getPlatformDiscountAmount().multiply(new BigDecimal(100));
            intShopDiscountAmount = Double.valueOf(multiply.toString()).intValue();
        }
        order.setDiscountAmount(intShopDiscountAmount + intShopDiscountAmount);

        //订单实付金额
        if (Objects.nonNull(item.getPayAmount())) {
            BigDecimal multiply = item.getPayAmount().multiply(new BigDecimal(100));
            int intPayAmount = Double.valueOf(multiply.toString()).intValue();
            order.setPayAmount(intPayAmount);
            order.setActualAmount(intPayAmount);
        }
//        if (item.getPayType() == 4) {
//            Map<String, Object> payInfoMap = Maps.newHashMap();
//            payInfoMap.put("useWallet", 1);
//            payInfoMap.put("walletAmount", item.getPayAmount());
//            payInfoMap.put("payDetailsList", Arrays.asList("余额支付: ¥" + item.getPayAmount()));
//            order.setPayInfo(JSON.toJSONString(payInfoMap));
//        }
        return order;
    }

    private void convert(Order order, OrderBaoZhu item) {
        order.setRefundFlag(0);
        if (Objects.nonNull(item.getStatusTxt())) {
            if (item.getStatusTxt().equals("已作废")) {
                order.setStatus(60);
            }
            if (item.getStatusTxt().equals("已完成")) {
                order.setStatus(50);
            }
            if (item.getStatusTxt().equals("已确认")) {
                order.setStatus(50);
            }
            if (item.getStatusTxt().equals("已退货")) {
                order.setStatus(70);
                order.setRefundFlag(1);
            }
            if (item.getStatusTxt().equals("部分退")) {
                order.setStatus(70);
                order.setRefundFlag(1);
            }
        }
        if (Objects.nonNull(item.getPayStatusTxt())) {
            if (item.getPayStatusTxt().equals("已支付")) {
                order.setPayStatus(1);
            }
            if (item.getPayStatusTxt().equals("已退款")) {
                order.setPayStatus(1);
            }
            if (item.getPayStatusTxt().equals("未支付")) {
                order.setPayStatus(0);
            }
        }
        if (Objects.nonNull(item.getSourceTxt())) {
            if (item.getSourceTxt().equals("Android收银终端")) {
                order.setSource(8);
            }
            if (item.getSourceTxt().equals("ONMOBILE")) {
                order.setSource(8);
            }
            if (item.getSourceTxt().equals("寶珠小程序外卖")) {
                order.setSource(1);
            }
            if (item.getSourceTxt().equals("异步订单")) {
                order.setSource(18);
            }
            if (item.getSourceTxt().equals("美团外卖")) {
                order.setSource(4);
            }
            if (item.getSourceTxt().equals("饿了么")) {
                order.setSource(5);
            }
        }
        if (Objects.nonNull(item.getOrderTypeTxt())) {
            if (item.getOrderTypeTxt().equals("内用")) {
                order.setOrderType(1);
            }
            if (item.getOrderTypeTxt().equals("外带")) {
                order.setOrderType(2);
            }
            if (item.getOrderTypeTxt().equals("外送")) {
                order.setOrderType(3);
            }
            if (item.getOrderTypeTxt().equals("自提")) {
                order.setOrderType(2);
            }
        }

    }

    private void buildBaoZhuItem(OrderBaoZhu thirdOrder, Order order, List<OrderItem> itemList) {
        List<OrderBaoZhuItem> orderBaoItems = zhuItemDao.selectByOrderNo(order.getOrderNo(), thirdOrder.getPayStatusTxt());
        List<InnerOrderItem> innerOrderItemList = new ArrayList<>();
        if (CollectionUtils.isEmpty(orderBaoItems)) {
            OrderItem orderItem = buildItem(thirdOrder, order);
            innerOrderItemList.add(mapper.map(orderItem, InnerOrderItem.class));
            itemList.add(orderItem);
        } else {
            Map<String, Object> extraMap = order.getExtraMap();

            for (OrderBaoZhuItem item : orderBaoItems) {
                OrderItem orderItem = buildItem(thirdOrder, order);
                orderItem.setItemName(item.getItemName());
                orderItem.setItemSign(item.getItemSign());
                orderItem.setNum(new BigDecimal(item.getNum()));
                orderItem.setItemUnit(item.getUnit());
                //
                int intTotalAmount = 0;
                if (Objects.nonNull(item.getTotalAmount())) {
                    BigDecimal multiply = item.getTotalAmount().multiply(new BigDecimal(100));
                    intTotalAmount = Double.valueOf(multiply.toString()).intValue();
                    orderItem.setItemPrice(intTotalAmount / item.getNum());
                    orderItem.setMarketPrice(orderItem.getItemPrice());
                }
                Map<String, Object> itemExtraMap = orderItem.getExtraMap();
                itemExtraMap.put("itemTypeTxt", item.getItemTypeTxt());

                if (Objects.nonNull(item.getCate())) {
                    Map<String, Object> cateMap = new HashMap<>();
                    cateMap.put("id", "");
                    cateMap.put("code", "");
                    cateMap.put("name", item.getCate());
                    itemExtraMap.put("goodsCate", Arrays.asList(cateMap));
                }

                itemExtraMap.put("itemPrice", item.getItemPrice());
                itemExtraMap.put("methodPrice", item.getMethodPrice());
                itemExtraMap.put("itemSpec", item.getSpec());
                itemExtraMap.put("itemMethod", item.getMethod());
                orderItem.setExtraMap(itemExtraMap);

                innerOrderItemList.add(mapper.map(orderItem, InnerOrderItem.class));
                itemList.add(orderItem);
                extraMap.put("storeName", item.getStoreName());
                order.setExtraMap(extraMap);
            }
        }
        order.setItemInfo(JSON.toJSONString(innerOrderItemList));
    }


    private OrderItem buildItem(OrderBaoZhu thirdOrder, Order order) {
        OrderItem item = new OrderItem();
        item.setId(keyGenerator.generateSnowflakeNumKey());
        item.setBizType(5);
        item.setUserId(order.getUserId());
        item.setOrderNo(order.getOrderNo());
        item.setItemId("-1");
        item.setGoodsId(0L);
        item.setItemImage("https://images.qmai.cn/s11478/2023/04/06/f05e6b031b4c42c6dc.jpg");
        item.setItemName("历史迁移商品");
        item.setItemSign("");
        item.setDiscountAmount(0);
        item.setNum(new BigDecimal(1));
        item.setItemSpec(null);
        item.setItemUnit("");
        item.setBrandSign("");
        item.setMarketPrice(0);
        item.setCostPrice(0);
        item.setMemberPrice(0);
        item.setPackAmount(0);
        item.setfCode("");
        item.setStatus(0);
        item.setActivityId(0L);
        item.setIsTimeDiscount(0);
        item.setOrderAt(order.getOrderAt());
        item.setProductNo("");
        item.setIsGift(0);
        item.setSellerId(order.getSellerId());
        item.setItemType(0);
        item.setOwnerId(0L);
        item.setBatchingInfo("");
        Map<String, Object> map = new HashMap();
        map.put("historyOrder", 1);
        item.setExtraMap(map);
        //商品实付金额
        item.setItemPrice(order.getItemAmount());
        //市场价
        item.setMarketPrice(order.getItemAmount());
        item.setDiscountAmount(order.getDiscountAmount());
//        InnerOrderItem inner = mapper.map(item, InnerOrderItem.class);
//        List<InnerOrderItem> innerOrderItems = Arrays.asList(inner);
//        order.setItemInfo(JSON.toJSONString(innerOrderItems));
        return item;
    }

    private void buildPushMessage(List<BatchSyncEsMessage> messageList, List<BatchSyncEsMessage> pushList) {
        if (!CollectionUtils.isEmpty(messageList)) {
            for (BatchSyncEsMessage message : messageList) {
                pushList.add(message);
            }
        }
    }

    private static int orderNum = 0;

    private void doTransfer(List<OrderBaoZhu> list) {
        try {
            int size = 200;
            List<Order> orderList = new ArrayList<>(size);
            List<OrderItem> itemList = new ArrayList<>(size);
            List<OrderPayDetails> payList = new ArrayList<>(size);
            List<OrderIndex> indexList = new ArrayList<>(size);
            List<OrderDiscount> discountList = new ArrayList<>(size);
            List<BatchSyncEsMessage> messageList = new ArrayList<>(size);

            for (OrderBaoZhu item : list) {
                Order order = buildOrder(item);
                buildBaoZhuItem(item, order, itemList);
                buildZhuPayDetail(item, order, payList);
                OrderIndex orderIndex = buildOrderIndex(order);
                buildZhuDiscount(item, order, discountList);
                messageList.add(buildMessage(order));

                orderList.add(order);
                indexList.add(orderIndex);
                messageList.add(buildMessage(order));
            }

            //新增订单
            if (!CollectionUtils.isEmpty(orderList)) {
                orderDao.insertList(orderList);
            }
            // 新增订单索引
            if (!CollectionUtils.isEmpty(indexList)) {
                indexDao.insertList(indexList);
            }
            //批量新增商品
            if (!CollectionUtils.isEmpty(itemList)) {
                orderItemDao.inserts(itemList);
            }
            //批量新增支付明细
            if (!CollectionUtils.isEmpty(payList)) {
                payDao.insertList(payList);
            }
            //批量新增订单优惠
            if (!CollectionUtils.isEmpty(discountList)) {
                discountDao.inserts(discountList);
            }
            searchManager.indexOrder(orderList);
//            List<BatchSyncEsMessage> pushList = new ArrayList<>(size);
//            buildPushMessage(messageList, pushList);
//            messageManager.sendBatchSyncMessage(pushList);
            orderNum += orderList.size();
            logger.info("baozhuOrder[doTransfer], ThreadName:{},lastId:{}, count:{}", Thread.currentThread().getName(),
                    list.get(list.size() - 1).getId(),
                    orderNum);
        } catch (Throwable e) {
            logger.error("baozhuOrder[doTransferError] failed!, cause by:{}", e);
        }
    }


    private void buildZhuDiscount(OrderBaoZhu thirdOrder, Order order, List<OrderDiscount> discountList) {
        if (order.getDiscountAmount() == 0) {
            return;
        }
        if (Objects.isNull(order.getDiscountAmount())) {
            return;
        }
        List<InnerOrderDiscount> innerDiscountList = new ArrayList<>();

        List<OrderBaoZhuDiscount> orderBaoZhuDiscounts = zhuDiscountDao.selectByOrderNo(order.getOrderNo());
        if (CollectionUtils.isEmpty(orderBaoZhuDiscounts)) {
            OrderDiscount orderDiscount = buildDiscount(thirdOrder, order);
            innerDiscountList.add(mapper.map(orderDiscount, InnerOrderDiscount.class));
            discountList.add(orderDiscount);
        } else {
            for (OrderBaoZhuDiscount discount : orderBaoZhuDiscounts) {
                OrderDiscount orderDiscount = buildDiscount(thirdOrder, order);
                orderDiscount.setDiscountName(discount.getDiscountName());
                orderDiscount.setDiscountSummary(discount.getDiscountDetail());
                if (Objects.nonNull(discount.getAmount())) {
                    BigDecimal multiply = discount.getAmount().multiply(new BigDecimal(100));
                    int amount = Double.valueOf(multiply.toString()).intValue();
                    orderDiscount.setDiscountAmount(amount);
                }
                discountList.add(orderDiscount);
                innerDiscountList.add(mapper.map(orderDiscount, InnerOrderDiscount.class));
            }
        }
        order.setDiscountInfo(JSON.toJSONString(innerDiscountList));
    }

    private OrderDiscount buildDiscount(OrderBaoZhu thirdOrder, Order order) {
        OrderDiscount discount = new OrderDiscount();
        discount.setId(keyGenerator.generateSnowflakeNumKey());
        discount.setBizType(5);
        discount.setUserId(order.getUserId());
        discount.setOrderNo(order.getOrderNo());
        discount.setSellerId(order.getSellerId());
        discount.setStatus(0);
        discount.setItemId("-1");
        discount.setDiscountLevel(0);
        discount.setDiscountId("-1");
        discount.setDiscountType(2);
        discount.setDiscountName("优惠券");
        discount.setDiscountSummary("优惠券");
        Map<String, Object> map = new HashMap();
        map.put("historyOrder", 1);
        discount.setExtraMap(map);
        discount.setDiscountAmount(order.getDiscountAmount());
        return discount;
    }


    private void doDel(List<OrderBaoZhu> list) {
        List<String> orderNoList = list.stream().map(OrderBaoZhu::getOrderNo).collect(Collectors.toList());
        List<Long> userIdList = Arrays.asList(0L);
        OrderQuery query = new OrderQuery();
        query.setUserIdList(userIdList);
        query.setOrderNoList(orderNoList);
        List<Order> orderList = orderDao.selectListByOrderNosUserIds(query);
        if (!CollectionUtils.isEmpty(orderList)) {
            for (Order order : orderList) {
                searchManager.deleteOrder(order.getId(), order.getSellerId());
            }
        }
        orderDao.deleteByOrderNos(orderNoList, userIdList);
        orderItemDao.deleteByOrderNos(orderNoList, userIdList);
        payDao.deleteByOrderNos(orderNoList, userIdList);
        discountDao.deleteByOrderNos(orderNoList, userIdList);
        indexDao.realDeleteByOrderNoUserId(orderNoList, userIdList);
        discountDao.deleteByOrderNos(orderNoList, userIdList);

        refundDao.deleteByOrderNos(orderNoList);
        refundItemDao.deleteByOrderNos(orderNoList);
        detailsDao.deleteByOrderNos(orderNoList);
        logger.info("baozhuOrderDel[doDel], ThreadName:{},lastId:{}", Thread.currentThread().getName(), list.get(list.size() - 1).getId());
    }

    private void doDelGuTou(List<OrderGuTou> list) {
        List<String> orderNoList = list.stream().map(OrderGuTou::getOrderNo).collect(Collectors.toList());
        List<Long> userIdList = Arrays.asList(0L);
        OrderQuery query = new OrderQuery();
        query.setUserIdList(userIdList);
        query.setOrderNoList(orderNoList);
        List<Order> orderList = orderDao.selectListByOrderNosUserIds(query);
        if (!CollectionUtils.isEmpty(orderList)) {
            for (Order order : orderList) {
                searchManager.deleteOrder(order.getId(), order.getSellerId());
            }
        }
        orderDao.deleteByOrderNos(orderNoList, userIdList);
        orderItemDao.deleteByOrderNos(orderNoList, userIdList);
        payDao.deleteByOrderNos(orderNoList, userIdList);
        discountDao.deleteByOrderNos(orderNoList, userIdList);
        indexDao.realDeleteByOrderNoUserId(orderNoList, userIdList);
        discountDao.deleteByOrderNos(orderNoList, userIdList);

        refundDao.deleteByOrderNos(orderNoList);
        refundItemDao.deleteByOrderNos(orderNoList);
        detailsDao.deleteByOrderNos(orderNoList);
        logger.info("baozhuOrderDel[doDel], ThreadName:{},lastId:{}", Thread.currentThread().getName(), list.get(list.size() - 1).getId());
    }


    @Override
    public void baozhuRefund() {
        try {
            logger.info("baozhuRefund[start]");
            Long lastId = 0L;
            int count = 0;
            int size = 200;
            for (; ; ) {
                List<OrderBaoZhu> list = zhuDao.selectRefundList(lastId, size);
                if (CollectionUtils.isEmpty(list)) {
                    break;
                }
                while (workQueue.remainingCapacity() < 80) {
                    logger.info("baozhuOrderWorkQueue size:{}", workQueue.size());
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                executorService.submit(() -> {
                    doTransferRefund(list);
                });

                lastId = list.get(list.size() - 1).getId();
                count = count + list.size();
                logger.info("baozhuRefund[running], count:{},lastId:{}", count, lastId);
                if (list.size() < size) {
                    break;
                }
            }
            logger.info("baozhuRefund[end], count:{},lastId:{}", count, lastId);

        } catch (Throwable e) {
            logger.error("baozhuRefund[execute] failed!, cause by:{}", e);
        }
    }

    private static int refundNums = 0;

    private void doTransferRefund(List<OrderBaoZhu> list) {
        try {
            int size = 200;
            List<Refund> refundList = new ArrayList<>(size);
            List<RefundItem> itemList = new ArrayList<>(size);
            List<OrderRefundDetails> detailsList = new ArrayList<>(size);

            List<String> orderNoList = list.stream().map(OrderBaoZhu::getOrderNo).collect(Collectors.toList());
            OrderQuery orderQuery = new OrderQuery();
            orderQuery.setUserIdList(Arrays.asList(0L));
            orderQuery.setOrderNoList(orderNoList);
            List<Order> orderList = orderDao.selectListByOrderNosUserIds(orderQuery);
            Map<String, Order> orderNoMap = orderList.stream().collect(Collectors.toMap(Order::getOrderNo, Function.identity()));
            for (OrderBaoZhu baoZhu : list) {
                //订单不存在, 退款单不迁移
                if (!orderNoMap.containsKey(baoZhu.getOrderNo())) {
                    logger.info("baozhuRefund[doTransferRefund-orderNoExist], id:{},orderNo:{}", baoZhu.getId(), baoZhu.getOrderNo());
                    continue;
                }
                Order order = orderNoMap.get(baoZhu.getOrderNo());
                Refund refund = buildRefund(baoZhu, order, refundList);
                buildRefundItem(baoZhu, order, itemList, refund);
                buildRefundPay(baoZhu, order, detailsList, refund);
                refundList.add(refund);
            }
            // 新增退款单
            if (!CollectionUtils.isEmpty(refundList)) {
                refundDao.insertList(refundList);
            }
            // 新增退款商品
            if (!CollectionUtils.isEmpty(itemList)) {
                refundItemDao.inserts(itemList);
            }
            // 新增退款支付
            if (!CollectionUtils.isEmpty(detailsList)) {
                detailsDao.insertList(detailsList);
            }
            refundNums = refundNums + refundList.size();
            logger.info("baozhuRefund[doTransfer], ThreadName:{},lastId:{}, count:{}", Thread.currentThread().getName(),
                    list.get(list.size() - 1).getId(),
                    refundNums);
        } catch (Throwable e) {
            logger.error("baozhuRefund[doTransferError] failed!, cause by:{}", e);
        }
    }


    private Refund buildRefund(OrderBaoZhu baoZhu, Order order, List<Refund> refundList) {
        Refund refund = new Refund();
        refund.setId(keyGenerator.generateSnowflakeNumKey());
        refund.setSource(order.getSource());
        refund.setSellerId(order.getSellerId());
        //生产退款单
        refund.setRefundNo(CommonUtils.uniqueOrderNo("HR"));
        refund.setOrderNo(order.getOrderNo());
        refund.setUserId(order.getUserId());
        refund.setBizType(5);
        refund.setOrderType(order.getOrderType());
        refund.setOrderSubType(0);
        refund.setRefundLevel(2);
        refund.setStoreId(order.getStoreId());
        refund.setMobile(order.getMobile());

        Integer payAmount = 0;
        if (Objects.nonNull(baoZhu.getPayAmount())) {
            BigDecimal multiply = baoZhu.getPayAmount().multiply(new BigDecimal(100));
            payAmount = Double.valueOf(multiply.toString()).intValue();
        }
        refund.setRefundAmount(payAmount);
        refund.setAmount(payAmount);
        refund.setWalletAmount(0);
        refund.setApplicant(order.getUserId());
        refund.setApplyAt(baoZhu.getOrderAt());
        refund.setOrderAt(baoZhu.getOrderAt());
        refund.setCreatedAt(baoZhu.getOrderAt());
        refund.setDealAt(baoZhu.getOrderAt());
        refund.setStatus(30);
        Map<String, Object> map = new HashMap();
        map.put("historyOrder", 1);
        refund.setExtraMap(map);
        refund.setIsAlone(0);
        refund.setRefundType(0);
        refund.setRefundWay(2);
        refund.setVersion(0);
        refund.setIsDeleted(0);
        refund.setIsDeleted(0);
        refund.setFromSystem(1);
        refund.setPayType(order.getPayType());
        refund.setReviewStatus(0);
        refund.setGiftCardAmount(0);
        refund.setPerformanceType(0);
        return refund;
    }

    private void buildRefundItem(OrderBaoZhu baoZhu, Order order, List<RefundItem> refundItemList, Refund refund) {
        List<OrderBaoZhuItem> zhuItems = zhuItemDao.selectByOrderNo(order.getOrderNo(), baoZhu.getPayStatusTxt());
        if (CollectionUtils.isEmpty(zhuItems)) {
            RefundItem refundItem = buildRefundItemValue(baoZhu, order, refund);
            refundItemList.add(refundItem);
        } else {
            for (OrderBaoZhuItem zhuItem : zhuItems) {
                RefundItem refundItem = buildRefundItemValue(baoZhu, order, refund);
                refundItem.setItemName(zhuItem.getItemName());
                if (Objects.nonNull(zhuItem.getItemAmount())) {
                    BigDecimal multiply = zhuItem.getItemAmount().multiply(new BigDecimal(100));
                    int itemPrice = Double.valueOf(multiply.toString()).intValue();
                    refundItem.setRefundAmount(itemPrice);
                }
                if (Objects.nonNull(zhuItem.getItemPrice())) {
                    BigDecimal multiply = zhuItem.getItemPrice().multiply(new BigDecimal(100));
                    int price = Double.valueOf(multiply.toString()).intValue();
                    refundItem.setItemPrice(price);
                }
                refundItemList.add(refundItem);
            }
        }

    }

    private void buildRefundPay(OrderBaoZhu baoZhu, Order order, List<OrderRefundDetails> refundList, Refund refund) {
        List<OrderBaoZhuPay> zhuItems = zhuPayDao.selectByOrderNo(order.getOrderNo(), baoZhu.getPayStatusTxt());
        List<InnerOrderRefundDetail> details = new ArrayList<>();

        if (CollectionUtils.isEmpty(zhuItems)) {
            OrderRefundDetails refundItem = buildRefundDetail(baoZhu, order, refund);
            refundList.add(refundItem);
            details.add(mapper.map(refundItem, InnerOrderRefundDetail.class));
        } else {
            for (OrderBaoZhuPay zhuItem : zhuItems) {
                OrderRefundDetails refundItem = buildRefundDetail(baoZhu, order, refund);
                refundItem.setCreatedAt(zhuItem.getPayAt());
                if (Objects.nonNull(zhuItem.getAmount())) {
                    BigDecimal multiply = zhuItem.getAmount().multiply(new BigDecimal(100));
                    int itemPrice = Double.valueOf(multiply.toString()).intValue();
                    refundItem.setRefundAmount(itemPrice);
                }
                refundList.add(refundItem);
                details.add(mapper.map(refundItem, InnerOrderRefundDetail.class));
            }
        }
        refund.setRefundDetailInfo(JSON.toJSONString(details));

    }

    private OrderRefundDetails buildRefundDetail(OrderBaoZhu baoZhu, Order order, Refund refund) {
        OrderRefundDetails payDetails = new OrderRefundDetails();
        payDetails.setId(keyGenerator.generateSnowflakeNumKey());
        payDetails.setRefundNo(refund.getRefundNo());
        payDetails.setOrderNo(refund.getOrderNo());
        payDetails.setUserId(refund.getUserId());
        payDetails.setStoreId(refund.getStoreId());
        payDetails.setSellerId(order.getSellerId());
        payDetails.setPayType(order.getPayType());
        payDetails.setRefundAmount(order.getPayAmount());
        payDetails.setBizType(5);
        return payDetails;
    }

    private RefundItem buildRefundItemValue(OrderBaoZhu baoZhu, Order order, Refund refund) {
        int intDiscountAmount = 0;
//        //当前商品优惠金
        RefundItem item = new RefundItem();
        item.setId(keyGenerator.generateSnowflakeNumKey());
        item.setSellerId(order.getSellerId());
        item.setBizType(5);
        item.setUserId(order.getUserId());
        item.setRefundNo(refund.getRefundNo());
        item.setOrderNo(refund.getOrderNo());
        item.setOrderItemId(0L);
        item.setItemId("-1");
        item.setGoodsId(-1L);
        item.setItemImage("https://images.qmai.cn/s11478/2023/04/06/f05e6b031b4c42c6dc.jpg");
        item.setItemSign("");
        item.setDiscountAmount(order.getDiscountAmount());
        item.setItemName("历史消费商品");
        item.setRefundNum(new BigDecimal(1));
        item.setNum(new BigDecimal(1));
        Integer refundAmount = 0;
//        if (Objects.nonNull(juiceOrder.getItemPrice())) {
//            BigDecimal multiply = juiceOrder.getItemPrice().multiply(new BigDecimal(100));
//            refundAmount = Double.valueOf(multiply.toString()).intValue();
//        }
        item.setRefundAmount(refund.getAmount());

//        BigDecimal itemPrice = new BigDecimal(refundAmount + intDiscountAmount).divide(item.getNum(), 0, RoundingMode.DOWN);
//        int intItemPrice = (Double.valueOf(itemPrice.toString()).intValue());
        item.setItemPrice(refund.getAmount());
        item.setItemSpec(null);
        item.setItemUnit("");
        item.setItemType(2);
        item.setRefundWay(2);
        item.setCreatedAt(refund.getOrderAt());
        item.setFeatures(null);
        item.setSellerId(refund.getSellerId());
        item.setItemType(0);
        return item;
    }

    @Autowired
    private OrderGuTouDao guTouDao;

    @Override
    public void gutouOrder() {
        try {
            logger.info("gutouOrder[start]");
            Long lastId = 0L;
            int count = 0;
            int size = 200;
            for (; ; ) {
                List<OrderGuTou> list = guTouDao.selectList(lastId, size);
                if (CollectionUtils.isEmpty(list)) {
                    break;
                }
                Result<String> redisData = redisManager.get("stop-gutou-Order");
                if (redisData.isStatus() && Objects.nonNull(redisData.getData())) {
                    return;
                }
                while (workQueue.remainingCapacity() < 80) {
                    logger.info("gutouOrderWorkQueue size:{}", workQueue.size());
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                executorService.submit(() -> {
                    doTransferGuTou(list);
                });

                lastId = list.get(list.size() - 1).getId();
                count = count + list.size();
                logger.info("gutouOrder[running], count:{},lastId:{}", count, lastId);
                if (list.size() < size) {
                    break;
                }
            }
            logger.info("gutouOrder[end], count:{},lastId:{}", count, lastId);

        } catch (Throwable e) {
            logger.error("gutouOrder[execute] failed!, cause by:{}", e);
        }
    }


    private void doTransferGuTou(List<OrderGuTou> list) {
        try {
            int size = 200;
            List<Order> orderList = new ArrayList<>(size);
            List<OrderItem> itemList = new ArrayList<>(size);
            List<OrderPayDetails> payList = new ArrayList<>(size);
            List<OrderIndex> indexList = new ArrayList<>(size);
            List<OrderDiscount> discountList = new ArrayList<>(size);

            for (OrderGuTou item : list) {
                Order order = buildOrder(item);
                buildItem(item, order, itemList);
                OrderPayDetails orderPayDetails = buildPayDetail(item, order);
                OrderIndex orderIndex = buildOrderIndex(order);
                buildDiscount(item, order, discountList);

                orderList.add(order);
                indexList.add(orderIndex);
                payList.add(orderPayDetails);
            }

            //新增订单
            if (!CollectionUtils.isEmpty(orderList)) {
                orderDao.insertList(orderList);
            }
            // 新增订单索引
            if (!CollectionUtils.isEmpty(indexList)) {
                indexDao.insertList(indexList);
            }
            //批量新增商品
            if (!CollectionUtils.isEmpty(itemList)) {
                orderItemDao.inserts(itemList);
            }
            //批量新增支付明细
            if (!CollectionUtils.isEmpty(payList)) {
                payDao.insertList(payList);
            }
            //批量新增订单优惠
            if (!CollectionUtils.isEmpty(discountList)) {
                discountDao.inserts(discountList);
            }
            searchManager.indexOrder(orderList);

            orderNum += orderList.size();
            logger.info("gutouOrder[doTransferGuTou], ThreadName:{},lastId:{}, count:{}", Thread.currentThread().getName(),
                    list.get(list.size() - 1).getId(),
                    orderNum);
        } catch (Throwable e) {
            logger.error("gutouOrder[doTransferError] failed!, cause by:{}", e);
        }
    }

    // todo beta
    private Long guTouSellerId = 217487L;

    private Order buildOrder(OrderGuTou item) {
        Long userId = item.getUserId();
        String mobile = item.getMobile();
        Order order = new Order();

        order.setPayAmount(0);
        order.setItemAmount(0);
        order.setPayStatus(1);
        order.setStatus(50);
        order.setBizSubType(0);
        order.setPackAmount(0);
        order.setChangeAmount(0);
        order.setPayModel(0);
        order.setIsAlone(0);
        order.setInvoiceType(0);
        order.setAfterSaleStatus(0);
        order.setReceiveStatus(0);
        order.setPerformanceStatus(0);
        order.setCommentStatus(0);
        order.setPerformanceType(0);
        order.setIsReceipt(0);
        order.setIsImmediatePerformance(0);
        order.setSourceNo("");
        order.setBizType(5);
        order.setFromSystem(0);
        order.setOrderSubType(0);
        order.setIsDeleted(1);
        order.setAddrId(0);
        order.setAddrInfo("");
        order.setSyncFlag(0);
        order.setVersion(1);
        order.setPayFlag(1);
        order.setStoreId(0L);
        order.setRefundFlag(0);
        order.setUpdatedAt(new Date());
        order.setFreightAmount(0);


        order.setSellerId(guTouSellerId);
        order.setId(keyGenerator.generateSnowflakeNumKey());
        order.setOrderNo(item.getOrderNo());
        order.setSource(item.getSource());
        order.setUserId(userId);

        String beforeOrderAt = "2023-04-23 00:00:00";


        Date orderAt = item.getOrderAt();
        String defOrderAt = "2023-05-05 03:03:03";
        try {
            Date beforeOrderAtDate = DateUtils.parse(beforeOrderAt);
            if (Objects.isNull(orderAt)) {
                orderAt = DateUtils.parse(defOrderAt);
            }
            if (Objects.nonNull(orderAt)) {
                if (item.getOrderAt().after(new Date()) || item.getOrderAt().before(beforeOrderAtDate)) {
                    orderAt = DateUtils.parse(defOrderAt);
                }
            }
        } catch (Throwable throwable) {
        }

        order.setTotalAmount(CommonUtils.yuanToFen(item.getTotalAmount()));
        order.setDiscountAmount(CommonUtils.yuanToFen(item.getDiscountAmount()));
        order.setActualAmount(CommonUtils.yuanToFen(item.getActualAmount()));
        order.setItemAmount(CommonUtils.yuanToFen(item.getItemAmount()));
        order.setPayAmount(CommonUtils.yuanToFen(item.getActualAmount()));
        order.setPayer(userId);
        order.setMobile(mobile);
        order.setOrderAt(orderAt);
        order.setCreatedAt(orderAt);
        order.setPayAt(orderAt);
        order.setCompletedAt(orderAt);
        order.setPayType(item.getPayType());
        order.setOrderType(item.getOrderType());
        if (StringUtils.isEmpty(order.getOrderNo())) {
            order.setOrderNo(keyGenerator.generateSnowflakeKey());
        }

        Map<String, Object> map = new HashMap();
        map.put("historyOrder", 1);
        Map<String, Object> userInfoMap = new HashMap();
        userInfoMap.put("phone", mobile);
        userInfoMap.put("openId", "");
        userInfoMap.put("userName", "");
        userInfoMap.put("userId", userId);
        map.put("userInfo", userInfoMap);

        Map<String, Object> payInfoMap = new HashMap();
        payInfoMap.put("amount", order.getPayAmount() / 100);
        payInfoMap.put("useWallet", 0);
        payInfoMap.put("walletAmount", 0);
        payInfoMap.put("payDetailsList", Lists.newArrayList("在线支付: ¥" + order.getPayAmount() / 100));
        order.setPayInfo(JSON.toJSONString(payInfoMap));

        order.setExtraMap(map);
        return order;
    }


    private OrderItem buildItem(OrderGuTou thirdOrder, Order order, List<OrderItem> list) {
        OrderItem item = new OrderItem();
        item.setId(keyGenerator.generateSnowflakeNumKey());
        item.setBizType(5);
        item.setUserId(order.getUserId());
        item.setOrderNo(order.getOrderNo());
        item.setItemId("-1");
        item.setGoodsId(0L);
        item.setItemImage("https://images.qmai.cn/qmv0/UQhiCLUpe4qmyAZ-kg5zt-_DomQPv4czXVQvurmwKNVy7Yk1oTTR0Ma5GMvFcDSjuMWPdYS02MM");
        item.setItemName("历史迁移商品");
        item.setItemSign("");
        item.setDiscountAmount(order.getDiscountAmount());
        item.setNum(new BigDecimal(1));
        item.setItemSpec(null);
        item.setItemUnit("");
        item.setBrandSign("");
        item.setMarketPrice(0);
        item.setCostPrice(0);
        item.setMemberPrice(0);
        item.setPackAmount(0);
        item.setfCode("");
        item.setStatus(0);
        item.setActivityId(0L);
        item.setIsTimeDiscount(0);
        item.setOrderAt(order.getOrderAt());
        item.setProductNo("");
        item.setIsGift(0);
        item.setSellerId(order.getSellerId());
        item.setItemType(0);
        item.setOwnerId(0L);
        item.setBatchingInfo("");
        Map<String, Object> map = new HashMap();
        map.put("historyOrder", 1);
        if (order.getOrderType().equals(5)) {
            map.put("depositActivityTitle", "历史储值活动");
            map.put("depositRechargeAmount", thirdOrder.getItemAmount());
            map.put("depositPresentAmount", thirdOrder.getGiftAmount());
            map.put("isThirdDepositActivity", 0);
            map.put("giftIntegral", 0);
        }
        item.setExtraMap(map);

        //商品实付金额
        item.setItemPrice(order.getItemAmount());
        //市场价
        item.setMarketPrice(order.getItemAmount());
        item.setDiscountAmount(order.getDiscountAmount());
        if (order.getOrderType().equals(5)) {
            item.setItemName("历史储值");
        }

        InnerOrderItem inner = mapper.map(item, InnerOrderItem.class);
        List<InnerOrderItem> innerOrderItems = Arrays.asList(inner);
        order.setItemInfo(JSON.toJSONString(innerOrderItems));

        list.add(item);


        return item;
    }

    private OrderPayDetails buildPayDetail(OrderGuTou thirdOrder, Order order) {
        OrderPayDetails payDetails = new OrderPayDetails();
        payDetails.setId(keyGenerator.generateSnowflakeNumKey());
        payDetails.setOrderNo(order.getOrderNo());
        payDetails.setUserId(order.getUserId());
        payDetails.setAmount(order.getPayAmount());
        payDetails.setPayType(order.getPayType());
        payDetails.setStoreId(order.getStoreId());
        payDetails.setSellerId(order.getSellerId());
        payDetails.setOrderAt(order.getOrderAt());
        payDetails.setPayAt(order.getOrderAt());
        payDetails.setOrderType(order.getOrderType());
        payDetails.setSource(order.getSource());
        payDetails.setBizType(order.getBizType());
        payDetails.setPerformanceType(order.getPerformanceType());
        payDetails.setPayNo("");
        payDetails.setThirdPayNo("");
        Map<String, Object> map = new HashMap();
        map.put("historyOrder", 1);
        payDetails.setExtraMap(map);
        String payDetailInfo = JSON.toJSONString(Arrays.asList(mapper.map(payDetails, InnerOrderPayDetails.class)));
        order.setPayDetailInfo(payDetailInfo);
        return payDetails;
    }

    private void buildDiscount(OrderGuTou thirdOrder, Order order, List<OrderDiscount> discountList) {
        if (Objects.isNull(order.getDiscountAmount())) {
            return;
        }
        if (order.getDiscountAmount() <= 0) {
            return;
        }
        OrderDiscount discount = new OrderDiscount();
        discount.setId(keyGenerator.generateSnowflakeNumKey());
        discount.setBizType(5);
        discount.setUserId(order.getUserId());
        discount.setOrderNo(order.getOrderNo());
        discount.setSellerId(order.getSellerId());
        discount.setStatus(0);
        discount.setItemId("-1");
        discount.setDiscountLevel(0);
        discount.setDiscountId("-1");
        discount.setDiscountType(2);
        discount.setDiscountName("优惠券");
        discount.setDiscountSummary("优惠券");
        Map<String, Object> map = new HashMap();
        map.put("historyOrder", 1);
        discount.setExtraMap(map);
        discount.setDiscountAmount(order.getDiscountAmount());

        String payDetailInfo = JSON.toJSONString(Arrays.asList(mapper.map(discount, InnerOrderDiscount.class)));
        order.setDiscountInfo(payDetailInfo);

        discountList.add(discount);
    }


    @Override
    public void delGuTouOrder() {
        try {
            Long lastId = 0L;
            int size = 200;
            int count = 0;
            int orderCount = 0;
            for (; ; ) {
                List<OrderGuTou> list = guTouDao.selectList(lastId, size);
                if (CollectionUtils.isEmpty(list)) {
                    break;
                }
                while (workQueue.remainingCapacity() < 50) {
                    logger.info("delGuTouOrderWorkQueue size:{}", workQueue.size());
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                executorService.submit(() -> {
                    doDelGuTou(list);
                });
                lastId = list.get(list.size() - 1).getId();
                count = count + list.size();
                logger.info("delGuTouOrder,count:{},lastId:{}, orderCount:{}", count, lastId, orderCount);
                if (list.size() < size) {
                    break;
                }
            }
        } catch (Throwable e) {
            logger.error("TempOrderServiceImplSync[delGuTouOrder] failed!, cause by:{}", e);
        }
    }
}

