package org.ta.pddserver.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.ta.pddserver.config.PddAPIConfig;
import org.ta.pddserver.entity.*;
import org.ta.pddserver.model.api.response.CollectOrderResponse;
import org.ta.pddserver.model.enums.IdentityErrorType;
import org.ta.pddserver.model.pddjy.request.JYBaseRequestModel;
import org.ta.pddserver.model.pddjy.request.*;
import org.ta.pddserver.model.pddlg.common.TraceObject;
import org.ta.pddserver.model.pddlg.request.LGBaseModel;
import org.ta.pddserver.model.pddlg.request.PddLogisticsCoTrackQueryRequest;
import org.ta.pddserver.model.pddlg.request.PddLogisticsCoTrackSubRequest;
import org.ta.pddserver.service.impl.*;
import org.ta.pddserver.utils.JsonResponse;
import org.ta.pddserver.utils.PddJYPriceTool;
import org.ta.pddserver.utils.PddSignTool;
import org.ta.pddserver.utils.WorldexUtil;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@RestController
public class PddOpenController {

    @Resource
    private OrderCreateImpl orderCreateImpl;
    @Resource
    private OutboundNoticeImpl outboundNoticeImpl;
    @Resource
    private OrderUpdateImpl orderUpdateImpl;
    @Resource
    private ReverseNotifyImpl reverseNotifyImpl;
    @Resource
    private FeeQueryImpl feeQueryImpl;
    @Resource
    private OrderQueryImpl orderQueryImpl;
    @Resource
    private PackOrderQueryImpl packOrderQueryImpl;
    @Resource
    private ReturnOrderQueryImpl returnOrderQueryImpl;
    @Resource
    private PackageQueryImpl packageQueryImpl;
    @Resource
    private PackageNoticeImpl packageNoticeImpl;
    @Resource
    private UnpackNoticeImpl unpackNoticeImpl;
    @Resource
    private UserIdentifyImpl userIdentifyImpl;
    @Resource
    TraceObjectImpl traceObjectImpl;

    @Resource
    private LogOrderImpl orderImpl;
    @Resource
    private LogOrderBuyerDetailImpl orderBuyerDetailImpl;
    @Resource
    private LogOrderItemImpl orderItemImpl;
    @Resource
    private LogOrderMailDetailImpl orderMailDetailImpl;
    @Resource
    private LogOrderPaymentDetailImpl orderPaymentDetailImpl;

    @Resource
    CollectOrderImpl collectOrderImpl;
    @Resource
    CollectOrderLogisticsOrderCodeImpl collectOrderLogisticsOrderCodeImpl;
    @Resource
    CollectOrderSnImpl collectOrderSnImpl;
    @Resource
    CollectOrderDetailImpl collectOrderDetailImpl;
    @Resource
    CollectMailDetailImpl collectMailDetailImpl;
    @Resource
    CollectReceiverDetailImpl collectReceiverDetailImpl;
    @Resource
    CollectFreightFeeDetailImpl collectFreightFeeDetailImpl;
    @Resource
    CollectFreightFeeDetailDiscountDetailImpl collectFreightFeeDetailDiscountDetailImpl;
    @Resource
    CollectFreightFeeDetailFeeDetailImpl collectFreightFeeDetailFeeDetailImpl;

    @Resource
    ManufacturerImpl manufacturerImpl;

    @PostMapping("/pdd-open")
    public JSONObject pddOpenAPI(HttpServletRequest request,
                                 @RequestBody JYBaseRequestModel requestParam) {
        String pdd_sign = request.getHeader("pdd_sign");
        if (StringUtils.isEmpty(pdd_sign)) {
            log.error("pdd_sign is empty");
        }
        String body = getStringFromRequest(request);
        log.info("Request:\n{}", body);

        try {
            if (!PddSignTool.verifySignFromBody(body, "PddAPIConfig.CLIENT_SECRET", pdd_sign)) {
                log.error("验签失败");
            }
            switch (requestParam.getType()) {
                case "pdd.service.conso.order.create": {
                    PddServiceConsoOrderCreateRequest createParam = JSON.parseObject(body, PddServiceConsoOrderCreateRequest.class);
                    OrderCreate(createParam);
//                    log.info("pdd service conso.order.create 集运单创建接口");
                }
                break;
                case "pdd.service.conso.outbound.notice": {
                    PddServiceConsoOutboundNoticeRequest noticeParam = JSON.parseObject(body, PddServiceConsoOutboundNoticeRequest.class);
                    OutboundNotice(noticeParam);
//                    log.info("pdd.service.conso.outbound.notice 出库通知");
                }
                break;
                case "pdd.service.conso.order.update": {
                    PddServiceConsoOrderUpdateRequest updateRequest = JSON.parseObject(body, PddServiceConsoOrderUpdateRequest.class);
                    OrderUpdate(updateRequest);
//                    log.info("pdd.service.conso.order.update 集运单更新");
                }
                break;
                case "pdd.service.conso.reverse.notify": {
                    PddServiceConsoReverseNotifyRequest notifyRequest = JSON.parseObject(body, PddServiceConsoReverseNotifyRequest.class);
                    ReverseNotify(notifyRequest);
//                    log.info("pdd.service.conso.reverse.notify 逆向通知");
                    // todo 不需特殊回复，但是code区分状态码
                }
                break;
                case "pdd.service.conso.fee.query": {
                    PddServiceConsoFeeQueryRequest queryRequest = JSON.parseObject(body, PddServiceConsoFeeQueryRequest.class);
                    FeeQuery(queryRequest);
//                    log.info("pdd.service.conso.fee.query 集运费用查询");
                    long freightFee = 0L;
                    int rentFee = 0;
                    int weight = 0;
                    List<String> orderCodes = queryRequest.getLogisticsOrderCodes();
                    List<PddServiceConsoFeeQueryRequest.MailDetail> queryList = queryRequest.getMailDetails();
                    for (String orderCode : orderCodes) {
                        log.info("已合包，开始处理 {}", orderCode);
                        LogOrderEntity logOrderEntity = orderImpl.getByOrderCode(orderCode);
                        if (logOrderEntity.getStatus() >= 50) {
                            log.info("已合包，开始处理");
                            // 已合包
                            // 每个计算重量，每个计算运费
                            List<LogOrderMailDetailEntity> mailDetailEntityList = orderMailDetailImpl.getNewPackListByCode(orderCode);
                            for (LogOrderMailDetailEntity mailDetailEntity : mailDetailEntityList) {
                                int currWeight = PddJYPriceTool.calculateWeight(mailDetailEntity.getLength(),
                                        mailDetailEntity.getWidth(),
                                        mailDetailEntity.getHeight(),
                                        mailDetailEntity.getWeight(),
                                        "SENDTORECEVER".equals(queryRequest.getSegmentCode()));
                                long currFee = PddJYPriceTool.calculateFreightFee(currWeight,
                                        mailDetailEntity.getPackageType(),
                                        1,
                                        "SENDTORECEVER".equals(queryRequest.getSegmentCode())
                                );
                                log.info("mailNo:{} weight:{}, fee:{}", mailDetailEntity.getMailNo(), currWeight, currFee);
                                weight += currWeight;
                                freightFee += currFee;

                            }

                        } else {
                            // 不合包
                            // 按照所有包裹计算重量，计算运费
                            List<LogOrderMailDetailEntity> mailDetailEntityList = orderMailDetailImpl.getListByCode(orderCode);
                            for (LogOrderMailDetailEntity mailDetailEntity : mailDetailEntityList) {
                                for (PddServiceConsoFeeQueryRequest.MailDetail mailDetail : queryList) {
                                    if (mailDetail.getMailNo().equals(mailDetailEntity.getMailNo())) {
                                        log.info("mailNo:{} weight:{}", mailDetailEntity.getMailNo(), mailDetailEntity.getWeight());
                                        long currWeight = PddJYPriceTool.calculateWeight(mailDetailEntity.getLength(),
                                                mailDetailEntity.getWidth(),
                                                mailDetailEntity.getHeight(),
                                                mailDetailEntity.getWeight(),
                                                "SENDTORECEVER".equals(queryRequest.getSegmentCode()));
                                        log.info("mailNo:{} weight:{}, fee:{}", mailDetailEntity.getMailNo(), currWeight);
                                        weight += currWeight;
                                    }
                                }
                            }
                            freightFee = PddJYPriceTool.calculateFreightFee(weight,
                                    queryRequest.getGoodsType(),
                                    1,
                                    "SENDTORECEVER".equals(queryRequest.getSegmentCode())
                            );
                            log.info("weight:{}, fee:{}", weight, freightFee);

                        }
                    }

                    // 拆包之前的租金
                    for (PddServiceConsoFeeQueryRequest.MailDetail mailDetail : queryRequest.getMailDetails()) {
                        LogOrderMailDetailEntity mailDetailEntity = orderMailDetailImpl.getByMailNo(mailDetail.getMailNo());
                        rentFee += PddJYPriceTool.calculateRent(mailDetailEntity.getEnterTime(), "SENDTORECEVER".equals(queryRequest.getSegmentCode()));
                    }

                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("success", true);
                    jsonObject.put("freightFee", freightFee);
                    jsonObject.put("rentFee", rentFee);
                    jsonObject.put("weight", weight);
                    log.info("RESP:\n{}", jsonObject.toJSONString());
                    return jsonObject;
                }
                case "pdd.service.conso.order.query": {
                    PddServiceConsoOrderQueryRequest queryRequest = JSON.parseObject(body, PddServiceConsoOrderQueryRequest.class);
                    OrderQuery(queryRequest);
//                    log.info("pdd.service.conso.order.query 集运单查询");

                }
                break;
                case "pdd.service.conso.pack.order.query": {
                    PddServiceConsoPackOrderQueryRequest queryRequest = JSON.parseObject(body, PddServiceConsoPackOrderQueryRequest.class);
                    PackOrderQuery(queryRequest);
//                    log.info("pdd.service.conso.pack.order.query 集运合包单状态查询接口");
                }
                break;
                case "pdd.service.conso.return.order.query": {
                    PddServiceConsoReturnOrderQueryRequest queryRequest = JSON.parseObject(body, PddServiceConsoReturnOrderQueryRequest.class);
                    ReturnOrderQuery(queryRequest);
//                    log.info("pdd.service.conso.return.order.query");
                }
                break;
                case "pdd.service.conso.package.query": {
                    PddServiceConsoPackageQueryRequest queryRequest = JSON.parseObject(body, PddServiceConsoPackageQueryRequest.class);
                    PackageQuery(queryRequest);
//                    log.info("pdd.service.conso.package.query");
                }
                break;
                case "pdd.service.conso.package.notice": {
                    PddServiceConsoPackageNoticeRequest noticeRequest = JSON.parseObject(body, PddServiceConsoPackageNoticeRequest.class);
                    PackageNotice(noticeRequest);
//                    log.info("pdd.service.conso.package.notice");
                }
                break;
                case "pdd.service.conso.unpack.notice": {
                    PddServiceConsoUnpackNoticeRequest noticeRequest = JSON.parseObject(body, PddServiceConsoUnpackNoticeRequest.class);
                    UnpackNotice(noticeRequest);
//                    log.info("pdd.service.conso.unpack.notice");
                }
                break;
                case "pdd.service.conso.user.identify": {
                    PddServiceConsoUserIdentifyRequest identifyRequest = JSON.parseObject(body, PddServiceConsoUserIdentifyRequest.class);
                    UserIdentify(identifyRequest);
                    log.info("pdd.service.conso.user.identify");
                    IdentityErrorType errorType = WorldexUtil.verifyIdentity(identifyRequest.getName(), identifyRequest.getMobileNo(), identifyRequest.getIdNumber());
                    if (!errorType.equals(IdentityErrorType.Correct)) {
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put("success", false);
                        jsonObject.put("code", errorType.getValue());
                        jsonObject.put("message", errorType.getDesc());
                        log.info("RESP:\n{}", jsonObject.toJSONString());
                        return jsonObject;
                    }

                }
                break;
                default: {
//                return JsonResponse.generateCommonFailedResponse(999, "UNKNOWN API");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
//        log.info("request_body = {}", JSON.toJSON(requestParam));
        JSONObject jsonObject = JsonResponse.generateOpenCommonSuccessResponse();
        log.info("RESP:\n{}", jsonObject.toJSONString());
        return jsonObject;
    }

    /**
     * 获取请求消息体文本
     *
     * @param request 请求
     * @return 消息体文本
     */
    private static String getStringFromRequest(HttpServletRequest request) {
        StringBuffer buffer = new StringBuffer();
        String line = null;
        try {
            BufferedReader reader = request.getReader();
            while ((line = reader.readLine()) != null) {
                buffer.append(line);
            }
        } catch (IOException e) {
            log.error(e.getMessage());
        }
        return buffer.toString();
    }

    @PostMapping("/pdd-lg")
    public JSONObject pddLogisticAPI(HttpServletRequest request,
                                     @RequestBody LGBaseModel requestParam) {
//        log.info("PDD pddLogisticAPI, type={}", requestParam.getType());
//        log.info("target_client_id = {}, client_id = {}, sign={}, timestamp = {}, type={}",
//                requestParam.getTarget_client_id(), requestParam.getClient_id(), requestParam.getSign(), requestParam.getTimestamp(), requestParam.getType()
//        );

        if (!PddSignTool.verifyLGSign(requestParam, PddAPIConfig.CLIENT_SECRET)) {
            log.error("验签失败");
        }
        String body = getStringFromRequest(request);
        log.info("Request:\n{}", body);

        switch (requestParam.getType()) {
            case "pdd.logistics.co.track.sub": {

                PddLogisticsCoTrackSubRequest subRequest = JSON.parseObject(body, PddLogisticsCoTrackSubRequest.class);
                subRequest.parseData();
                log.info("pdd.logistics.co.track.sub 拼多多向物流公司订阅指定运单号的物流轨迹详情，快递公司运单号：{}", subRequest.getDataObject().getTrackingOrderNo());
            }
            break;
            case "pdd.logistics.co.track.query": {
                PddLogisticsCoTrackQueryRequest subRequest = JSON.parseObject(body, PddLogisticsCoTrackQueryRequest.class);
                subRequest.parseData();
                log.info("pdd.logistics.co.track.query 拼多多向物流公司查询指定运单号当前的完整物流轨迹信息。快递公司运单号：{}", subRequest.getDataObject().getTrackingNumber());

                List<TraceObjectEntity> TraceObjectlist = traceObjectImpl.selectByTrackingNumber(subRequest.getDataObject().getTrackingNumber());
                List<TraceObject> list = new ArrayList<TraceObject>();

                for (TraceObjectEntity traceObjectEntity : TraceObjectlist) {
                    list.add(TraceObject.createFromTraceEntity(traceObjectEntity));
                }
                JSONObject jsonObject = JsonResponse.generateLGCommonSuccessResponse(requestParam.getShip_id(), list);
                log.info("RESP:\n{}", jsonObject.toJSONString());
                return jsonObject;
            }
            default: {
                log.error("未知请求");
                return JsonResponse.generateLGCommonFailedResponse(requestParam.getShip_id(), "999", "UNKNOWN API");
            }
        }

        return JsonResponse.generateLGCommonSuccessResponse(requestParam.getShip_id(), null);
    }

    public void OrderCreate(PddServiceConsoOrderCreateRequest createParam) {
        OrderCreateEntity orderCreateEntity = new OrderCreateEntity();
        orderCreateEntity.setProviderCode(createParam.getProviderCode());
        orderCreateEntity.setConsoWarehouseCode(createParam.getConsoWarehouseCode());
        orderCreateEntity.setLogisticsOrderCode(createParam.getLogisticsOrderCode());
        orderCreateEntity.setBizType(createParam.getBizType());
        orderCreateEntity.setConsoType(createParam.getConsoType());
        orderCreateEntity.setBuyerCode(createParam.getBuyerCode());
        orderCreateEntity.setDereRecogCode(createParam.getDereRecogCode());
        orderCreateEntity.setPackageQuantity(createParam.getPackageQuantity());
        orderCreateEntity.setMailDetails(JSONObject.toJSONString(createParam.getMailDetails()));
        orderCreateEntity.setItems(JSONObject.toJSONString(createParam.getItems()));
        orderCreateEntity.setBuyerDetail(JSONObject.toJSONString(createParam.getBuyerDetail()));
        orderCreateEntity.setPaymentDetail(JSONObject.toJSONString(createParam.getPaymentDetail()));
        orderCreateEntity.setTags(JSONObject.toJSONString(createParam.getTags()));
        orderCreateImpl.save(orderCreateEntity);

        LogOrderEntity orderEntity = new LogOrderEntity();
        orderEntity.setUid(orderCreateEntity.getUid());
        orderEntity.setCreated(orderCreateEntity.getCreated());
        orderEntity.setUpdated(orderCreateEntity.getUpdated());
        orderEntity.setStatus(orderCreateEntity.getStatus());
        orderEntity.setState(orderCreateEntity.getState());
        orderEntity.setProviderCode(orderCreateEntity.getProviderCode());
        orderEntity.setConsoWarehouseCode(orderCreateEntity.getConsoWarehouseCode());
        orderEntity.setLogisticsOrderCode(orderCreateEntity.getLogisticsOrderCode());
        orderEntity.setBizType(orderCreateEntity.getBizType());
        orderEntity.setConsoType(orderCreateEntity.getConsoType());
        orderEntity.setBuyerCode(orderCreateEntity.getBuyerCode());
        orderEntity.setDereRecogCode(orderCreateEntity.getDereRecogCode());
        orderEntity.setPackageQuantity(orderCreateEntity.getPackageQuantity());
        orderImpl.save(orderEntity);

        LogOrderBuyerDetailEntity orderBuyerDetailEntity = new LogOrderBuyerDetailEntity();
        orderBuyerDetailEntity.setLogisticsOrderCode(orderCreateEntity.getLogisticsOrderCode());
        orderBuyerDetailEntity.setName(createParam.getBuyerDetail().getName());
        orderBuyerDetailEntity.setTelePhone(createParam.getBuyerDetail().getTelePhone());
        orderBuyerDetailEntity.setCountry(createParam.getBuyerDetail().getCountry());
        orderBuyerDetailEntity.setProvince(createParam.getBuyerDetail().getProvince());
        orderBuyerDetailEntity.setCity(createParam.getBuyerDetail().getCity());
        orderBuyerDetailEntity.setDistrict(createParam.getBuyerDetail().getDistrict());
        orderBuyerDetailEntity.setDetailAddress(createParam.getBuyerDetail().getDetailAddress());
        orderBuyerDetailEntity.setPostCode(createParam.getBuyerDetail().getPostCode());
        orderBuyerDetailImpl.save(orderBuyerDetailEntity);

        for (PddServiceConsoOrderCreateRequest.Item item : createParam.getItems()) {
            LogOrderItemEntity orderItemEntity = new LogOrderItemEntity();
            orderItemEntity.setLogisticsOrderCode(orderCreateEntity.getLogisticsOrderCode());
            orderItemEntity.setItemId(item.getItemId());
            orderItemEntity.setItemName(item.getItemName());
            orderItemEntity.setCategoryId(item.getCategoryId());
            orderItemEntity.setCategoryName(item.getCategoryName());
            orderItemEntity.setTotalActualPayment(item.getTotalActualPayment());
            orderItemEntity.setCurrencyUnit(item.getCurrencyUnit());
            orderItemEntity.setCurrency(item.getCurrency());
            orderItemEntity.setItemQuantity(item.getItemQuantity());
            orderItemEntity.setItemPicUrl(item.getItemPicUrl());
            orderItemEntity.setItemSkuProperty(item.getItemSkuProperty());
            orderItemEntity.setChargedStatus(item.getChargedStatus());
            orderItemEntity.setGoodsType(item.getGoodsType());
            orderItemEntity.setMagneticStatus(item.getMagneticStatus());
            orderItemImpl.save(orderItemEntity);
        }

        for (PddServiceConsoOrderCreateRequest.MailDetail mailDetail : createParam.getMailDetails()) {
            LogOrderMailDetailEntity orderMailDetail = new LogOrderMailDetailEntity();
            orderMailDetail.setLogisticsOrderCode(orderCreateEntity.getLogisticsOrderCode());
            orderMailDetail.setExpressCode(mailDetail.getExpressCode());
            orderMailDetail.setMailNo(mailDetail.getMailNo());
            orderMailDetailImpl.save(orderMailDetail);
        }

        LogOrderPaymentDetailEntity orderPaymentDetailEntity = new LogOrderPaymentDetailEntity();
        orderPaymentDetailEntity.setLogisticsOrderCode(orderCreateEntity.getLogisticsOrderCode());
        orderPaymentDetailEntity.setTradeOrderSn(createParam.getPaymentDetail().getTradeOrderSn());
        orderPaymentDetailEntity.setTradeOrderValue(createParam.getPaymentDetail().getTradeOrderValue());
        orderPaymentDetailEntity.setTradeOrderActualAmount(createParam.getPaymentDetail().getTradeOrderActualAmount());
        orderPaymentDetailEntity.setCurrencyUnit(createParam.getPaymentDetail().getCurrencyUnit());
        orderPaymentDetailEntity.setCurrency(createParam.getPaymentDetail().getCurrency());
        orderPaymentDetailImpl.save(orderPaymentDetailEntity);

    }

    public void OutboundNotice(PddServiceConsoOutboundNoticeRequest noticeParam) {
        OutboundNoticeEntity outboundNoticeEntity = new OutboundNoticeEntity();
        outboundNoticeEntity.setProviderCode(noticeParam.getProviderCode());
        outboundNoticeEntity.setConsoWarehouseCode(noticeParam.getConsoWarehouseCode());
        outboundNoticeEntity.setOrderCode(noticeParam.getOrderCode());
        outboundNoticeEntity.setBuyerCode(noticeParam.getBuyerCode());
        outboundNoticeEntity.setLogisticsOrderCodes(JSONObject.toJSONString(noticeParam.getLogisticsOrderCodes()));
        outboundNoticeEntity.setOrderSns(JSONObject.toJSONString(noticeParam.getOrderSns()));
        outboundNoticeEntity.setOrderDetails(JSONObject.toJSONString(noticeParam.getOrderDetails()));
        outboundNoticeEntity.setTradeOrderActualAmountTotal(noticeParam.getTradeOrderActualAmountTotal());
        outboundNoticeEntity.setItemQuantityTotal(noticeParam.getItemQuantityTotal());
        outboundNoticeEntity.setSegmentCode(noticeParam.getSegmentCode());
        outboundNoticeEntity.setConsoType(noticeParam.getConsoType());
        outboundNoticeEntity.setDeliveryType(noticeParam.getDeliveryType());
        outboundNoticeEntity.setStationCode(noticeParam.getStationCode());
        outboundNoticeEntity.setMailDetails(JSONObject.toJSONString(noticeParam.getMailDetails()));
        outboundNoticeEntity.setReceiverDetail(JSONObject.toJSONString(noticeParam.getReceiverDetail()));
        outboundNoticeEntity.setFreightFeeDetail(JSONObject.toJSONString(noticeParam.getFreightFeeDetail()));
        outboundNoticeImpl.save(outboundNoticeEntity);

        // 合包单
        CollectOrderEntity collectOrderEntity = generateCollectOrder(noticeParam, outboundNoticeEntity);
        collectOrderImpl.save(collectOrderEntity);

        // 合包单集运单
        if (noticeParam.getLogisticsOrderCodes() != null && !noticeParam.getLogisticsOrderCodes().isEmpty()) {
            for (String logisticsOrderCode : noticeParam.getLogisticsOrderCodes()) {
                CollectOrderLogisticsOrderCodeEntity collectOrderLogisticsOrderCodeEntity = new CollectOrderLogisticsOrderCodeEntity();
                collectOrderLogisticsOrderCodeEntity.setLogisticsOrderCode(logisticsOrderCode);
                collectOrderLogisticsOrderCodeEntity.setOrderCode(collectOrderEntity.getOrderCode());
                collectOrderLogisticsOrderCodeImpl.save(collectOrderLogisticsOrderCodeEntity);
            }
        }

        // 合包单一段单号
        if (noticeParam.getOrderSns() != null && !noticeParam.getOrderSns().isEmpty()) {
            for (String orderSn : noticeParam.getOrderSns()) {
                CollectOrderSnEntity snEntity = new CollectOrderSnEntity();
                snEntity.setOrderSn(orderSn);
                snEntity.setOrderCode(collectOrderEntity.getOrderCode());
                collectOrderSnImpl.save(snEntity);
            }
        }

        // 一段订单详情列表
        if (noticeParam.getOrderDetails() != null && !noticeParam.getOrderDetails().isEmpty()) {
            for (PddServiceConsoOutboundNoticeRequest.OrderDetail orderDetail : noticeParam.getOrderDetails()) {
                CollectOrderDetailEntity orderDetailEntity = new CollectOrderDetailEntity();
                orderDetailEntity.setOrderCode(collectOrderEntity.getOrderCode());
                orderDetailEntity.setOrderSn(orderDetail.getOrderSn());
                orderDetailEntity.setLogisticsOrderCode(orderDetail.getLogisticsOrderCode());
                orderDetailEntity.setItemId(orderDetail.getItemId());
                orderDetailEntity.setItemName(orderDetail.getItemName());
                orderDetailEntity.setCategoryId(orderDetail.getCategoryId());
                orderDetailEntity.setCategoryName(orderDetail.getCategoryName());
                orderDetailEntity.setItemQuantity(orderDetail.getItemQuantity());
                orderDetailEntity.setWeightTotal(orderDetail.getWeightTotal());
                orderDetailEntity.setActualAmount(orderDetail.getActualAmount());
                orderDetailEntity.setProductName(orderDetail.getProductName());
                orderDetailEntity.setExportDecAmount(orderDetail.getExportDecAmount());

                // 生产销售企业
                if (orderDetail.getManufacturer() != null) {
                    ManufacturerEntity manufacturerEntity = new ManufacturerEntity();
                    manufacturerEntity.setProducerEnterpriseName(orderDetail.getManufacturer().getProducerEnterpriseName());
                    manufacturerEntity.setProducerEnterpriseCode(orderDetail.getManufacturer().getProducerEnterpriseCode());
                    manufacturerEntity.setProducerType(orderDetail.getManufacturer().getProducerType());
                    manufacturerImpl.save(manufacturerEntity);
                    orderDetailEntity.setManufacturerId(manufacturerEntity.getUid());
                }

                collectOrderDetailImpl.save(orderDetailEntity);
            }
        }


        // 运单详情
        if (noticeParam.getMailDetails() != null && !noticeParam.getMailDetails().isEmpty()) {
            for (PddServiceConsoOutboundNoticeRequest.MailDetail mailDetail : noticeParam.getMailDetails()) {
                CollectMailDetailEntity mailDetailEntity = new CollectMailDetailEntity();
                mailDetailEntity.setOrderCode(collectOrderEntity.getOrderCode());
                mailDetailEntity.setExpressCode(mailDetail.getExpressCode());
                mailDetailEntity.setMailNo(mailDetail.getMailNo());
                mailDetailEntity.setConsoWarehouseCode(mailDetail.getConsoWarehouseCode());
                collectMailDetailImpl.save(mailDetailEntity);
            }
        }

        // 收货人
        if (noticeParam.getReceiverDetail() != null) {
            CollectReceiverDetailEntity collectReceiverDetailEntity = generateCollectReceiverDetailEntity(noticeParam, collectOrderEntity);
            collectReceiverDetailImpl.save(collectReceiverDetailEntity);
        }

        // 运费详情
        PddServiceConsoOutboundNoticeRequest.FreightFeeDetail freightFeeDetail = noticeParam.getFreightFeeDetail();
        if (freightFeeDetail != null) {
            CollectFreightFeeDetailEntity collectFreightFeeDetailEntity = generateCollectFreightFeeDetailEntity(collectOrderEntity, freightFeeDetail);
            collectFreightFeeDetailImpl.save(collectFreightFeeDetailEntity);
            // 优惠详情
            if (freightFeeDetail.getDiscountDetails() != null && !freightFeeDetail.getDiscountDetails().isEmpty()) {
                for (PddServiceConsoOutboundNoticeRequest.FreightFeeDetail.DiscountDetail discountDetail : freightFeeDetail.getDiscountDetails()) {
                    CollectFreightFeeDetailDiscountDetailEntity detailDiscountDetailEntity = new CollectFreightFeeDetailDiscountDetailEntity();
                    detailDiscountDetailEntity.setOrderCode(collectOrderEntity.getOrderCode());
                    detailDiscountDetailEntity.setDiscountType(discountDetail.getDiscountType());
                    detailDiscountDetailEntity.setDiscountFee(discountDetail.getDiscountFee());
                    collectFreightFeeDetailDiscountDetailImpl.save(detailDiscountDetailEntity);
                }
            }
            // 费用详情
            if (freightFeeDetail.getFeeDetails() != null && !freightFeeDetail.getFeeDetails().isEmpty()) {
                for (PddServiceConsoOutboundNoticeRequest.FreightFeeDetail.FeeDetail feeDetail : freightFeeDetail.getFeeDetails()) {
                    CollectFreightFeeDetailFeeDetailEntity feeDetailFeeDetail = generateCollectFreightFeeDetailFeeDetailEntity(feeDetail, collectOrderEntity);
                    collectFreightFeeDetailFeeDetailImpl.save(feeDetailFeeDetail);
                }
            }
        }
    }

    private static CollectFreightFeeDetailFeeDetailEntity generateCollectFreightFeeDetailFeeDetailEntity(PddServiceConsoOutboundNoticeRequest.FreightFeeDetail.FeeDetail feeDetail, CollectOrderEntity collectOrderEntity) {
        CollectFreightFeeDetailFeeDetailEntity feeDetailFeeDetail = new CollectFreightFeeDetailFeeDetailEntity();
        feeDetailFeeDetail.setOrderCode(collectOrderEntity.getOrderCode());
        feeDetailFeeDetail.setScene(feeDetail.getScene());
        feeDetailFeeDetail.setType(feeDetail.getType());
        feeDetailFeeDetail.setAmount(feeDetail.getAmount());
        feeDetailFeeDetail.setCurrencyUnit(feeDetail.getCurrencyUnit());
        feeDetailFeeDetail.setCurrency(feeDetail.getCurrency());
        return feeDetailFeeDetail;
    }

    private static CollectFreightFeeDetailEntity generateCollectFreightFeeDetailEntity(CollectOrderEntity collectOrderEntity, PddServiceConsoOutboundNoticeRequest.FreightFeeDetail freightFeeDetail) {
        CollectFreightFeeDetailEntity collectFreightFeeDetailEntity = new CollectFreightFeeDetailEntity();
        collectFreightFeeDetailEntity.setOrderCode(collectOrderEntity.getOrderCode());
        collectFreightFeeDetailEntity.setPayOrderId(freightFeeDetail.getPayOrderId());
        collectFreightFeeDetailEntity.setPayTime(freightFeeDetail.getPayTime());
        collectFreightFeeDetailEntity.setWeight(freightFeeDetail.getWeight());
        collectFreightFeeDetailEntity.setFreightPrice(freightFeeDetail.getFreightPrice());
        collectFreightFeeDetailEntity.setFreightPackageType(freightFeeDetail.getFreightPackageType());
        collectFreightFeeDetailEntity.setGoodsType(freightFeeDetail.getGoodsType());
        collectFreightFeeDetailEntity.setCurrencyUnit(freightFeeDetail.getCurrencyUnit());
        collectFreightFeeDetailEntity.setCurrency(freightFeeDetail.getCurrency());
        collectFreightFeeDetailEntity.setDeclareAmount(freightFeeDetail.getDeclareAmount());
        collectFreightFeeDetailEntity.setDiscountFee(freightFeeDetail.getDiscountFee());
        return collectFreightFeeDetailEntity;
    }

    private static CollectReceiverDetailEntity generateCollectReceiverDetailEntity(PddServiceConsoOutboundNoticeRequest noticeParam, CollectOrderEntity collectOrderEntity) {
        CollectReceiverDetailEntity collectReceiverDetailEntity = new CollectReceiverDetailEntity();
        collectReceiverDetailEntity.setOrderCode(collectOrderEntity.getOrderCode());
        collectReceiverDetailEntity.setName(noticeParam.getReceiverDetail().getName());
        collectReceiverDetailEntity.setIdNumber(noticeParam.getReceiverDetail().getIdNumber());
        collectReceiverDetailEntity.setTelePhone(noticeParam.getReceiverDetail().getTelePhone());
        collectReceiverDetailEntity.setCountry(noticeParam.getReceiverDetail().getCountry());
        collectReceiverDetailEntity.setProvince(noticeParam.getReceiverDetail().getProvince());
        collectReceiverDetailEntity.setCity(noticeParam.getReceiverDetail().getCity());
        collectReceiverDetailEntity.setDistrict(noticeParam.getReceiverDetail().getDistrict());
        collectReceiverDetailEntity.setDetailAddress(noticeParam.getReceiverDetail().getDetailAddress());
        collectReceiverDetailEntity.setPostCode(noticeParam.getReceiverDetail().getPostCode());
        return collectReceiverDetailEntity;
    }

    private static CollectOrderEntity generateCollectOrder(PddServiceConsoOutboundNoticeRequest noticeParam, OutboundNoticeEntity outboundNoticeEntity) {
        CollectOrderEntity collectOrderEntity = new CollectOrderEntity();
        collectOrderEntity.setUid(outboundNoticeEntity.getUid());
        collectOrderEntity.setProviderCode(noticeParam.getProviderCode());
        collectOrderEntity.setConsoWarehouseCode(noticeParam.getConsoWarehouseCode());
        collectOrderEntity.setOrderCode(noticeParam.getOrderCode());
        collectOrderEntity.setBuyerCode(noticeParam.getBuyerCode());
        collectOrderEntity.setTradeOrderActualAmountTotal(noticeParam.getTradeOrderActualAmountTotal());
        collectOrderEntity.setItemQuantityTotal(noticeParam.getItemQuantityTotal());
        collectOrderEntity.setSegmentCode(noticeParam.getSegmentCode());
        collectOrderEntity.setConsoType(noticeParam.getConsoType());
        collectOrderEntity.setDeliveryType(noticeParam.getDeliveryType());
        collectOrderEntity.setStationCode(noticeParam.getStationCode());
        return collectOrderEntity;
    }

    public void OrderUpdate(PddServiceConsoOrderUpdateRequest updateRequest) {
        OrderUpdateEntity orderUpdateEntity = new OrderUpdateEntity();
        orderUpdateEntity.setProviderCode(updateRequest.getProviderCode());
        orderUpdateEntity.setConsoWarehouseCode(updateRequest.getConsoWarehouseCode());
        orderUpdateEntity.setLogisticsOrderCode(updateRequest.getLogisticsOrderCode());
        orderUpdateEntity.setPackageQuantity(updateRequest.getPackageQuantity());
        orderUpdateEntity.setMailDetails(JSONObject.toJSONString(updateRequest.getMailDetails()));
        orderUpdateEntity.setTags(JSONObject.toJSONString(updateRequest.getTags()));
        orderUpdateImpl.save(orderUpdateEntity);

        //根据集运单号更新包裹数量
        orderImpl.savePackageQuantity(orderUpdateEntity.getLogisticsOrderCode(), orderUpdateEntity.getPackageQuantity());

        //最新详情列表
        List<PddServiceConsoOrderUpdateRequest.MailDetail> listNew = updateRequest.getMailDetails();

        //根据集运单号获取运单详情列表
        List<LogOrderMailDetailEntity> list = orderMailDetailImpl.getListByCode(orderUpdateEntity.getLogisticsOrderCode());
        for (int i = 0; i < list.size(); i++) {
            LogOrderMailDetailEntity orderMailDetailEntity = list.get(i);
            for (int j = 0; j < listNew.size(); j++) {
                PddServiceConsoOrderUpdateRequest.MailDetail mailDetail = listNew.get(j);
                if (orderMailDetailEntity.getMailNo().equals(mailDetail.getMailNo())) {
                    //相同，删除
                    list.remove(i);
                    listNew.remove(j);
                    i -= 1;
                    break;
                }
            }
        }

        //判断是否有剩余
        for (PddServiceConsoOrderUpdateRequest.MailDetail mailDetail : listNew) {
            LogOrderMailDetailEntity orderMailDetailEntity = new LogOrderMailDetailEntity();
            orderMailDetailEntity.setLogisticsOrderCode(orderUpdateEntity.getLogisticsOrderCode());
            orderMailDetailEntity.setExpressCode(mailDetail.getExpressCode());
            orderMailDetailEntity.setMailNo(mailDetail.getMailNo());
            orderMailDetailImpl.save(orderMailDetailEntity);
        }

        for (LogOrderMailDetailEntity orderMailDetailEntity : list) {
            orderMailDetailImpl.removeById(orderMailDetailEntity.getUid());
        }

    }


    public void ReverseNotify(PddServiceConsoReverseNotifyRequest notifyRequest) {
        ReverseNotifyEntity reverseNotifyEntity = new ReverseNotifyEntity();
        reverseNotifyEntity.setProviderCode(notifyRequest.getProviderCode());
        reverseNotifyEntity.setConsoWarehouseCode(notifyRequest.getConsoWarehouseCode());
        reverseNotifyEntity.setOrderCode(notifyRequest.getOrderCode());
        reverseNotifyEntity.setOrderType(notifyRequest.getOrderType());
        reverseNotifyEntity.setStatus(notifyRequest.getStatus());

        reverseNotifyImpl.save(reverseNotifyEntity);
        String orderCode = notifyRequest.getOrderCode();
        if (notifyRequest.getType().toUpperCase().equals("HEBAO")) {
            CollectOrderResponse collectOrderEntity = collectOrderImpl.getByOrderCode(orderCode);
            if (collectOrderEntity != null) {
                if (notifyRequest.getStatus().toUpperCase().equals("CANCELOUTBOUND")) {
                    collectOrderImpl.updateOrderStatus(11, collectOrderEntity.getUid());
                }
            }
        } else if (notifyRequest.getType().toUpperCase().equals("JIYUN")) {
            LogOrderEntity logOrderEntity = orderImpl.getByOrderCode(orderCode);
            if (logOrderEntity != null) {
                if (notifyRequest.getStatus().toUpperCase().equals("REJECTSIGN")) {
                    orderImpl.updateOrderStatus(11, logOrderEntity.getUid());
                } else if (notifyRequest.getStatus().toUpperCase().equals("CANCELREJECTSIGN")) {
                    orderImpl.updateOrderStatus(21, logOrderEntity.getUid());
                } else if (notifyRequest.getStatus().toUpperCase().equals("ONLYREFUNDSUC")) {
                    orderImpl.updateOrderStatus(31, logOrderEntity.getUid());
                }
            }
        }
    }

    public void FeeQuery(PddServiceConsoFeeQueryRequest queryRequest) {
        FeeQueryEntity feeQueryEntity = new FeeQueryEntity();
        feeQueryEntity.setProviderCode(queryRequest.getProviderCode());
        feeQueryEntity.setConsoWarehouseCode(queryRequest.getConsoWarehouseCode());
        feeQueryEntity.setLogisticsPackOrderCode(queryRequest.getLogisticsPackOrderCode());
        feeQueryEntity.setLogisticsOrderCodes(JSONObject.toJSONString(queryRequest.getLogisticsOrderCodes()));
        feeQueryEntity.setBizType(queryRequest.getBizType());
        feeQueryEntity.setFreightPackageType(queryRequest.getFreightPackageType());
        feeQueryEntity.setGoodsType(queryRequest.getGoodsType());
        feeQueryEntity.setSegmentCode(queryRequest.getSegmentCode());
        feeQueryEntity.setDeliveryType(queryRequest.getDeliveryType());
        feeQueryEntity.setConsoType(queryRequest.getConsoType());
        feeQueryEntity.setMailDetails(JSONObject.toJSONString(queryRequest.getMailDetails()));
        feeQueryEntity.setReceiverDetail(JSONObject.toJSONString(queryRequest.getReceiverDetail()));
        feeQueryImpl.save(feeQueryEntity);
    }

    public void OrderQuery(PddServiceConsoOrderQueryRequest queryRequest) {
        OrderQueryEntity orderQueryEntity = new OrderQueryEntity();
        orderQueryEntity.setProviderCode(queryRequest.getProviderCode());
        orderQueryEntity.setLogisticsOrderCode(queryRequest.getLogisticsOrderCode());

        orderQueryImpl.save(orderQueryEntity);
    }

    public void PackOrderQuery(PddServiceConsoPackOrderQueryRequest queryRequest) {
        PackOrderQueryEntity packOrderQueryEntity = new PackOrderQueryEntity();
        packOrderQueryEntity.setProviderCode(queryRequest.getProviderCode());
        packOrderQueryEntity.setOrderCode(queryRequest.getOrderCode());

        packOrderQueryImpl.save(packOrderQueryEntity);
    }

    public void ReturnOrderQuery(PddServiceConsoReturnOrderQueryRequest queryRequest) {
        ReturnOrderQueryEntity returnOrderQueryEntity = new ReturnOrderQueryEntity();
        returnOrderQueryEntity.setProviderCode(queryRequest.getProviderCode());
        returnOrderQueryEntity.setOrderCode(queryRequest.getOrderCode());

        returnOrderQueryImpl.save(returnOrderQueryEntity);
    }

    public void PackageQuery(PddServiceConsoPackageQueryRequest queryRequest) {
        PackageQueryEntity packageQueryEntity = new PackageQueryEntity();
        packageQueryEntity.setOrderCode(queryRequest.getOrderCode());
        packageQueryEntity.setOrderCodeType(queryRequest.getOrderCodeType());
        packageQueryEntity.setProviderCode(queryRequest.getProviderCode());
        packageQueryEntity.setMailDetails(JSONObject.toJSONString(queryRequest.getMailDetails()));

        packageQueryImpl.save(packageQueryEntity);
    }

    public void PackageNotice(PddServiceConsoPackageNoticeRequest noticeRequest) {
        PackageNoticeEntity packageNoticeEntity = new PackageNoticeEntity();
        packageNoticeEntity.setOrderCode(noticeRequest.getOrderCode());
        packageNoticeEntity.setOrderCodeType(noticeRequest.getOrderCodeType());
        packageNoticeEntity.setProviderCode(noticeRequest.getProviderCode());
        packageNoticeEntity.setMailDetails(JSONObject.toJSONString(noticeRequest.getMailDetails()));

        packageNoticeImpl.save(packageNoticeEntity);
    }

    public void UnpackNotice(PddServiceConsoUnpackNoticeRequest noticeRequest) {
        CollectOrderResponse collectOrderEntity = collectOrderImpl.getByOrderCode(noticeRequest.getOrderCode());
        if (collectOrderEntity == null) {
            log.error("未找到合包单，单号：{}", noticeRequest.getOrderCode());
        } else {
            if (noticeRequest.getMailDetails() != null && noticeRequest.getMailDetails().size() > 0) {
                for (PddServiceConsoUnpackNoticeRequest.MailDetail mailDetail : noticeRequest.getMailDetails()) {
                    CollectMailDetailEntity collectMailDetailEntity = collectMailDetailImpl.getByOrderCodeAndMailNo(noticeRequest.getOrderCode(), mailDetail.getExpressCode(), mailDetail.getMailNo());
                    if (collectMailDetailEntity == null) {
                        log.error("合包单内包裹未找到，合包单号：{}， 快递公司：{}， 快递单号：{}", noticeRequest.getOrderCode(), mailDetail.getExpressCode(), mailDetail.getMailNo());
                        continue;
                    }
                    if (collectMailDetailEntity.getStatus() != 0) {
                        log.error("合包单内包裹状态异常，非默认初始状态，合包单号：{}， 快递公司：{}， 快递单号：{}， 当前状态：{}", noticeRequest.getOrderCode(), mailDetail.getExpressCode(), mailDetail.getMailNo(), collectMailDetailEntity.getStatus());
                    }
                    collectMailDetailImpl.updateStatusByUid(11, collectMailDetailEntity.getUid());
                }
            }
        }

        UnpackNoticeEntity unpackNoticeEntity = new UnpackNoticeEntity();
        unpackNoticeEntity.setOrderCode(noticeRequest.getOrderCode());
        unpackNoticeEntity.setBuyerCode(noticeRequest.getBuyerCode());
        unpackNoticeEntity.setConsoType(noticeRequest.getConsoType());
        unpackNoticeEntity.setConsoWarehouseCode(noticeRequest.getConsoWarehouseCode());
        unpackNoticeEntity.setDeliveryType(noticeRequest.getDeliveryType());
        unpackNoticeEntity.setProviderCode(noticeRequest.getProviderCode());
        unpackNoticeEntity.setMailDetails(JSONObject.toJSONString(noticeRequest.getMailDetails()));
        unpackNoticeEntity.setReceiverDetail(JSONObject.toJSONString(noticeRequest.getReceiverDetail()));

        unpackNoticeImpl.save(unpackNoticeEntity);
    }

    public void UserIdentify(PddServiceConsoUserIdentifyRequest identifyRequest) {
        UserIdentifyEntity userIdentifyEntity = new UserIdentifyEntity();
        userIdentifyEntity.setMobileNo(identifyRequest.getMobileNo());
        userIdentifyEntity.setIdType(identifyRequest.getIdType());
        userIdentifyEntity.setIdNumber(identifyRequest.getIdNumber());
        userIdentifyEntity.setName(identifyRequest.getName());

        userIdentifyImpl.save(userIdentifyEntity);
    }
}
