package com.ms.biz.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.doudian.open.api.order_logisticsAddMultiPack.param.OrderLogisticsAddMultiPackParam;
import com.doudian.open.api.order_logisticsAddMultiPack.param.PackListItem;
import com.doudian.open.api.order_logisticsAddMultiPack.param.ShippedOrderInfoItem;
import com.doudian.open.api.supplyCenter_order_cancel.param.SupplyCenterOrderCancelParam;
import com.doudian.open.api.supplyCenter_order_confirm.param.SupplyCenterOrderConfirmParam;
import com.doudian.open.api.supplyCenter_order_logistics.param.SupplyCenterOrderLogisticsParam;
import com.doudian.open.api.supplyCenter_order_pay.param.SkuOrderPayInfosItem;
import com.doudian.open.api.supplyCenter_order_pay.param.SupplyCenterOrderPayParam;
import com.doudian.open.api.supplyCenter_order_syncSupplierInfo.param.SkuOrdersItem;
import com.doudian.open.api.supplyCenter_order_syncSupplierInfo.param.SupplierOrderUrl;
import com.doudian.open.api.supplyCenter_order_syncSupplierInfo.param.SupplyCenterOrderSyncSupplierInfoParam;
import com.doudian.open.api.supplyCenter_refund_operate.param.Address;
import com.doudian.open.api.supplyCenter_refund_operate.param.SkuRefundInfosItem;
import com.doudian.open.api.supplyCenter_refund_operate.param.SupplyCenterRefundOperateParam;
import com.doudian.open.utils.StringUtil;
import com.jinritemai.cloud.base.core.util.AuthThreadLocalUtil;
import com.ms.biz.consts.*;
import com.ms.biz.quque.Group;
import com.ms.biz.quque.Producer;
import com.ms.biz.quque.Topic;
import com.ms.biz.service.DsMessageConsumerBufferService;
import com.ms.biz.service.DsMessageConsumerQueueService;
import com.ms.biz.service.DsMessageService;
import com.ms.api.dto.dsorder.*;
import com.ms.biz.tool.CommonTool;
import com.ms.biz.util.DDApi;
import com.ms.dal.entity.*;
import com.ms.dal.mapper.*;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
@AllArgsConstructor
public class DsMessageServiceImpl implements DsMessageService {
    private final DataSourceTransactionManager dataSourceTransactionManager;
    private final TransactionDefinition transactionDefinition;

    private DsMessageMapper dsMessageMapper;
    private DsMessageConsumerBufferService dsMessageConsumerBufferService;
    private DsMessageConsumerQueueService dsMessageConsumerQueueService;
    private PlatformPurchaseOrderMapper platformPurchaseOrderMapper;
    private PlatformPurchaseOrderSkuMapper platformPurchaseOrderSkuMapper;
    private PurchaseOrderMapper purchaseOrderMapper;
    private PurchaseOrderItemMapper purchaseOrderItemMapper;
    private LogisticsMapper logisticsMapper;
    private RefundPurchaseOrderMapper refundPurchaseOrderMapper;
    private RefundPurchaseOrderSkuMapper refundPurchaseOrderSkuMapper;

    @Override
    public int deleteByPrimaryKey(Long id) {
        return dsMessageMapper.deleteByPrimaryKey(id);
    }

    @Override
    public int insert(DsMessage record) {
        return dsMessageMapper.insert(record);
    }

    @Override
    public int insertSelective(DsMessage record) {
        return dsMessageMapper.insertSelective(record);
    }

    @Override
    public DsMessage selectByPrimaryKey(Long id) {
        return dsMessageMapper.selectByPrimaryKey(id);
    }

    @Override
    public int updateByPrimaryKeySelective(DsMessage record) {
        return dsMessageMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    public int updateByPrimaryKey(DsMessage record) {
        return dsMessageMapper.updateByPrimaryKey(record);
    }

    @Override
    public DsMessageDTO parseData(DsMessage dsMessage) {
        DsMessageDTO dto;
        switch (dsMessage.getBizType()) {
            case DsMessageConst.BIZ_TYPE_CANCEL_PURCHASE_ORDER:
                dto = JSONObject.parseObject(dsMessage.getData(), PurchaseOrderCancelMessageDTO.class);
                break;
            case DsMessageConst.BIZ_TYPE_PURCHASE_ORDER_CHANGE:
                dto = JSONObject.parseObject(dsMessage.getData(), PurchaseOrderChangeMessageDTO.class);
                break;
            case DsMessageConst.BIZ_TYPE_RELATE_PURCHASE_ORDER:
                dto = JSONObject.parseObject(dsMessage.getData(), PurchaseOrderRelateMessageDTO.class);
                break;
            default:
                throw new RuntimeException("该消息类型不能解析");
        }
        return dto;
    }

    @Override
    public boolean hasNewThanDsMessage(DsMessage dsMessage, String bizType) {
        DsMessageDTO dto = parseData(dsMessage);
        String purchaseOrderSn = null;
        if (Objects.equals(dsMessage.getBizType(), DsMessageConst.BIZ_TYPE_PURCHASE_ORDER_CHANGE)) {
            purchaseOrderSn = ((PurchaseOrderChangeMessageDTO) dto).getPurchaseOrderInfo().getPurchaseOrderSn();
        } else if (Objects.equals(dsMessage.getBizType(), DsMessageConst.BIZ_TYPE_RELATE_PURCHASE_ORDER)) {
            purchaseOrderSn = ((PurchaseOrderRelateMessageDTO) dto).getPurchaseOrderInfo().getPurchaseOrderSn();
        }

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        DsMessage newDsMessage = getNewestDsMessage(dsMessage.getBizId(), dsMessage.getBizType(), dsMessage.getPlatformPushMsgId(), format.format(dsMessage.getGmtCreate()), purchaseOrderSn);
        return newDsMessage != null;
    }

    @Override
    public DsMessage getNewestDsMessage(String bizId, String bizType, Long curPlatformPushMsgId, String curGmtCreate, @Nullable String purchaseOrderSn) {
        return dsMessageMapper.getNewestDsMessage(bizId, bizType, curPlatformPushMsgId, curGmtCreate, purchaseOrderSn);
    }

    @Override
    public DsMessage add(Long shopId, Long platformPushMsgId, String bizId, String bizType, String data) {
        DsMessage dsMessage = new DsMessage();
        dsMessage.setShopId(shopId);
        dsMessage.setPlatformPushMsgId(platformPushMsgId);
        dsMessage.setBizId(bizId);
        dsMessage.setData(data);
        dsMessage.setBizType(bizType);
        dsMessage.setGmtCreate(new Date());
        dsMessage.setGmtModified(new Date());
        dsMessageMapper.insertSelective(dsMessage);
        return dsMessage;
    }

    @Override
    public void addDsMessage(Long shopId, Long platformPushMsgId, String bizId, String bizType, String data) {
        log.info("addDsMessagePlatformPushMsgId" + platformPushMsgId);
        DsMessage dsMessage = add(shopId, platformPushMsgId, bizId, bizType, data);
        com.ms.biz.quque.message.DsMessage message = new com.ms.biz.quque.message.DsMessage();
        message.setDsMessageId(dsMessage.getDsMessageId());
        Producer producer = new Producer(Group.GROUP_DS_MESSAGE);
        producer.send(message.build(Topic.TOPIC_DS_MESSAGE), 5000);
    }

    @Override
    @Transactional
    public void clearDsMessageQueue(DsMessageConsumerQueue queue, ResultDTO result) {
        System.out.println("queue: " + queue);
        System.out.println("result: " + result);
        log.info("clearDsMessageQueue[queue]:"  + queue);
        log.info("clearDsMessageQueue[result]:"  + result);
        boolean isDelay = false;
        if (result.getData().containsKey("code")) {
            isDelay = result.getData().get("code").equals(StatusConst.delay);
        }
        if (isDelay) {
            int randomNum = CommonTool.getRandom(2, 5);
            Date gmtExec = new Date(new Date().getTime() + randomNum * 1000L);
            dsMessageConsumerBufferService.addBuffer(queue.getShopId(), queue.getDsMessageId(), gmtExec);
        } else {
            dsMessageMapper.updateStatus(queue.getDsMessageId(), result.getResult(), result.getReason());
        }
        dsMessageConsumerQueueService.deleteByPrimaryKey(queue.getDsMessageConsumerQueueId());
    }

    @Override
    public void processDsMessage(Long dsMessageId) {
        DsMessage dsMessage = selectByPrimaryKey(dsMessageId);
        String reason = "成功";
        String status = StatusConst.success;
        try {
            handleDsMessage(dsMessage);
        } catch (RuntimeException e) {
            log.error("processDsMessageError", e);
            reason = e.getMessage();
            status = StatusConst.fail;
        } catch (Throwable e) {
            log.error("processDsMessageError", e);
            reason = "系统异常";
            status = StatusConst.fail;
        }
        dsMessage.setStatus(status);
        dsMessage.setReason(reason);
        dsMessage.setGmtModified(new Date());
        dsMessageMapper.updateByPrimaryKeySelective(dsMessage);
    }

    private void handleDsMessage(DsMessage dsMessage) {
        if (dsMessage == null) {
            log.error("handleDsMessage: 消息不存在");
            throw new RuntimeException("消息不存在");
        }

        DsMessageDTO messageDTO = parseData(dsMessage);
        boolean isExpire = isDsMessageExpire(dsMessage, messageDTO);
        if (isExpire) {
            if (Objects.equals(dsMessage.getBizType(), DsMessageConst.BIZ_TYPE_RELATE_PURCHASE_ORDER)) {
                PurchaseOrderDTO purchaseOrderDTO = ((PurchaseOrderRelateMessageDTO)messageDTO).getPurchaseOrderInfo();
                // do something
            }
            log.error("handleDsMessage: 消息已过期");
//            throw new RuntimeException("消息已过期");
        }

        switch (dsMessage.getBizType()) {
            case DsMessageConst.BIZ_TYPE_RELATE_PURCHASE_ORDER:
//                handlePurchaseOrderRelate((PurchaseOrderRelateMessageDTO)messageDTO);
                break;
            case DsMessageConst.BIZ_TYPE_PURCHASE_ORDER_CHANGE:
                handlePurchaseOrderChange((PurchaseOrderChangeMessageDTO)messageDTO);
                break;
            case DsMessageConst.BIZ_TYPE_CANCEL_PURCHASE_ORDER:
                handlePurchaseOrderCancel((PurchaseOrderCancelMessageDTO)messageDTO);
                break;
            default:
                throw new RuntimeException("bizType [" + dsMessage.getBizType()  + "] 暂无对应的处理逻辑");
        }
    }

    private boolean isDsMessageExpire(DsMessage dsMessage, DsMessageDTO messageDTO) {
        if (messageDTO.getGmtMessageCreate() == null) {
            return false;
        }
        switch (dsMessage.getBizType()) {
            case DsMessageConst.BIZ_TYPE_CANCEL_PURCHASE_ORDER:
                return hasNewThanDsMessage(dsMessage, DsMessageConst.BIZ_TYPE_RELATE_PURCHASE_ORDER);
            case DsMessageConst.BIZ_TYPE_PURCHASE_ORDER_CHANGE:
                return hasNewThanDsMessage(dsMessage, DsMessageConst.BIZ_TYPE_PURCHASE_ORDER_CHANGE);
            case DsMessageConst.BIZ_TYPE_RELATE_PURCHASE_ORDER:
                return hasNewThanDsMessage(dsMessage, DsMessageConst.BIZ_TYPE_CANCEL_PURCHASE_ORDER);
            default:
                return false;
        }
    }

    private void handlePurchaseOrderChange(PurchaseOrderChangeMessageDTO messageDTO) {
        PurchaseOrderDTO purchaseOrderDTO = messageDTO.getPurchaseOrderInfo();
        PurchaseOrder purchaseOrder = purchaseOrderMapper.getByPurchaseOrderSn(purchaseOrderDTO.getPurchaseOrderSn());
        PlatformPurchaseOrder platformPurchaseOrder = platformPurchaseOrderMapper.selectByPrimaryKey(purchaseOrder.getPurOrderId());

        AuthThreadLocalUtil.set(platformPurchaseOrder.getShopId().toString());

        List<PlatformPurchaseOrderSku> platformPurchaseOrderSkus = platformPurchaseOrderSkuMapper.getListByPurOrderIds(Collections.singletonList(purchaseOrder.getPurOrderId()));
        Map<Long, PlatformPurchaseOrderSku> skuIdAndPlatformPurchaseOrderSkuMap = platformPurchaseOrderSkus.stream().collect(Collectors.toMap(PlatformPurchaseOrderSku::getSkuId, x->x));

        String purchaseOrderStatus  = purchaseOrderDTO.getPurchaseOrderStatus();

        if (messageDTO.getAlibabaMsg() != null && messageDTO.getAlibabaMsg().isRefundMsg()) {
            handlePurchaseOrderRefund(purchaseOrderDTO, purchaseOrder, messageDTO.getAlibabaMsg());
            return;
        }

        log.error("handleDsMessage purchaseOrderStatus: " + purchaseOrderStatus);

        if (!Objects.equals(purchaseOrder.getPurchaseOrderStatus(),purchaseOrderStatus)){
            switch (purchaseOrderStatus) {
                case PurchaseOrderConst.PURCHASE_ORDER_STATUS_WAIT_SEND:
                    handlePurchaseOrderAfterPay(purchaseOrderDTO, purchaseOrder, skuIdAndPlatformPurchaseOrderSkuMap);
                    break;
                case PurchaseOrderConst.PURCHASE_ORDER_STATUS_HAS_SEND:
                    handlePurchaseOrderAfterSend(purchaseOrderDTO, purchaseOrder, skuIdAndPlatformPurchaseOrderSkuMap);
                    break;
                case PurchaseOrderConst.PURCHASE_ORDER_STATUS_FINISHED:
                    handlePurchaseOrderAfterFinish(purchaseOrderDTO, purchaseOrder);
                    break;
                case PurchaseOrderConst.PURCHASE_ORDER_STATUS_CANCEL:
                    handlePurchaseOrderAfterCancel(purchaseOrderDTO, purchaseOrder);
                    platformPurchaseOrder.setStatus(StatusConst.delete); // TODO 多单？精选
                    break;
            }
            platformPurchaseOrder.setPurchaseStatus(purchaseOrderStatus);
            platformPurchaseOrder.setGmtModified(new Date());
            platformPurchaseOrderMapper.updateByPrimaryKeySelective(platformPurchaseOrder);

            purchaseOrder.setPurchaseOrderStatus(purchaseOrderStatus);
            purchaseOrder.setGmtModified(new Date());
            purchaseOrderMapper.updateByPrimaryKeySelective(purchaseOrder);

            if (purchaseOrder.getStatus().equals(StatusConst.delete)) {
                purchaseOrderItemMapper.updateStatusByPurchaseOrderIds(StatusConst.delete, Collections.singletonList(purchaseOrder.getPurchaseOrderId()));
            }
        }
    }

    private void handlePurchaseOrderAfterPay(PurchaseOrderDTO purchaseOrderDTO, PurchaseOrder purchaseOrder, Map<Long, PlatformPurchaseOrderSku> skuIdAndPlatformPurchaseOrderSkuMap) {
        purchaseOrder.setPurchaseOrderPayment(new BigDecimal(purchaseOrderDTO.getPurchaseOrderPayment()));

        Date payTime = CommonTool.parseDate(purchaseOrderDTO.getPurchaseOrderPayTime());

        SupplyCenterOrderPayParam param = new SupplyCenterOrderPayParam();
        param.setPayAmount((long)(Double.parseDouble(purchaseOrderDTO.getPurchaseOrderPayment()) * 100));
        param.setPayTime(payTime.getTime());
        param.setPurOrderId(purchaseOrder.getPurOrderId());
        param.setPostAmount(0L);
        List<SkuOrderPayInfosItem> skuOrderPayInfosItems = new ArrayList<>();
        for (PurchaseOrderItemDTO item: purchaseOrderDTO.getItems()) {
            PlatformPurchaseOrderSku platformPurchaseOrderSku = skuIdAndPlatformPurchaseOrderSkuMap.get(item.getSkuId());
            SkuOrderPayInfosItem skuOrderPayInfosItem = new SkuOrderPayInfosItem();
            skuOrderPayInfosItem.setPayAmount((long)(item.getPurchasePrice() * 100 * item.getPurchaseNum()));
            skuOrderPayInfosItem.setPurSkuOrderId(platformPurchaseOrderSku.getPurSkuOrderId());
            skuOrderPayInfosItems.add(skuOrderPayInfosItem);
        }
        param.setSkuOrderPayInfos(skuOrderPayInfosItems);
        DDApi.supplyCenterOrderPay(param);
    }

    private void handlePurchaseOrderAfterSend(PurchaseOrderDTO purchaseOrderDTO, PurchaseOrder purchaseOrder, Map<Long, PlatformPurchaseOrderSku> skuIdAndPlatformPurchaseOrderSkuMap) {
        Date purchaseOrderSendTime = CommonTool.parseDate(purchaseOrderDTO.getPurchaseOrderUpdateTime());
        purchaseOrder.setPurchaseOrderSendTime(purchaseOrderSendTime);
        purchaseOrder.setPurchaseOrderLogisticsName(purchaseOrder.getPurchaseOrderLogisticsName());
        purchaseOrder.setPurchaseOrderWaybillCode(purchaseOrder.getPurchaseOrderWaybillCode());

        SupplyCenterOrderLogisticsParam param = new SupplyCenterOrderLogisticsParam();
        param.setPurOrderId(purchaseOrder.getPurOrderId());
        if (purchaseOrderSendTime != null) {
            param.setExpressTime(purchaseOrderSendTime.getTime());
        }
        param.setExpressType(1);
        DDApi.supplyCenterOrderLogistics(param);

        logisticsAddMultiPack(purchaseOrderDTO, skuIdAndPlatformPurchaseOrderSkuMap);
    }

    private void logisticsAddMultiPack(PurchaseOrderDTO purchaseOrderDTO, Map<Long, PlatformPurchaseOrderSku> skuIdAndPlatformPurchaseOrderSkuMap) {
        OrderLogisticsAddMultiPackParam param = new OrderLogisticsAddMultiPackParam();
        param.setOrderId(purchaseOrderDTO.getPlatformOrderId());

        List<PackListItem> packageList = new ArrayList<>();
        PackListItem packListItem = new PackListItem();
        packListItem.setLogisticsCode(purchaseOrderDTO.getPurchaseOrderWaybillCode());

        String logisticsName = LogisticsConst.getDDLogisticsName(purchaseOrderDTO.getPurchaseOrderLogisticsName());
        Logistics logistics = logisticsMapper.getByLogisticsName(logisticsName);
        if (logistics == null) {
            log.info("物流不存在: 1688[{}] 抖店[{}]", purchaseOrderDTO.getPurchaseOrderLogisticsName(), logisticsName);
            throw new RuntimeException("物流不存在");
        }
        packListItem.setCompanyCode(logistics.getLogisticsCode());
        packListItem.setCompany(logisticsName);
        List<ShippedOrderInfoItem> shippedOrderInfo = new ArrayList<>();
        for (PurchaseOrderItemDTO item: purchaseOrderDTO.getItems()) {
            PlatformPurchaseOrderSku platformPurchaseOrderSku = skuIdAndPlatformPurchaseOrderSkuMap.get(item.getSkuId());
            ShippedOrderInfoItem shippedOrderInfoItem = new ShippedOrderInfoItem();
            shippedOrderInfoItem.setShippedNum(Long.valueOf(item.getPurchaseNum()));
            shippedOrderInfoItem.setShippedOrderId(platformPurchaseOrderSku.getSkuOrderId());
            shippedOrderInfo.add(shippedOrderInfoItem);
        }
        packListItem.setShippedOrderInfo(shippedOrderInfo);
        packageList.add(packListItem);
        param.setPackList(packageList);
        param.setRequestId(UUID.randomUUID().toString());
        DDApi.logisticsAddMultiPack(param);
    }

    private void handlePurchaseOrderAfterFinish(PurchaseOrderDTO purchaseOrderDTO, PurchaseOrder purchaseOrder) {
        Date updateTime = CommonTool.parseDate(purchaseOrderDTO.getPurchaseOrderUpdateTime());
        SupplyCenterOrderConfirmParam param = new SupplyCenterOrderConfirmParam();
        param.setPurOrderId(purchaseOrder.getPurOrderId());
        param.setConfirmTime(updateTime.getTime());
        DDApi.supplyCenterOrderConfirm(param);
    }

    private void handlePurchaseOrderAfterCancel(PurchaseOrderDTO purchaseOrderDTO, PurchaseOrder purchaseOrder) {
        if (purchaseOrderDTO.getPurchaseOrderPayTime() != null) {
            return;
        }
        Date updateTime = CommonTool.parseDate(purchaseOrderDTO.getPurchaseOrderUpdateTime());
        purchaseOrder.setStatus(StatusConst.delete);
        SupplyCenterOrderCancelParam param = new SupplyCenterOrderCancelParam();
        param.setPurOrderId(purchaseOrder.getPurOrderId());
        param.setCancelTime(updateTime.getTime());
        DDApi.supplyCenterOrderCancel(param);
    }

    private Map<String, String> getSkuItemIdAndPurSkuOrderIdMap(PurchaseOrderDTO purchaseOrderDTO, PurchaseOrder purchaseOrder)  {
        Map<String, String> skuIdAndPurSkuOrderIdMap = new HashMap<>();
        List<PlatformPurchaseOrderSku> skus = platformPurchaseOrderSkuMapper.getListByPurOrderIds(Collections.singletonList(purchaseOrder.getPurOrderId()));
        for (PlatformPurchaseOrderSku sku: skus) {
            skuIdAndPurSkuOrderIdMap.put(String.valueOf(sku.getSkuId()), sku.getPurSkuOrderId());
        }
        Map<String, String> skuItemIdAndPurSkuOrderIdMap = new HashMap<>();
        for (PurchaseOrderItemDTO itemDTO: purchaseOrderDTO.getItems()) {
            if (!skuIdAndPurSkuOrderIdMap.containsKey(itemDTO.getSkuId().toString())) {
                log.info("purSkuOrderId unFound skuId: " + itemDTO.getSkuId() + "skuIdAndPurSkuOrderIdMap: " + skuIdAndPurSkuOrderIdMap);
                continue;
            }
            skuItemIdAndPurSkuOrderIdMap.put(itemDTO.getSubItemId(), skuIdAndPurSkuOrderIdMap.get(itemDTO.getSkuId().toString()));
        }
        return skuItemIdAndPurSkuOrderIdMap;
    }

    private void handlePurchaseOrderRefund(PurchaseOrderDTO purchaseOrderDTO, PurchaseOrder purchaseOrder, AlibabaMessage alibabaMessage) {
        if (alibabaMessage == null || purchaseOrderDTO.getRefundInfo() == null || purchaseOrderDTO.getRefundInfo().isEmpty()) {
            return;
        }
        String refundId = (String) alibabaMessage.getMsgData().get("refundId");
        RefundInfoDTO refundInfo = purchaseOrderDTO.getRefundInfo().get(refundId);
        if (refundInfo == null) {
            throw new RuntimeException("未找到售后信息");
        }

        Map<String, String> skuItemIdAndPurSkuOrderIdMap = getSkuItemIdAndPurSkuOrderIdMap(purchaseOrderDTO, purchaseOrder);

        saveRefundPurchaseOrder(refundInfo, purchaseOrder, skuItemIdAndPurSkuOrderIdMap);

        SupplyCenterRefundOperateParam param = new SupplyCenterRefundOperateParam();
        param.setPurOrderId(purchaseOrder.getPurOrderId());

        boolean isAfterSale = StringUtil.isNotEmpty(purchaseOrderDTO.getPurchaseOrderWaybillCode()) && StringUtil.isNotEmpty(purchaseOrderDTO.getPurchaseOrderLogisticsName());

        List<SkuRefundInfosItem> skuRefundInfosItems = new ArrayList<>();
        Set<String> subItemIds = refundInfo.getOrderEntryCountMap().keySet();
        for (String subItemId: subItemIds) {
            if (!skuItemIdAndPurSkuOrderIdMap.containsKey(subItemId)) {
                log.info("purSkuOrderId unFound subItemId: " + subItemId + "skuItemIdAndPurSkuOrderIdMap: " + skuItemIdAndPurSkuOrderIdMap);
                continue;
            }
            String purSkuOrderId = skuItemIdAndPurSkuOrderIdMap.get(subItemId);
            SkuRefundInfosItem skuRefundInfosItem = buildSkuRefundInfosItem(purSkuOrderId, refundInfo, alibabaMessage, isAfterSale);
            skuRefundInfosItems.add(skuRefundInfosItem);
        }
        param.setSkuRefundInfos(skuRefundInfosItems);
        DDApi.supplyCenterRefundOperate(param);
    }

    private void saveRefundPurchaseOrder(RefundInfoDTO refundInfo, PurchaseOrder purchaseOrder, Map<String, String> skuItemIdAndPurSkuOrderIdMap) {
        RefundPurchaseOrder refundPurchaseOrder = refundPurchaseOrderMapper.getByRefundId(refundInfo.getRefundId());
        List<RefundPurchaseOrderSku> refundPurchaseOrderSkus = new ArrayList<>();
        if (refundPurchaseOrder == null) {
            refundPurchaseOrder = new RefundPurchaseOrder();
            refundPurchaseOrder.setGmtCreate(new Date());
            for (Map.Entry<String, Integer> entry: refundInfo.getOrderEntryCountMap().entrySet()) {
                String purSkuOrderId = skuItemIdAndPurSkuOrderIdMap.get(entry.getKey());
                RefundPurchaseOrderSku  refundPurchaseOrderSku = new RefundPurchaseOrderSku();
                refundPurchaseOrderSku.setOrderId(String.valueOf(purchaseOrder.getOrderId()));
                refundPurchaseOrderSku.setPurOrderId(purchaseOrder.getPurOrderId());
                refundPurchaseOrderSku.setRefundId(refundInfo.getRefundId());
                refundPurchaseOrderSku.setShopId(purchaseOrder.getShopId());
                refundPurchaseOrderSku.setSubItemId(entry.getKey());
                refundPurchaseOrderSku.setPurSkuOrderId(purSkuOrderId);
                refundPurchaseOrderSku.setNum(entry.getValue());
                refundPurchaseOrderSku.setGmtCreate(new Date());
                refundPurchaseOrderSku.setGmtModified(new Date());
                refundPurchaseOrderSkus.add(refundPurchaseOrderSku);
            }
        }
        refundPurchaseOrder.setOrderId(String.valueOf(purchaseOrder.getOrderId()));
        refundPurchaseOrder.setPurOrderId(purchaseOrder.getPurOrderId());
        refundPurchaseOrder.setRefundId(refundInfo.getRefundId());
        refundPurchaseOrder.setOnlyRefund(refundInfo.getOnlyRefund());
        refundPurchaseOrder.setRefundGoods(refundInfo.getRefundGoods());
        refundPurchaseOrder.setRejectReason(refundInfo.getRejectReason() == null ? "" : refundInfo.getRejectReason());
        refundPurchaseOrder.setGoodsReceived(refundInfo.getGoodsReceived() ? 1 : 0);
        refundPurchaseOrder.setGoodsStatus(refundInfo.getGoodsStatus());
        refundPurchaseOrder.setShopId(purchaseOrder.getShopId());
        refundPurchaseOrder.setStatus(refundInfo.getStatus());
        refundPurchaseOrder.setSellerMobile(refundInfo.getSellerMobile());
        refundPurchaseOrder.setSellerTel(refundInfo.getSellerTel());
        refundPurchaseOrder.setSellerRealName(refundInfo.getSellerRealName());
        refundPurchaseOrder.setSellerReceiveAddress(refundInfo.getSellerReceiveAddress());
        refundPurchaseOrder.setGmtTimeOut(refundInfo.getGmtTimeOut());
        refundPurchaseOrder.setGmtModified(new Date());
        if (refundPurchaseOrder.getRefundPurchaseOrderId() == null) {
            refundPurchaseOrderMapper.insertSelective(refundPurchaseOrder);
            refundPurchaseOrderSkuMapper.insertBatch(refundPurchaseOrderSkus);
        } else {
            refundPurchaseOrderMapper.updateByPrimaryKeySelective(refundPurchaseOrder);
        }
    }

    private SkuRefundInfosItem buildSkuRefundInfosItem(String purSkuOrderId, RefundInfoDTO refundInfo, AlibabaMessage alibabaMessage, boolean isAfterSale) {
        SkuRefundInfosItem skuRefundInfosItem = new SkuRefundInfosItem();
        skuRefundInfosItem.setPurSkuOrderId(purSkuOrderId);
        skuRefundInfosItem.setRejectReason(refundInfo.getRejectReason());

        if (StringUtil.isNotEmpty(refundInfo.getSellerRealName()) || StringUtil.isNotEmpty(refundInfo.getSellerMobile()) || StringUtil.isNotEmpty(refundInfo.getSellerReceiveAddress())) {
            Address address = new Address();
            address.setUserName(refundInfo.getSellerRealName());
            address.setDetail(refundInfo.getSellerReceiveAddress());
            address.setMobile(refundInfo.getSellerMobile());
            skuRefundInfosItem.setAddress(address);
        }
        skuRefundInfosItem.setCloseReason("");
        skuRefundInfosItem.setOperationType(getOperateType(refundInfo, alibabaMessage));
        skuRefundInfosItem.setAftersaleType(getAftersaleType(refundInfo, isAfterSale));
        return skuRefundInfosItem;
    }

    private int getOperateType(RefundInfoDTO refundInfo, AlibabaMessage alibabaMessage) {
        JSONObject msgData = alibabaMessage.getMsgData();
        String refundAction = (String) msgData.get("refundAction");
        if (refundAction.equals(Refund1688Const.ACTION_BUYER_APPLY_REFUND)) {
            return 0;
        }
        if (Refund1688Const.isCloseAction(refundAction)) {
            return 5;
        }
        if (refundAction.equals(Refund1688Const.ACTION_SELLER_AGREE_REFUND_PROCOTOL)) {
            return 2;
        }
        if (refundInfo.getGoodsStatus() == 3 && Refund1688Const.isRejectRefundAction(refundAction)) {
            return 7;
        }
        if (refundInfo.getGoodsStatus() == 3 && Refund1688Const.isAgreeRefundAction(refundAction)) {
            return 4;
        }
        if (refundAction.equals(Refund1688Const.ACTION_BUYER_SEND_GOODS)) {
            return 6;
        }
        if (Refund1688Const.isAgreeRefundAction(refundAction)) {
            return 1;
        }
        if (Refund1688Const.isRejectRefundAction(refundAction)) {
            return 3;
        }
        return  0;
    }

    private int getAftersaleType(RefundInfoDTO refundInfo, boolean isAfterSale) {
        if (!isAfterSale && refundInfo.getOnlyRefund() == 1) {
            return 2;
        }
        if (isAfterSale && refundInfo.getOnlyRefund() == 1) {
            return 1;
        }
        return 3;
    }

    private void handlePurchaseOrderCancel(PurchaseOrderCancelMessageDTO messageDTO) {
    }

    private void handlePurchaseOrderRelate(PurchaseOrderRelateMessageDTO messageDTO) {
        PurchaseOrderDTO purchaseOrderDTO = messageDTO.getPurchaseOrderInfo();
        PurchaseOrder purchaseOrder = purchaseOrderMapper.getByPurchaseOrderSn(purchaseOrderDTO.getPurchaseOrderSn());
        PlatformPurchaseOrder platformPurchaseOrder = platformPurchaseOrderMapper.selectByPrimaryKey(purchaseOrder.getPurOrderId());

        AuthThreadLocalUtil.set(platformPurchaseOrder.getShopId().toString());

        List<PurchaseOrderItem> purchaseOrderItems = purchaseOrderItemMapper.getListByPurchaseOrderId(purchaseOrder.getPurchaseOrderId());
        List<PlatformPurchaseOrderSku> platformPurchaseOrderSkus = platformPurchaseOrderSkuMapper.getListByPurOrderIds(Collections.singletonList(purchaseOrder.getPurOrderId()));
        Map<Long, PlatformPurchaseOrderSku> skuIdAndPlatformPurchaseOrderSkuMap = platformPurchaseOrderSkus.stream().collect(Collectors.toMap(PlatformPurchaseOrderSku::getSkuId, x->x));

        SupplyCenterOrderSyncSupplierInfoParam param = new SupplyCenterOrderSyncSupplierInfoParam();
        param.setPurOrderId(platformPurchaseOrder.getPurOrderId());
        param.setSupplierOrderId(purchaseOrderDTO.getPurchaseOrderSn());
        SupplierOrderUrl supplierOrderUrl = new SupplierOrderUrl();
        String url = String.format("https://trade.1688.com/order/new_step_order_detail.htm?orderId=%s&amug_web_biz=fwmkt&amug_web_fl_src=cy", purchaseOrderDTO.getPurchaseOrderSn());
        supplierOrderUrl.setH5Url(url);
        supplierOrderUrl.setPcUrl(url);
        param.setSupplierOrderUrl(supplierOrderUrl);
        List<SkuOrdersItem> skuOrders = new ArrayList<>();
        Map<Long, String> skuIdAndSubItemIdMap = new HashMap<>();
        for (PurchaseOrderItemDTO item: purchaseOrderDTO.getItems()) {
            PlatformPurchaseOrderSku platformPurchaseOrderSku = skuIdAndPlatformPurchaseOrderSkuMap.get(item.getSkuId());
            SkuOrdersItem skuOrdersItem = new SkuOrdersItem();
            skuOrdersItem.setPurSkuOrderId(platformPurchaseOrderSku.getPurSkuOrderId());
            skuOrdersItem.setSupplierSkuOrderId(item.getSubItemId());
            skuIdAndSubItemIdMap.put(item.getSkuId(), item.getSubItemId());
            skuOrders.add(skuOrdersItem);
        }
        param.setSkuOrders(skuOrders);

        for (PurchaseOrderItem item: purchaseOrderItems) {
            if (skuIdAndSubItemIdMap.containsKey(item.getSkuId())) {
                item.setSubItemId(skuIdAndSubItemIdMap.get(item.getSkuId()));
                purchaseOrderItemMapper.updateByPrimaryKeySelective(item);
            }
        }

        DDApi.supplyCenterOrderSyncSupplierInfo(param);
    }
}




