package com.ms.biz.service.impl;

import com.alibaba.fastjson.JSON;
import com.doudian.open.api.supplyCenter_cargo_detail.data.SpecPricesItem;
import com.doudian.open.api.supplyCenter_cargo_detail.data.SupplyCenterCargoDetailData;
import com.doudian.open.api.supplyCenter_cargo_detail.param.SupplyCenterCargoDetailParam;
import com.doudian.open.api.supplyCenter_order_syncSupplierInfo.param.SupplierOrderUrl;
import com.ms.api.dto.dsapi.request.*;
import com.ms.api.dto.dsapi.response.*;
import com.ms.api.dto.dsorder.PurchaseOrderDTO;
import com.ms.api.dto.dsorder.PurchaseOrderItemDTO;
import com.ms.biz.consts.CommonConst;
import com.ms.biz.consts.DsOrderConst;
import com.ms.biz.consts.PurchaseOrderConst;
import com.ms.biz.consts.StatusConst;
import com.ms.biz.dto.openspi.request.*;
import com.ms.biz.dto.openspi.response.BatchCreateData;
import com.ms.biz.dto.openspi.response.BatchPayData;
import com.ms.biz.dto.openspi.response.OrderResult;
import com.ms.biz.dto.openspi.response.PaymentResult;
import com.ms.biz.service.DistributionOrderService;
import com.ms.biz.service.DsApiService;
import com.ms.biz.tool.SecurityTool;
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.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;

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

@Service
@Slf4j
@AllArgsConstructor
public class DistributionOrderServiceImpl implements DistributionOrderService {
    private final DataSourceTransactionManager dataSourceTransactionManager;
    private final TransactionDefinition transactionDefinition;

    private PlatformPurchaseOrderMapper platformPurchaseOrderMapper;
    private PlatformPurchaseOrderSkuMapper platformPurchaseOrderSkuMapper;
    private PlatformPurchaseOrderAddressMapper platformPurchaseOrderAddressMapper;
    private PlatformPurchaseOrderMaskAddressMapper platformPurchaseOrderMaskAddressMapper;
    private PurchaseOrderMapper purchaseOrderMapper;
    private PurchaseOrderItemMapper purchaseOrderItemMapper;
    private DsApiService dsApiService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public void batchCreate(BatchCreateParam param, BatchCreateData data) {
        System.out.println("param: " + param);
        if (param.getOrders().size() > 1) {
            throw new RuntimeException("目前暂不支持多单采购");
        }
        Long shopId = param.getShopId();

        Map<String, String> orderIdAndPurOrderIdMap = new HashMap<>();
        Map<Long, String> skuIdAndPurSkuOrderIdMap = new HashMap<>();
        for (CreateOrder order: param.getOrders()) {
            orderIdAndPurOrderIdMap.put(order.getOrderId(), order.getPurOrderId());
            for (SkuOrder skuOrder: order.getSkuOrders()) {
                skuIdAndPurSkuOrderIdMap.put(skuOrder.getSkuId(), skuOrder.getPurSkuOrderId());
            }
        }

        Set<String> purOrderIds = new HashSet<>(orderIdAndPurOrderIdMap.values());
        storeCreateOrders(shopId, param.getOrders(), purOrderIds);

        BatchCreateDistributionOrdersRequestDTO request = buildBatchCreateDistributionOrdersRequestDTO(param);
        BatchCreateDistributionOrdersResponseDTO response = dsApiService.batchCreateDistributionOrders(param.getShopId(), request);

//        String res = "{\"result\":\"success\",\"successCount\":1,\"failCount\":0,\"successList\":[{\"result\":\"success\",\"data\":{\"success\":true,\"totalSuccessAmount\":598,\"orderId\":\"3641170788609141341\",\"postFee\":0,\"mutilOrders\":null},\"createAlibabaOrderLogId\":1496,\"platformOrderIds\":[\"6923971910449173607\"],\"isEncryptOrder\":\"true\",\"isSupportEncryptOrder\":1,\"isUseManualConsignee\":0,\"flow\":\"fenxiao\",\"includeSplitJxhy\":false,\"sourceOrderIds\":[\"3641170788609141341\"],\"payRet\":null,\"platformOrderId\":\"6923971910449173607\",\"relatePurchaseOrderInfos\":[{\"platformOrderId\":\"6923971910449173607\",\"purchasePlatform\":\"1688DS\",\"purchaseOrderSn\":\"3641170788609141341\",\"purchaseOrderBuyer\":\"douhuotest\",\"purchaseOrderSeller\":\"\\u798f\\u5dde\\u67cf\\u4e3a\\u5546\\u8d38\\u6709\\u9650\\u516c\\u53f8\",\"purchaseOrderPayment\":\"5.98\",\"purchaseOrderFullname\":\"\\u6de1*\",\"purchaseOrderMobile\":\"1********80\",\"purchaseOrderFullAddress\":\"\\u6d59\\u6c5f\\u7701 \\u676d\\u5dde\\u5e02 \\u4f59\\u676d\\u533a \\u4ed3\\u524d\\u8857\\u9053 \\u4f59\\u676d*\\u8def****\",\"purchaseOrderStartTime\":\"2023-11-22 11:03:37\",\"platformPushStatus\":\"wait\",\"purchaseOrderLogisticsName\":\"\",\"purchaseOrderWaybillCode\":\"\",\"purchaseOrderStatus\":\"wait_pay\",\"purchaseOrderFlow\":\"fenxiao\",\"alibabaOrderStatus\":\"waitbuyerpay\",\"isUseManualConsignee\":0,\"isDsEncryptOrder\":0,\"isSupportEncryptOrder\":0,\"logisticsIsAccept\":false,\"items\":[{\"skuId\":\"3386515436145410\",\"wareId\":\"3651940874226638524\",\"purchaseNum\":\"2\",\"purchasePrice\":\"2.99\",\"sourceItemId\":\"712130508984\",\"subItemId\":\"3641170788609141341\"}],\"mergePurchasePlatformOrderIds\":null,\"purchaseOrderUpdateTime\":\"2023-11-22 11:03:37\",\"purchaseOrderPayTime\":null}]}],\"errorList\":null,\"lockSourceItems\":[{\"createPurchaseOrderLockSkuId\":\"2224\",\"createPurchaseOrderLockId\":\"20001680\",\"sourceItemId\":\"712130508984\",\"sourceSkuId\":\"4987755988437\",\"createPurchaseOrderLogId\":\"1553\",\"sourceOrderId\":\"3641170788609141341\",\"sourceNum\":null,\"reqId\":null,\"status\":\"lock\",\"gmtCreate\":\"2023-11-22 11:03:36\",\"gmtModified\":\"2023-11-22 11:03:37\",\"platformOrderId\":\"6923971910449173607\",\"platformItemId\":\"3651940874226638524\",\"platformSkuId\":\"3386515436145410\"}]}";
//        BatchCreateDistributionOrdersResponseDTO response = JSON.parseObject(res, BatchCreateDistributionOrdersResponseDTO.class);

        if (response.getErrorList() != null) {
            List<String> errorList = new ArrayList<>();
            for (DsErrorRetDTO errorRet: response.getErrorList()) {
                errorList.add(errorRet.getReason());
            }
            if (!errorList.isEmpty()) {
                throw new RuntimeException(String.join(";", errorList));
            }
        }

        List<OrderResult> orderResults = new ArrayList<>();
        List<PurchaseOrder> purchaseOrders = new ArrayList<>();
        List<PurchaseOrderItem> purchaseOrderItems = new ArrayList<>();
        for (DsSuccessRetDTO successRet: response.getSuccessList()) {
            for (PurchaseOrderDTO purchaseOrderDTO: successRet.getRelatePurchaseOrderInfos()) {
                String purOrderId = orderIdAndPurOrderIdMap.get(purchaseOrderDTO.getPlatformOrderId());
                PurchaseOrder purchaseOrder = buildPurchaseOrderByDTO(shopId, purchaseOrderDTO, purOrderId);
                purchaseOrders.add(purchaseOrder);
                List<PurchaseOrderItem> items = buildPurchaseOrderItemsByPurchaseOrderDTO(purchaseOrder, purchaseOrderDTO, purOrderId);
                purchaseOrderItems.addAll(items);
                OrderResult orderResult = buildOrderResult(purchaseOrderDTO, orderIdAndPurOrderIdMap, skuIdAndPurSkuOrderIdMap);
                orderResults.add(orderResult);
            }
        }
        data.setOrderResults(orderResults);

        purchaseOrderMapper.insertBatch(purchaseOrders);
        purchaseOrderItemMapper.insertBatch(purchaseOrderItems);
    }

    private PurchaseOrder buildPurchaseOrderByDTO(Long shopId, PurchaseOrderDTO purchaseOrderDTO, String purOrderId) {
        Date purchaseOrderSendTime = null;
        Date purchaseOrderStartTime = null;
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            if (StringUtils.isNotBlank(purchaseOrderDTO.getPurchaseOrderStartTime())) {
                purchaseOrderStartTime = dateFormat.parse(purchaseOrderDTO.getPurchaseOrderStartTime());
            }
            if (StringUtils.isNotBlank(purchaseOrderDTO.getPurchaseOrderSendTime())) {
                purchaseOrderSendTime = dateFormat.parse(purchaseOrderDTO.getPurchaseOrderSendTime());
            }
        } catch (java.text.ParseException e) {
            throw new RuntimeException("时间格式错误");
        }

        String purchaseOrderId = generateOrderId("purchase_order");

        PurchaseOrder purchaseOrder = new PurchaseOrder();
        purchaseOrder.setPurchaseOrderId(Long.valueOf(purchaseOrderId));
        purchaseOrder.setShopId(shopId);
        purchaseOrder.setPurOrderId(purOrderId);
        purchaseOrder.setOrderId(Long.valueOf(purchaseOrderDTO.getPlatformOrderId()));
        purchaseOrder.setPurchasePlatform(purchaseOrderDTO.getPurchasePlatform());
        purchaseOrder.setPurchaseOrderStatus(purchaseOrderDTO.getPurchaseOrderStatus());
        purchaseOrder.setPurchaseOrderSendTime(purchaseOrderSendTime);
        purchaseOrder.setPurchaseOrderStartTime(purchaseOrderStartTime);
        purchaseOrder.setPurchaseOrderPayment(BigDecimal.valueOf(0));
        purchaseOrder.setPurchaseOrderBuyer(purchaseOrderDTO.getPurchaseOrderBuyer());
        purchaseOrder.setPurchaseOrderSeller(purchaseOrderDTO.getPurchaseOrderSeller());
        purchaseOrder.setLogisticsIsAccept(purchaseOrderDTO.getLogisticsIsAccept());
        purchaseOrder.setPurchaseOrderFullAddress(purchaseOrderDTO.getPurchaseOrderFullAddress());
        purchaseOrder.setPurchaseOrderMobile(purchaseOrderDTO.getPurchaseOrderMobile());
        purchaseOrder.setPurchaseOrderFullname(purchaseOrderDTO.getPurchaseOrderFullname());
        purchaseOrder.setPurchaseOrderSn(purchaseOrderDTO.getPurchaseOrderSn());
        purchaseOrder.setPurchaseOrderLogisticsName(purchaseOrderDTO.getPurchaseOrderLogisticsName());
        purchaseOrder.setPurchaseOrderWaybillCode(purchaseOrderDTO.getPurchaseOrderWaybillCode());
        purchaseOrder.setStatus(StatusConst.normal);
        purchaseOrder.setGmtCreate(new Date());
        purchaseOrder.setGmtModified(new Date());
        return purchaseOrder;
    }

    private List<PurchaseOrderItem> buildPurchaseOrderItemsByPurchaseOrderDTO(PurchaseOrder purchaseOrder, PurchaseOrderDTO purchaseOrderDTO, String purOrderId) {
        List<PurchaseOrderItem> items = new ArrayList<>();
        for (PurchaseOrderItemDTO itemDTO: purchaseOrderDTO.getItems()) {
            PurchaseOrderItem item = new PurchaseOrderItem();
            item.setPurOrderId(purOrderId);
            item.setPurchaseOrderId(purchaseOrder.getPurchaseOrderId());
            item.setShopId(purchaseOrder.getShopId());
            item.setOrderId(Long.valueOf(purchaseOrderDTO.getPlatformOrderId()));
            item.setPurchaseNum(itemDTO.getPurchaseNum());
            item.setSkuId(itemDTO.getSkuId());
            item.setSubItemId(itemDTO.getSubItemId() == null ? "" : itemDTO.getSubItemId());
            item.setWareId(itemDTO.getWareId());
            item.setPurchaseUrl(itemDTO.getPurchaseUrl() == null ? "" : itemDTO.getPurchaseUrl());
            item.setPurchasePrice(BigDecimal.valueOf(0));
            item.setStatus(StatusConst.normal);
            item.setGmtCreate(new Date());
            item.setGmtModified(new Date());
            items.add(item);
        }
        return items;
    }

    private Map<String, Map<Long, String>> getSkuAndProductOfSourceMap(List<Long> productIds) {
        List<Long> hadGetProductIds = new ArrayList<>();
        Map<Long, String> skuIdAndOutSkuIdMap = new HashMap<>();
        Map<Long, String> productIdAndOutProductIdMap = new HashMap<>();
        for (Long productId: productIds) {
            if (hadGetProductIds.contains(productId)) {
                continue;
            }
            SupplyCenterCargoDetailParam supplyCenterCargoDetailParam = new SupplyCenterCargoDetailParam();
            supplyCenterCargoDetailParam.setProductId(productId.toString());
            SupplyCenterCargoDetailData supplyCenterCargoDetailData = DDApi.supplyCenterCargoDetail(supplyCenterCargoDetailParam);
            productIdAndOutProductIdMap.put(productId, supplyCenterCargoDetailData.getOuterProductId());
            for (SpecPricesItem item: supplyCenterCargoDetailData.getSpecPrices()) {
                skuIdAndOutSkuIdMap.put(item.getSkuId(), item.getOuterSkuId());
            }
            hadGetProductIds.add(productId);
        }
        Map<String, Map<Long, String>> result = new HashMap<>();
        result.put("skuIdAndOutSkuIdMap", skuIdAndOutSkuIdMap);
        result.put("productIdAndOutProductIdMap", productIdAndOutProductIdMap);
        return result;
    }

    private Map<Long, SourceProductInfo> getProductIdAndSourceProductInfoMap(Long shopId, Map<Long, String> productIdAndOutProductIdMap) {
        List<String> sourceItemIds = new ArrayList<>(productIdAndOutProductIdMap.values());
        GetSourceItemInfosResponseDTO sourceItemInfosResp = dsApiService.getSourceItemInfos(shopId, sourceItemIds);
        if (!sourceItemInfosResp.isSuccess()) {
            throw new RuntimeException(sourceItemInfosResp.getReason());
        }
        System.out.println("sourceItemInfosResp: " + sourceItemInfosResp);
        List<String> errorList = new ArrayList<>();
        for (Map.Entry<String, CommonResponseDTO> entry: sourceItemInfosResp.getSourceItemIdAndProductApiRetMap().entrySet()) {
            if (!entry.getValue().isSuccess()) {
                errorList.add(entry.getValue().getReason());
            }
        }
        if (!errorList.isEmpty()) {
            throw new RuntimeException(String.join(" / ", errorList));
        }

        Map<Long, SourceProductInfo> productIdAndSourceProductInfoMap = new HashMap<>();
        for (Map.Entry<Long, String> entry : productIdAndOutProductIdMap.entrySet()) {
            SourceProductInfo sourceProductInfo = sourceItemInfosResp.getSourceItemIdAndProductInfoMap().get(entry.getValue());
            productIdAndSourceProductInfoMap.put(entry.getKey(), sourceProductInfo);
        }
        return productIdAndSourceProductInfoMap;
    }

    private OrderResult buildOrderResult(PurchaseOrderDTO purchaseOrder, Map<String, String> orderIdAndPurOrderIdMap, Map<Long, String> skuIdAndPurSkuOrderIdMap) {
        OrderResult orderResult = new OrderResult();
        orderResult.setOutPreOrderId(""); // TODO 无此参数
        orderResult.setPurOrderId(orderIdAndPurOrderIdMap.get(purchaseOrder.getPlatformOrderId()));
        orderResult.setSupplierOrderId(purchaseOrder.getPurchaseOrderSn());

        OrderResult.SupplierOrderUrl supplierOrderUrl = new OrderResult.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", purchaseOrder.getPurchaseOrderSn());
        supplierOrderUrl.setH5Url(url);
        supplierOrderUrl.setPcUrl(url);
        orderResult.setSupplierOrderUrl(supplierOrderUrl);

        List<OrderResult.SkuOrderResult> skuOrderResults = new ArrayList<>();
        for (PurchaseOrderItemDTO item: purchaseOrder.getItems()) {
            OrderResult.SkuOrderResult skuOrderResult = new OrderResult.SkuOrderResult();
            skuOrderResult.setPurSkuOrderId(skuIdAndPurSkuOrderIdMap.get(item.getSkuId()));
            skuOrderResult.setSupplierSkuOrderId(item.getSubItemId() == null ? "" : item.getSubItemId());
            skuOrderResults.add(skuOrderResult);
        }
        orderResult.setSkuOrderResults(skuOrderResults);
        return orderResult;
    }

    private void storeCreateOrders(Long shopId, List<CreateOrder> orders, Set<String> purOrderIds) {
        List<PlatformPurchaseOrder> existsPlatformPurchaseOrders = platformPurchaseOrderMapper.getListByPurOrderIds(new ArrayList<>(purOrderIds));
        Set<String> existsPurOrderIds = existsPlatformPurchaseOrders.stream().map(PlatformPurchaseOrder::getPurOrderId).collect(Collectors.toSet());

        TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
        try {
            for (CreateOrder order: orders) {
                if (existsPurOrderIds.contains(order.getPurOrderId())) {
                    continue;
                }
                savePlatformPurchaseOrder(shopId, order);
                savePlatformPurchaseOrderAddress(shopId, order.getPurOrderId(), order.getPostAddress());
                savePlatformPurchaseOrderMaskAddress(shopId, order.getPurOrderId(), order.getMaskPostAddress());
                savePlatformPurchaseOrderSku(shopId, order.getPurOrderId(), order.getSkuOrders());
            }
            dataSourceTransactionManager.commit(transactionStatus);
        } catch (Throwable e) {
            log.error("storeCreateOrders", e);
            dataSourceTransactionManager.rollback(transactionStatus);
            throw new RuntimeException("数据保存异常:" + e.getMessage());
        }
    }

    private PlatformPurchaseOrder savePlatformPurchaseOrder(Long shopId, CreateOrder order) {
        PlatformPurchaseOrder platformPurchaseOrder = new PlatformPurchaseOrder();
        platformPurchaseOrder.setPurOrderId(order.getPurOrderId());
        platformPurchaseOrder.setOrderId(order.getOrderId());
        platformPurchaseOrder.setShopId(shopId);
        platformPurchaseOrder.setPurchaseStatus(PurchaseOrderConst.PURCHASE_ORDER_STATUS_WAIT_PAY);
        platformPurchaseOrder.setStatus(StatusConst.normal);
        platformPurchaseOrder.setGmtModified(new Date());
        platformPurchaseOrder.setGmtModified(new Date());
        platformPurchaseOrderMapper.insertSelective(platformPurchaseOrder);
        return platformPurchaseOrder;
    }

    private List<PlatformPurchaseOrderSku> savePlatformPurchaseOrderSku(Long shopId, String purOrderId, List<SkuOrder> skuOrders) {
        if (skuOrders.isEmpty()) {
            return new ArrayList<>();
        }
        List<PlatformPurchaseOrderSku> platformPurchaseOrderSkus = new ArrayList<>();
        for (SkuOrder skuOrder: skuOrders) {
            PlatformPurchaseOrderSku platformPurchaseOrderSku = new PlatformPurchaseOrderSku();
            platformPurchaseOrderSku.setPurOrderId(purOrderId);
            platformPurchaseOrderSku.setShopId(shopId);
            platformPurchaseOrderSku.setPurSkuOrderId(skuOrder.getPurSkuOrderId());
            platformPurchaseOrderSku.setOuterSkuId(skuOrder.getOuterSkuId());
            platformPurchaseOrderSku.setOuterProductId(skuOrder.getOuterProductId());
            platformPurchaseOrderSku.setSkuOrderId(skuOrder.getSkuOrderId());
            platformPurchaseOrderSku.setSkuId(skuOrder.getSkuId());
            platformPurchaseOrderSku.setProductId(skuOrder.getProductId());
            platformPurchaseOrderSku.setCargoId(skuOrder.getCargoId());
            platformPurchaseOrderSku.setCargoSkuId(skuOrder.getCargoSkuId());
            platformPurchaseOrderSku.setNum(skuOrder.getNum());
            platformPurchaseOrderSku.setGmtModified(new Date());
            platformPurchaseOrderSku.setGmtCreate(new Date());
            platformPurchaseOrderSkus.add(platformPurchaseOrderSku);
        }
        System.out.println("purchaseOrderSkus: " + platformPurchaseOrderSkus);
        platformPurchaseOrderSkuMapper.insertBatch(platformPurchaseOrderSkus);
        return platformPurchaseOrderSkus;
    }

    private PlatformPurchaseOrderAddress savePlatformPurchaseOrderAddress(Long shopId, String purOrderId, Address address) {
        PlatformPurchaseOrderAddress platformPurchaseOrderAddress = new PlatformPurchaseOrderAddress();
        platformPurchaseOrderAddress.setPurOrderId(purOrderId);
        platformPurchaseOrderAddress.setShopId(shopId);
        platformPurchaseOrderAddress.setProvinceId(address.getProvince().getId());
        platformPurchaseOrderAddress.setProvinceName(address.getProvince().getName());
        platformPurchaseOrderAddress.setCityId(address.getCity().getId());
        platformPurchaseOrderAddress.setCityName(address.getCity().getName());
        platformPurchaseOrderAddress.setTownId(address.getTown().getId());
        platformPurchaseOrderAddress.setTownName(address.getTown().getName());
        platformPurchaseOrderAddress.setEncryptDetail(address.getEncryptDetail());
        platformPurchaseOrderAddress.setPostReceiver(address.getPostReceiver());
        platformPurchaseOrderAddress.setPostTel(address.getPostTel());
        platformPurchaseOrderAddress.setGmtCreate(new Date());
        platformPurchaseOrderAddress.setGmtModified(new Date());
        platformPurchaseOrderAddressMapper.insertSelective(platformPurchaseOrderAddress);
        return platformPurchaseOrderAddress;
    }

    private PlatformPurchaseOrderMaskAddress savePlatformPurchaseOrderMaskAddress(Long shopId, String purOrderId, Address address) {
        PlatformPurchaseOrderMaskAddress platformPurchaseOrderMaskAddress = new PlatformPurchaseOrderMaskAddress();
        platformPurchaseOrderMaskAddress.setPurOrderId(purOrderId);
        platformPurchaseOrderMaskAddress.setShopId(shopId);
        platformPurchaseOrderMaskAddress.setProvinceId(address.getProvince().getId());
        platformPurchaseOrderMaskAddress.setProvinceName(address.getProvince().getName());
        platformPurchaseOrderMaskAddress.setCityId(address.getCity().getId());
        platformPurchaseOrderMaskAddress.setCityName(address.getCity().getName());
        platformPurchaseOrderMaskAddress.setTownId(address.getTown().getId());
        platformPurchaseOrderMaskAddress.setTownName(address.getTown().getName());
        platformPurchaseOrderMaskAddress.setDetail(address.getDetail());
        platformPurchaseOrderMaskAddress.setPostReceiver(address.getPostReceiver());
        platformPurchaseOrderMaskAddress.setPostTel(address.getPostTel());
        platformPurchaseOrderMaskAddress.setGmtCreate(new Date());
        platformPurchaseOrderMaskAddress.setGmtModified(new Date());
        platformPurchaseOrderMaskAddressMapper.insertSelective(platformPurchaseOrderMaskAddress);
        return platformPurchaseOrderMaskAddress;
    }

    private ConsigneeInfoDTO buildConsigneeInfoDTO(Address address) {
        ConsigneeInfoDTO consigneeInfo = new ConsigneeInfoDTO();
        consigneeInfo.setAddress(address.getDetail());
        consigneeInfo.setProvince(address.getProvince().getName());
        consigneeInfo.setProvinceAreaId(address.getProvince().getId());
        consigneeInfo.setCity(address.getCity().getName());
        consigneeInfo.setCityAreaId(address.getCity().getId());
        consigneeInfo.setCounty(address.getTown().getName());
        consigneeInfo.setCountyAreaId(address.getTown().getId());
        consigneeInfo.setTown(address.getStreet().getName());
        consigneeInfo.setTownAreaId(address.getStreet().getId());
        consigneeInfo.setFullname(address.getPostReceiver());
        consigneeInfo.setMobile(address.getPostTel());

        String fullAddress = String.format("%s%s%s%s%s", consigneeInfo.getProvince(), consigneeInfo.getCity(), consigneeInfo.getCounty(), consigneeInfo.getTown(), consigneeInfo.getAddress());
        consigneeInfo.setFullAddress(fullAddress);
        return consigneeInfo;
    }

    private EncryptOutOrderInfoDTO buildEncryptOutOrderInfoDTO(String orderId, Address address) {
        EncryptOutOrderInfoDTO encryptOutOrderInfo = new EncryptOutOrderInfoDTO();
        encryptOutOrderInfo.setEncryptOrder(true);
        encryptOutOrderInfo.setOutPlatformOrderNo(orderId);
        encryptOutOrderInfo.setOutPlatformCode("douyin");
        encryptOutOrderInfo.setEncryptReceiverName(address.getEncryptPostReceiver());
        encryptOutOrderInfo.setEncryptReceiverMobile(address.getEncryptPostTel());
        encryptOutOrderInfo.setEncryptReceiverAddress(address.getEncryptDetail());
        return encryptOutOrderInfo;
    }

    private PlatformOrderDTO buildPlatformOrderDTO(Long shopId, CreateOrder order, Map<Long, SourceProductInfo> productIdAndSourceProductInfoMap, Map<Long, String> skuIdAndOutSkuIdMap) {
        ConsigneeInfoDTO consigneeInfo = buildConsigneeInfoDTO(order.getMaskPostAddress());
        EncryptOutOrderInfoDTO encryptOutOrderInfo = buildEncryptOutOrderInfoDTO(order.getOrderId(), order.getPostAddress());
        List<PlatformOrderItemDTO> items = new ArrayList<>();
        for (SkuOrder skuOrder: order.getSkuOrders()) {
            PlatformOrderItemDTO item = buildPlatformOrderItemDTO(order.getOrderId(), skuOrder, productIdAndSourceProductInfoMap, skuIdAndOutSkuIdMap);
            items.add(item);
        }

        PlatformOrderDTO platformOrder = new PlatformOrderDTO();
        platformOrder.setPlatformOrderId(order.getOrderId());
        platformOrder.setShopId(shopId.toString());
        platformOrder.setSourceOrderBuyerRemark("");
        platformOrder.setSourceOrderSellerMemo("");
        platformOrder.setBuyerRemark("");
        platformOrder.setUserId(SecurityTool.encodeByAES(String.valueOf(shopId)));
        platformOrder.setConsigneeInfo(consigneeInfo);
        platformOrder.setEncryptOutOrderInfo(encryptOutOrderInfo);
        platformOrder.setItems(items);
        return platformOrder;
    }

    private SourceSkuInfo getSourceSkuInfo(SkuOrder skuOrder, Map<Long, SourceProductInfo> productIdAndSourceProductInfoMap, Map<Long, String> skuIdAndOutSkuIdMap) {
        SourceProductInfo sourceProductInfo = productIdAndSourceProductInfoMap.get(skuOrder.getProductId());
        if (sourceProductInfo == null) {
            throw new RuntimeException("未匹配到货源商品");
        }
        SourceSkuInfo sourceSkuInfo = null;
        String sourceSkuId = skuIdAndOutSkuIdMap.get(skuOrder.getSkuId());
        if (sourceSkuId == null) {
            throw new RuntimeException("未匹配到货源SKU");
        }
        for (SourceSkuInfo sku: sourceProductInfo.getSkus()) {
            if (Objects.equals(sku.getSourceSkuId(), Long.valueOf(sourceSkuId))) {
                sourceSkuInfo = sku;
            }
        }
        return sourceSkuInfo;
    }

    private PlatformOrderItemDTO buildPlatformOrderItemDTO(String orderId, SkuOrder skuOrder, Map<Long, SourceProductInfo> productIdAndSourceProductInfoMap, Map<Long, String> skuIdAndOutSkuIdMap) {
        SourceSkuInfo sourceSkuInfo = getSourceSkuInfo(skuOrder, productIdAndSourceProductInfoMap, skuIdAndOutSkuIdMap);
        if (sourceSkuInfo == null) {
            throw new RuntimeException("未匹配到货源SKU");
        }
        boolean isJxhyOffer= sourceSkuInfo.getIsJxhyOffer().equals(1);

        PlatformOrderItemDTO item = new PlatformOrderItemDTO();
        item.setItemTotal(skuOrder.getNum().intValue());
        item.setSourceSkuId(sourceSkuInfo.getSourceSkuId());
        item.setSourceItemId(sourceSkuInfo.getSourceItemId().toString());
        item.setPlatformItemId(String.valueOf(skuOrder.getProductId()));
        item.setPlatformSkuId(skuOrder.getSkuId());
        item.setPlatformOrderId(orderId);
        item.setPlatformSkuSubName(sourceSkuInfo.getSkuSubName());
        item.setSpecId(sourceSkuInfo.getSpecId());
        item.setIsJxhyOffer(isJxhyOffer);
        item.setJxhyPrice(sourceSkuInfo.getJxhyPrice());
        return item;
    }

    private BatchCreateDistributionOrdersRequestDTO buildBatchCreateDistributionOrdersRequestDTO(BatchCreateParam param) {
        Map<Long, String> productIdAndOutProductIdMap = new HashMap<>();
        Map<Long, String> skuIdAndOutSkuIdMap = new HashMap<>();
        for (CreateOrder order: param.getOrders()) {
            for (SkuOrder skuOrder: order.getSkuOrders()) {
                productIdAndOutProductIdMap.put(skuOrder.getProductId(), skuOrder.getOuterProductId());
                skuIdAndOutSkuIdMap.put(skuOrder.getSkuId(), skuOrder.getOuterSkuId());
            }
        }

        Map<Long, SourceProductInfo> productIdAndSourceProductInfoMap = getProductIdAndSourceProductInfoMap(param.getShopId(), productIdAndOutProductIdMap);

        BatchCreateDistributionOrdersRequestDTO request = new BatchCreateDistributionOrdersRequestDTO();
        List<PlatformOrderDTO> platformOrders = new ArrayList<>();
        for (CreateOrder order: param.getOrders()) {
            PlatformOrderDTO platformOrder = buildPlatformOrderDTO(param.getShopId(), order, productIdAndSourceProductInfoMap, skuIdAndOutSkuIdMap);
            platformOrders.add(platformOrder);
        }
        request.setPlatformOrders(platformOrders);
        request.setPlatform(CommonConst.PLATFORM);
        request.setActionSource(DsOrderConst.ACTION_SOURCE_BATCH_PURCHASE);
        request.setPurchaseSource(DsOrderConst.PURCHASE_SOURCE_PLATFORM_BATCH);
        request.setIsAutoPay(0);
        request.setRepurchase(false);
        return request;
    }

    @Override
    public void batchPay(BatchPayParam param, BatchPayData data) {
        if (param.getParams().size() != 1) {
            throw new RuntimeException("每次只能请求1个采购单");
        }

        String purOrderId = param.getParams().get(0).getPurOrderId();
        PlatformPurchaseOrder platformPurchaseOrder = platformPurchaseOrderMapper.selectByPrimaryKey(param.getParams().get(0).getPurOrderId());
        if (platformPurchaseOrder == null) {
            throw new RuntimeException("采购单不存在");
        }

        PurchaseOrder purchaseOrder = purchaseOrderMapper.getByPurOrderId(purOrderId);

        List<PaymentResult> paymentResults = new ArrayList<>();
        for (BatchPayParam.Param p: param.getParams()) {
            List<String> sourceOrderIds = Collections.singletonList(purchaseOrder.getPurchaseOrderSn());
            GetPurchaseOrderPayUrlResponseDTO response1 = dsApiService.getPurchaseOrderPayUrl(p.getShopId(), sourceOrderIds, "PC");
            GetPurchaseOrderPayUrlResponseDTO response2 = dsApiService.getPurchaseOrderPayUrl(p.getShopId(), sourceOrderIds, "WIRELESS");
            if (!response1.isSuccess()) {
                throw new RuntimeException(response1.getReason());
            }
            if (!response2.isSuccess()) {
                throw new RuntimeException(response2.getReason());
            }
            PaymentResult paymentResult = new PaymentResult();
            PaymentResult.PayUrl payUrl = new PaymentResult.PayUrl();

            payUrl.setPcUrl(response1.getPayUrl());
            payUrl.setH5Url(response2.getPayUrl());

            paymentResult.setPayUrl(payUrl);
            paymentResult.setPurOrderId(p.getPurOrderId());
            paymentResults.add(paymentResult);

            platformPurchaseOrder.setPayPcUrl(response1.getPayUrl());
            platformPurchaseOrder.setPayH5Url(response2.getPayUrl());
            platformPurchaseOrderMapper.updateByPrimaryKeySelective(platformPurchaseOrder);
        }
        data.setPaymentResults(paymentResults);
    }

    public String generateOrderId(String type) {
        Date date = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddhhmm00");
        String dateKey = dateFormat.format(date);
        String key = type + ":" + dateKey;
        Long value = redisTemplate.opsForValue().increment(key, 1);
        redisTemplate.expire(key, 1, TimeUnit.MINUTES);
        SimpleDateFormat dateFormat1 = new SimpleDateFormat("yyyyMMddhhmmss");
        return dateFormat1.format(date) + String.format("%1$04d", value);
    }
}
