package cn.freemud.service.universal.impl;

import cn.freemud.adapter.CreateOrderAdapter;
import cn.freemud.adapter.OrderAdapter;
import cn.freemud.base.entity.BaseResponse;
import cn.freemud.constant.ResponseCodeConstant;
import cn.freemud.entities.bo.CreateOrderBo;
import cn.freemud.entities.dto.ConfirmOrderDto;
import cn.freemud.entities.dto.QueryRelationOrderByIdResponseDto;
import cn.freemud.entities.dto.UserDeliveryInfoDto;
import cn.freemud.entities.dto.pay.OrderPayResponse;
import cn.freemud.entities.dto.product.AttributeValue;
import cn.freemud.entities.dto.product.GroupDetail;
import cn.freemud.entities.dto.product.ProductAttributeGroup;
import cn.freemud.entities.dto.product.ProductGroup;
import cn.freemud.entities.dto.shoppingCart.ShoppingCartGoodsDto;
import cn.freemud.entities.vo.*;
import cn.freemud.enums.OrderSourceType;
import cn.freemud.enums.ResponseResult;
import cn.freemud.enums.*;
import cn.freemud.interceptor.ServiceException;
import cn.freemud.service.MallOrderService;
import cn.freemud.service.impl.ItemServiceImpl;
import cn.freemud.service.universal.UniversalOrderService;
import cn.freemud.utils.AppLogUtil;
import cn.freemud.utils.ResponseUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.freemud.api.assortment.datamanager.entity.db.AssortmentOpenPlatformWxapp;
import com.freemud.api.assortment.datamanager.entity.vo.AssortmentCustomerInfoVo;
import com.freemud.application.sdk.api.constant.ResponseResultEnum;
import com.freemud.application.sdk.api.couponcenter.offline.request.CouponLockRequest;
import com.freemud.application.sdk.api.log.LogThreadLocal;
import com.freemud.application.sdk.api.membercenter.request.UserScoreRequest;
import com.freemud.application.sdk.api.ordercenter.entities.v1.OrderBeanV1;
import com.freemud.application.sdk.api.ordercenter.enums.AfterSalesType;
import com.freemud.application.sdk.api.ordercenter.enums.OrderClientType;
import com.freemud.application.sdk.api.ordercenter.request.OrderExtInfoDto;
import com.freemud.application.sdk.api.ordercenter.request.OrderExtendedReq;
import com.freemud.application.sdk.api.ordercenter.request.create.DeliveryContactInfoCreateReq;
import com.freemud.application.sdk.api.ordercenter.request.create.OrderCostCreateReq;
import com.freemud.application.sdk.api.ordercenter.request.create.OrderItemCreateReq;
import com.freemud.application.sdk.api.ordercenter.request.create.OrderSettlementCreateReq;
import com.freemud.application.sdk.api.promotioncenter.dto.promotion.GoodsStockDTO;
import com.freemud.application.sdk.api.promotioncenter.request.promotion.ActivityUpdateStockRequest;
import com.freemud.application.sdk.api.stockapi.request.UpdateStocksRequest;
import com.freemud.sdk.api.assortment.order.adapter.OrderSdkAdapter;
import com.freemud.sdk.api.assortment.order.enums.*;
import com.freemud.sdk.api.assortment.order.request.order.*;
import com.freemud.sdk.api.assortment.order.response.order.BaseOrderResponse;
import com.freemud.sdk.api.assortment.order.response.order.CreateOrderResponse;
import com.freemud.sdk.api.assortment.order.response.order.QueryRelatedOrderByCodeResp;
//import com.freemud.sdk.api.assortment.order.response.payment.OrderPayResponse;
import com.freemud.sdk.api.assortment.order.util.ClassUtils;
import com.freemud.sdk.api.assortment.order.vo.ProductGroupVo;
import com.freemud.sdk.api.assortment.payment.request.UnifiedOrderRequest;
import com.freemud.sdk.api.assortment.payment.response.UnifiedOrderResponse;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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


/**
 * @author : xh.Z
 * @email : fisherman0510@163.com
 * @Date : 2021/4/9 下午2:30
 * @description : 商城订单
 */
@Service
public class SaasMallOrderService extends UniversalOrderService {

    @Autowired
    private OrderAdapter orderAdapter;

    @Autowired
    private ItemServiceImpl itemService;

    @Autowired
    private OrderSdkAdapter orderSdkAdapter;

    @Autowired
    private MallOrderService mallOrderService;

    /**
     * 商城有自己的支付逻辑 不走预支付流程
     *
     * @return
     */
    @Override
    protected boolean defaultPrepayOrder() {
        return false;
    }

    @Override
    public void getCustomCreateOrderBo(CreateOrderBo createOrderBo) {

    }

    @Override
    public void validParam(CreateOrderBaseVo createOrderBaseVo) {

    }

    /**
     * 订单 核心方法被覆写 该方法不起作用 无需实现
     *
     * @param createOrderBo
     * @return
     * @see SaasMallOrderService#createSharedOrder(cn.freemud.entities.bo.CreateOrderBo)
     * @see UniversalOrderService#createSharedOrder(cn.freemud.entities.bo.CreateOrderBo)
     */
    @Override
    protected com.freemud.application.sdk.api.ordercenter.request.create.CreateOrderRequest absGetCreateOrderRequest(CreateOrderBo createOrderBo) {

        return null;
    }

    @Override
    public OrderExtInfoDto getExtInfo(CreateOrderBo createOrderBo) {
        OrderExtInfoDto orderExtInfoDto = new OrderExtInfoDto();
        AssortmentCustomerInfoVo userLoginInfoDto = createOrderBo.getUserLoginInfoDto();
        CreateOrderBaseVo createOrderBaseVo = createOrderBo.getCreateOrderBaseVo();
        String sessionId = createOrderBaseVo.getSessionId();
        String version = createOrderBaseVo.getVersion();
        orderExtInfoDto.setOpenid(userLoginInfoDto.getOpenId());
        orderExtInfoDto.setAppid(userLoginInfoDto.getWxAppId());
        orderExtInfoDto.setSessionId(sessionId);
        orderExtInfoDto.setVersion(version);

        createOrderBo.setExtInfo(orderExtInfoDto);
        return orderExtInfoDto;
    }

    /**
     * @param createOrderBo
     * @param createOrderResponse
     * @return
     */
    @Override
    protected BaseResponse sendActivityUpdateStock(CreateOrderBo createOrderBo, CreateOrderResponse createOrderResponse) {
        BaseCreateOrderRequest baseCreateOrderRequest = createOrderBo.getBaseCreateOrderRequest();
        List<CreateOrderProductRequest> products = baseCreateOrderRequest.getProducts();
        ActivityUpdateStockRequest activityUpdateStockRequest = baseCreateOrderRequest.getActivityUpdateStockRequest();
        List<CreateOrderAccountRequest> accounts = baseCreateOrderRequest.getAccounts();

        // mq  老代码里 商城订单不发送mq  这里就注释下 需要再开放
        MqMessageRequest mqMessageRequest = new MqMessageRequest();
//        mqMessageRequest.setBackOrdersNotifyActivityExchange(super.backOrdersNotifyActivityExchange);
//        mqMessageRequest.setBackOrdersNotifyActivityQueue(super.backOrdersChangeOrderStatusConsumerQueue);
        String menuType = baseCreateOrderRequest.getMenuType();

        BaseOrderResponse baseOrderResponse = this.updateStockAndScore(createOrderResponse.getData(),
                products,
                activityUpdateStockRequest,
                accounts,
                mqMessageRequest,
                menuType);
        if (!ResponseCodeConstant.RESPONSE_SUCCESS.equals(baseOrderResponse.getErrcode())) {
            return ResponseUtil.error(baseOrderResponse.getErrcode().toString(), baseOrderResponse.getErrmsg(), null);
        }
        // 表示 成功操作
        return null;
    }

    private BaseOrderResponse updateStockAndScore(OrderBeanV1 orderBean,
                                                  List<CreateOrderProductRequest> products,
                                                  ActivityUpdateStockRequest updateStockRequest,
                                                  List<CreateOrderAccountRequest> accounts,
                                                  MqMessageRequest mqMessageRequest,
                                                  String menuType) {
        //TODO 转换获取库存信息,扣减库存
        UpdateStocksRequest updateProductStock = orderSdkAdapter.getUpdateProductStock(orderBean, products, StockChangeType.REDUCE, menuType);
        BaseOrderResponse baseResponse = super.reducesStocks(updateProductStock, orderBean.getOid(), orderBean.getCompanyId());
        if (baseResponse != null) {
            // 表示 减库存失败
            return baseResponse;

        }
        //TODO 扣减活动库存
        ActivityUpdateStockRequest activityUpdateStockRequest = orderSdkAdapter.convert2ActivityUpdateStockRequest(orderBean, updateStockRequest);
        baseResponse = super.reducesActivityStocks(activityUpdateStockRequest, orderBean, mqMessageRequest);
        if (baseResponse != null) {
            // 表示 操作失败
            return baseResponse;
        }

        // 扣减积分，扣减失败冲正积分返回错误
        UserScoreRequest userScoreRequest = orderSdkAdapter.convent2UserScoreRequest(orderBean, accounts, true);
        baseResponse = super.reducesScore(userScoreRequest, orderBean, mqMessageRequest);
        if (baseResponse != null) {
            // 表示 操作失败
            return baseResponse;
        }

        // 下单成锁定劵，冻结失败提示下单失败并冲正库存积分等,判断支付渠道，积分和svc卡直接核销，无需锁定10102 = svc卡支付 || 支付金额小于等于0
        //todo:统一流程 下单锁券再核销
        CouponLockRequest couponLockRequest = orderSdkAdapter.convert2CouponLockRequest(orderBean, accounts);
        baseResponse = super.couponLock(couponLockRequest, orderBean, mqMessageRequest);
        if (baseResponse != null) {
            // 表示 操作失败
            return baseResponse;
        }
        return BaseOrderResponse.getErrorBaseOrderResponse(ResponseCodeConstant.RESPONSE_SUCCESS_STR, "");
    }


    /**
     * 覆写下订单接口
     *
     * @param createOrderBo
     * @return
     */
    @Override
    protected BaseResponse createSharedOrder(CreateOrderBo createOrderBo) {
        OrderExtendedReq orderExtendedReq = orderAdapter.saveStoreInfo(createOrderBo.getStoreResponseDto());
        CreateOrderBaseVo createOrderBaseVo = createOrderBo.getCreateOrderBaseVo();
        ShoppingCartGoodsDto shoppingCartGoodsDto = createOrderBo.getShoppingCartGoodsDto();
        //创建普通订单
        Function<Object, BaseResponse> createOrder = (var -> {
            BaseCreateOrderRequest baseCreateOrderRequest = this.convent2CreateOrderDto(createOrderBaseVo, shoppingCartGoodsDto);
            //查询第三方商品编号
            baseCreateOrderRequest = getProductCustomerCode(baseCreateOrderRequest);
            //保存门店渠道信息
            baseCreateOrderRequest.setOrderExtended(orderExtendedReq);
            baseCreateOrderRequest.setOrderClient(OrderClientType.SAASMALL);
            baseCreateOrderRequest.setTrackingNo(LogThreadLocal.getTrackingNo());

            createOrderBo.setBaseCreateOrderRequest(baseCreateOrderRequest);
            com.freemud.application.sdk.api.ordercenter.request.create.CreateOrderRequest request = convent2CreateOrderRequest(baseCreateOrderRequest);
            return super.sendCreateOrder(request, createOrderBo);
        });
        //普通订单
        BaseResponse createOrderFlowResponse = createOrder.apply(null);
        if (ObjectUtils.notEqual(Integer.valueOf(ResponseResult.SUCCESS.getCode()), createOrderFlowResponse.getCode())) {
            return ResponseUtil.error(createOrderFlowResponse.getCode(), createOrderFlowResponse.getMessage());
        }
        OrderBeanV1 orderBean = (OrderBeanV1) createOrderFlowResponse.getResult();
        long totalAmount = orderBean.getAmount();

        //<!---创建订单公共方法执行逻辑--->
        OrderPayResponse orderPayResponse;
        AssortmentCustomerInfoVo userLoginInfoDto = createOrderBo.getUserLoginInfoDto();
        PaymentRequest paymentRequest = this.orderBodyConvertToPaymentBody(userLoginInfoDto, createOrderBaseVo.getPartnerId());
        if (totalAmount < 0) {
            throw new ServiceException(ResponseResult.PAY_AMOUNT_ERROR);
        } else if (totalAmount > 0) {
            orderPayResponse = this.getPreOrderPay(orderBean, paymentRequest, LogThreadLocal.getTrackingNo(), 0);
        } else {
            // 0元订单如果不需要支付，自定义支付单号
            orderPayResponse = super.getOrderPayResponse(paymentRequest, orderBean);
        }
        if (orderPayResponse == null) {
            return this.failPreOrderPay(LogThreadLocal.getTrackingNo(), orderBean);
        }

        //自己拉起支付 不走主逻辑
        CreateOrderResponseVo createOrderResponse = orderAdapter.convent2CreateFatherSonOrderResponseVo(orderPayResponse, orderBean);
        BaseResponse baseEditResponse = this.updateOrderInfo(orderPayResponse, createOrderBo.getExtInfo(), orderBean, LogThreadLocal.getTrackingNo());
        if (baseEditResponse != null) {
            return baseEditResponse;
        }
        if (totalAmount > 0 && StringUtils.isBlank(createOrderBaseVo.getCardCode())) {
            createOrderResponse.setPaySuccess(false);
        } else {
            createOrderResponse.setPaySuccess(true);
        }
        if (!createOrderResponse.getPaySuccess()) {
            return ResponseUtil.success(createOrderResponse);
        } else {
            //如果是商品券支付0元，调用回调接口
            PaysuccessNoticeMessage message = new PaysuccessNoticeMessage();
            message.setResult_code(100);
            message.setOut_trade_no(createOrderResponse.getFmId());
            message.setTrans_id(createOrderResponse.getOid());
            message.setTotal_fee(0);
            message.setOpenid(userLoginInfoDto.getOpenId());
            message.setPlatform_coupon(0);
            message.setMerchant_coupon(0);
            this.paySuccessCallback(message);
            return ResponseUtil.success(createOrderResponse);
        }
    }

    private String paySuccessCallback(PaysuccessNoticeMessage message) {
        ConfirmOrderDto confirmOrderDto = orderAdapter.convent2ConfirmOrderDto(message);
        Map<String, OrderBeanV1> orderBeans = getOrderBeanByOrderId(confirmOrderDto.getOrderId());
        return this.paySuccessCallback(message, confirmOrderDto, orderBeans);
    }

    private String paySuccessCallback(PaysuccessNoticeMessage message, ConfirmOrderDto confirmOrderDto, Map<String, OrderBeanV1> orderBeans) {
        // 没动代码 直接拿来用了 后期需要修改
        return mallOrderService.paySuccessCallback(message, confirmOrderDto, orderBeans);
    }

    private Map<String, OrderBeanV1> getOrderBeanByOrderId(String orderId) {
        // 订单查询：若结果集只有一个orderBean，则为普通订单，否则为会员卡订单（父子订单）
        Map<String, OrderBeanV1> result = new HashMap<>();
        QueryRelationOrderByIdResponseDto queryOrderByIdResponseDto = getQueryRelationOrderByIdResponseDto(orderId);
        if (CollectionUtils.isEmpty(queryOrderByIdResponseDto.getData())) {
            return result;
        }
        if (1 == queryOrderByIdResponseDto.getData().size()) {
            result.put(OrderBeanType.SAASORDER.getCode(), queryOrderByIdResponseDto.getData().get(0));
        } else {
            List<OrderBeanV1> saasOrderBeans = queryOrderByIdResponseDto.getData().stream().filter(order -> order.getBizType().equals(1)).collect(Collectors.toList());
            List<OrderBeanV1> memberOrderBeans = queryOrderByIdResponseDto.getData().stream().filter(order -> order.getBizType().equals(3) && !order.getIsParent()).collect(Collectors.toList());
            List<OrderBeanV1> fatherOrderBeans = queryOrderByIdResponseDto.getData().stream().filter(order -> order.getBizType().equals(2) && order.getIsParent()).collect(Collectors.toList());
            result.put(OrderBeanType.SAASORDER.getCode(), CollectionUtils.isNotEmpty(saasOrderBeans) ? saasOrderBeans.get(0) : null);
            result.put(OrderBeanType.MERMBERORDER.getCode(), CollectionUtils.isNotEmpty(memberOrderBeans) ? memberOrderBeans.get(0) : null);
            result.put(OrderBeanType.FATHERORDER.getCode(), CollectionUtils.isNotEmpty(fatherOrderBeans) ? fatherOrderBeans.get(0) : null);
        }
        return result;
    }

    private QueryRelationOrderByIdResponseDto getQueryRelationOrderByIdResponseDto(String oid) {
        QueryRelatedOrderByCodeRequest baseQueryOrderRequest = new QueryRelatedOrderByCodeRequest();
        baseQueryOrderRequest.setOrderCode(oid);
        baseQueryOrderRequest.setTrackingNo(LogThreadLocal.getTrackingNo());
        QueryRelatedOrderByCodeResp queryOrderByIdResponse;
        queryOrderByIdResponse = orderCenterSdkService.queryRelatedOrderByCode(baseQueryOrderRequest);
        String string = JSONObject.toJSONString(queryOrderByIdResponse);
        JSONObject jsonObject = JSONObject.parseObject(string);
        QueryRelationOrderByIdResponseDto queryOrderByIdResponseDto = jsonObject.toJavaObject(QueryRelationOrderByIdResponseDto.class);
        String orderString = JSONObject.toJSONString(queryOrderByIdResponse.getOrderBeanList());
        queryOrderByIdResponseDto.setData(JSONArray.parseArray(orderString, OrderBeanV1.class));
        return queryOrderByIdResponseDto;
    }

    @Override
    public BaseResponse updateOrderInfo(OrderPayResponse orderPayResponse,
                                        OrderExtInfoDto orderExtInfo,
                                        OrderBeanV1 orderBean,
                                        String trackingNo) {
        orderExtInfo.setOpenid(orderPayResponse.getOpenId());
        String prepayId = "";
        // StringUtils 依赖修改
        if (orderPayResponse.getPayOrder() != null && !StringUtils.isEmpty(orderPayResponse.getPayOrder().getPackageX())) {
            String[] prepayIds = orderPayResponse.getPayOrder().getPackageX().split("=");
            prepayId = prepayIds.length > 1 ? prepayIds[1] : "";
        }
        orderExtInfo.setPrepayId(prepayId);

        OrderEditRequest orderEditRequest = new OrderEditRequest(orderPayResponse.getPayTransId(),
                JSONObject.toJSONString(orderExtInfo));
        orderEditRequest.setOrderId(orderBean.getOid());
        orderEditRequest.setTrackingNo(trackingNo);
        BaseOrderResponse baseOrderResponse = orderCenterSdkService.orderEdit(orderEditRequest);
        if (!ObjectUtils.equals(ResponseCodeConstant.RESPONSE_SUCCESS, baseOrderResponse.getErrcode())) {
            CancelOrderRequest cancelOrderRequest = orderAdapter.convent2CancelOrderRequest(orderBean.getOid(), orderBean.getCompanyId(),
                    AfterSalesType.SYSTEM_CANCEL, "编辑订单支付信息失败", trackingNo, null);
            orderCenterSdkService.orderCancel(cancelOrderRequest);
            return ResponseUtil.error(baseOrderResponse.getErrcode().toString(), baseOrderResponse.getErrmsg());
        }

        return null;
    }

    private BaseResponse failPreOrderPay(String trackingNo, OrderBeanV1 orderBean) {
        //失败冲正库存，冲正活动库存，取消订单
        CancelOrderRequest cancelOrderRequest = orderAdapter.convent2CancelOrderRequest(orderBean.getOid(), orderBean.getCompanyId(),
                AfterSalesType.SYSTEM_CANCEL, "获取预支付失败", trackingNo, null);
        super.orderCenterSdkService.orderCancel(cancelOrderRequest);
        return ResponseUtil.error(ResponseResultEnum.PAY_UNIFIED_ORDER_ERROR.getCode(), ResponseResultEnum.PAY_UNIFIED_ORDER_ERROR.getMessage(), null);
    }

    private OrderPayResponse getPreOrderPay(OrderBeanV1 orderBean, PaymentRequest paymentRequest, String trackingNo, Integer cardAmount) {
        try {
            UnifiedOrderRequest request = orderAdapter.convent2UnifiedOrderRequest(orderBean, paymentRequest, orderBean.getAmount(), cardAmount, orderBean.getOid());
            com.freemud.application.sdk.api.base.BaseResponse<UnifiedOrderResponse> responseBase = super.payService.unifiedOrder(request);
            if (!ResponseCodeConstant.RESPONSE_SUCCESS_STR.equals(responseBase.getCode())) {
                return null;
            }
            OrderPayResponse orderPayResponse = orderAdapter.convent2OrderPayResponse(responseBase.getData());
            orderPayResponse.setWxAppid(paymentRequest.getWxAppId());
            orderPayResponse.setOpenId(paymentRequest.getOpenId());
            orderPayResponse.setPartnerId(orderBean.getCompanyId());
            orderPayResponse.setOrderId(orderBean.getOid());
            return orderPayResponse;
        } catch (Exception e) {
            AppLogUtil.errorLog("getPreOrderPay_error", JSONObject.toJSONString(orderBean), JSONObject.toJSONString(paymentRequest),e);
            //TODO 邮件告警
            return null;
        }
    }

    private PaymentRequest orderBodyConvertToPaymentBody(AssortmentCustomerInfoVo userLoginInfoDto, String partnerId) {
        String wxAppId = userLoginInfoDto.getWxAppId();
        //设置支付信息
        PaymentRequest paymentRequest = new PaymentRequest();
        paymentRequest.setOpenId(userLoginInfoDto.getOpenId());
        paymentRequest.setWxAppId(wxAppId);
        AssortmentOpenPlatformWxapp wxApp = super.openPlatformWxappManager.findByPartnerIdAndWxappId(partnerId, wxAppId);
        paymentRequest.setPrincipalName(StringUtils.defaultString(wxApp.getPrincipalName(), "上海非码网络科技有限公司"));
        paymentRequest.setReverseNotifyiDcUrl(super.reverseNotifyiDcUrl);
        return paymentRequest;
    }

    /**
     * 创建 请求基础服务的 request对象
     *
     * @param requestVO
     * @return
     * @see CreateOrderAdapter  这里面 和其他 订单有重复代码 有时间需要提炼
     */
    private com.freemud.application.sdk.api.ordercenter.request.create.CreateOrderRequest convent2CreateOrderRequest(BaseCreateOrderRequest requestVO) {
        com.freemud.application.sdk.api.ordercenter.request.create.CreateOrderRequest request = new com.freemud.application.sdk.api.ordercenter.request.create.CreateOrderRequest();
        request.setPartnerId(requestVO.getCompanyId());
        request.setStoreId(requestVO.getShopId());
        //1:线上支付 2:线下支付
        request.setPayType(1);
        request.setUserId(requestVO.getUserId());
        request.setUserName(requestVO.getUserName());
        request.setStoreName(requestVO.getShopName());
        request.setPayTime(requestVO.getPayTime());
        request.setThirdStoreId(requestVO.getThirdShopId());
        request.setThirdOrderCode(requestVO.getThirdOrderCode());
        request.setPayChannelType(requestVO.getPayChannelType());
        if (requestVO.getOrderStatus() != null) {
            request.setOrderState(orderSdkAdapter.getNewOrderStatus(requestVO.getOrderStatus().getCode()));
        }
        if (requestVO.getPayStatus() != null) {
            request.setPayState(requestVO.getPayStatus().getCode());
        }
        if (requestVO.getPayChannel() != null) {
            request.setPayChannel(requestVO.getPayChannel());
        }
        if (requestVO.getPayChannelName() != null) {
            request.setPayChannelName(requestVO.getPayChannelName());
        }
        if (requestVO.getGmtExpect() != null && requestVO.getGmtExpect() != 0) {
            request.setExpectTime(new Date(requestVO.getGmtExpect()));
        }
        //订单原始金额，单位分
        Long originalAmount = 0L;
        //用户在界面上看到的支付金额
        request.setSettlementAmount(requestVO.getAmount());
        //实际支付现金金额，扣除支付自生优惠，单位分
        request.setActualPayAmount(requestVO.getAmount());
        if (requestVO.getOrderClient() != null) {
            request.setOrderClient(requestVO.getOrderClient().getIndex());
        } else {
            request.setOrderClient(StringUtils.isEmpty(requestVO.getSource()) ? OrderClientType.SAAS.getIndex() : orderSdkAdapter.getNewOrderClient(requestVO.getSource()));
        }
        //订单业务类型 1:普通订单 2:虚拟订单
        request.setBizType(1);
        request.setNote(requestVO.getRemark());
        request.setOrderType(orderSdkAdapter.getNewOrderType(requestVO.getOrderType(), requestVO.getGmtExpect(),null));
        request.setBarCounter(requestVO.getBarCounter());

        //订单market类型
        if (requestVO.getMarketingType() != null) {
            request.setMarketingType(ClassUtils.toInteger(requestVO.getMarketingType()));
        }

        //商品信息转换
        List<OrderItemCreateReq> orderItemList = new ArrayList<>();
        //优惠信息转换
        List<OrderSettlementCreateReq> orderSettlementCreateReqList = new ArrayList<>();
        //结算信息转换
        List<OrderCostCreateReq> orderCostCreateReqs = new ArrayList<>();
        // 更新订单商品详情信息
        originalAmount = orderSdkAdapter.updateOrderItemsAndSettlements(orderItemList,
                orderSettlementCreateReqList,
                orderCostCreateReqs,
                requestVO.getProducts(),
                requestVO.getAccounts(),
                requestVO.getCompanyId());

        //商品信息赋值
        request.setOrderItemList(orderItemList);
        //订单原始金额，单位分
        request.setOriginalAmount(originalAmount);
        //结算信息赋值
        request.setOrderCostDetailList(orderCostCreateReqs);
        //商品优惠信息赋值
        request.setOrderSettlementDetailList(orderSettlementCreateReqList);

        //收货人信息转换
        List<DeliveryContactInfoCreateReq> deliveryContactInfoList = new ArrayList<DeliveryContactInfoCreateReq>();
        DeliveryContactInfoCreateReq deliveryContactInfoCreateReq = new DeliveryContactInfoCreateReq();
        //地址类型 1:订单地址 2:售后单地址 3:配送员信息
        deliveryContactInfoCreateReq.setRelateObjectType(1);
        //联系方式类型 1:取件 2:收件
        deliveryContactInfoCreateReq.setInfoType(1);
        deliveryContactInfoCreateReq.setContactsName(requestVO.getUserName());
        deliveryContactInfoCreateReq.setMobile(requestVO.getPhone());
        deliveryContactInfoCreateReq.setLatitude(StringUtils.isBlank(requestVO.getLatitude()) ? null : new BigDecimal(requestVO.getLatitude()));
        deliveryContactInfoCreateReq.setLongitude(StringUtils.isBlank(requestVO.getLongitude()) ? null : new BigDecimal(requestVO.getLongitude()));
        deliveryContactInfoCreateReq.setAddressDetail(requestVO.getAddress());
        deliveryContactInfoCreateReq.setProvince(requestVO.getProvince());
        deliveryContactInfoCreateReq.setCity(requestVO.getCity());
        deliveryContactInfoCreateReq.setRegion(requestVO.getRegion());
        JSONObject deliveryExtInfo = new JSONObject();
        deliveryExtInfo.put("receiveId", requestVO.getReceiveId());
        deliveryContactInfoCreateReq.setExtInfo(deliveryExtInfo.toJSONString());
        deliveryContactInfoList.add(deliveryContactInfoCreateReq);
        //第三方配送信息
        orderSdkAdapter.getThirdDeliveryInfo(deliveryContactInfoList, requestVO.getAddInfo());
        request.setDeliveryContactInfoList(deliveryContactInfoList);
        //保存门店渠道信息
        request.setOrderExtended(requestVO.getOrderExtended());
        request.setOperator(requestVO.getOperator());
        request.setAppId(requestVO.getAppId());

        // 扩展字段（第三方商品分类编号）
        if (null != requestVO && null != requestVO.getOtherInfo()) {
            request.setExtInfo(JSONObject.toJSONString(requestVO.getOtherInfo()));
        }

        //订单重量
        Double orderWeight = orderSdkAdapter.sumOrderWeight(requestVO.getProducts());
        request.setWeight(orderWeight);

        // 买一赠一寄件信息
        if (requestVO.getChooseGoods() != null && !requestVO.getChooseGoods().isEmpty()) {
            request.setOrderSendCouponRespList(JSONArray.parseArray(JSONObject.toJSONString(requestVO.getChooseGoods()), com.freemud.application.sdk.api.ordercenter.request.create.CreateOrderRequest.ChooseGood.class));
        }

        return request;
    }


    /**
     * 查询第三方商品编号
     *
     * @param createOrderDto
     * @return
     */
    private BaseCreateOrderRequest getProductCustomerCode(BaseCreateOrderRequest createOrderDto) {
        List<String> spuIds = new ArrayList<>();
        for (CreateOrderProductRequest productDto : createOrderDto.getProducts()) {
            spuIds.add(productDto.getProductId());
        }
        Map<String, GetProductsVo> products = itemService.getSpuProducts(spuIds, createOrderDto.getCompanyId(), createOrderDto.getShopId(), createOrderDto.getMenuType());
        if (products.isEmpty()) {
            return createOrderDto;
        }
        for (CreateOrderProductRequest productDto : createOrderDto.getProducts()) {
            String skuId = productDto.getSpecification();
            if (products.get(skuId) != null) {
                productDto.setCustomerCode(products.get(skuId).getCustomerCode());
                productDto.setProductCode(products.get(skuId).getProductCode());
                productDto.setThirdProductSpecId(products.get(productDto.getSpecification()).getThirdProductSpecId());
                productDto.setThirdProductPropertyId(getThirdPropertyId(products.get(productDto.getSpecification()).getProductAttributeGroupList(), productDto.getAddInfo()));

                // todo 商品组信息
                setProductGroupInfo(products.get(skuId).getProductGroupList(), productDto);
            } else {
                productDto.setCustomerCode("");
                productDto.setProductCode("");
                AppLogUtil.errorLog("getProducts_exception", JSONObject.toJSONString(skuId), JSONObject.toJSONString(products), null);
            }
            //套餐子商品
            if (CollectionUtils.isNotEmpty(productDto.getComboProduct())) {
                for (CreateOrderProductRequest comboProduct : productDto.getComboProduct()) {
                    String comboSkuId = comboProduct.getSpecification();
                    System.out.println(comboSkuId);
                    if (products.get(comboSkuId) != null) {
                        comboProduct.setCustomerCode(products.get(comboSkuId).getCustomerCode());
                        comboProduct.setProductCode(products.get(comboSkuId).getProductCode());
                        comboProduct.setThirdProductSpecId(products.get(comboSkuId).getThirdProductSpecId());
                        comboProduct.setThirdProductPropertyId(getThirdPropertyId(products.get(comboSkuId).getProductAttributeGroupList(), comboProduct.getAddInfo()));
                        comboProduct.setStapleFood(products.get(comboSkuId).getStapleFood());
                        // todo 套餐商品的商品组信息
                        setProductGroupInfo(products.get(comboSkuId).getProductGroupList(), comboProduct);
                    } else {
                        comboProduct.setCustomerCode("");
                        comboProduct.setProductCode("");
                        AppLogUtil.errorLog("getProducts_exception", JSONObject.toJSONString(skuId), JSONObject.toJSONString(products), null);
                    }
                }
            }
        }
        return createOrderDto;
    }

    /**
     * 设置商品组信息
     *
     * @param productGroupList
     * @param product
     */
    private void setProductGroupInfo(List<ProductGroup> productGroupList, CreateOrderProductRequest product) {
        if (CollectionUtils.isEmpty(productGroupList)) return;

        List<com.freemud.sdk.api.assortment.order.vo.ProductGroupVo> targetGroupList = Lists.newArrayList();
        for (ProductGroup productGroup : productGroupList) {
            for (GroupDetail groupDetail : productGroup.getGroupDetail()) {
                com.freemud.sdk.api.assortment.order.vo.ProductGroupVo productGroupVo = ProductGroupVo.builder()
                        .groupId(groupDetail.getGroupId()).groupName(productGroup.getName())
                        .thirdGroupId(productGroup.getGroupCode()).build();
                if (!targetGroupList.contains(productGroupVo)) {
                    targetGroupList.add(productGroupVo);
                }
            }
        }
        product.setProductGroupList(targetGroupList);
    }


    private String getThirdPropertyId(List<ProductAttributeGroup> productAttributeGroups, String addInfo) {
        String thirdProductPropertyId = "";
        if (StringUtils.isBlank(addInfo) || CollectionUtils.isEmpty(productAttributeGroups)) {
            return thirdProductPropertyId;
        }
        JSONObject jsonObject = JSONObject.parseObject(addInfo);
        String attributeNames = (String) jsonObject.get("attributeNames");
        List<String> list = new ArrayList<>();
        String[] split = attributeNames.split("/");

        List<AttributeValue> attributeValues = new ArrayList<>();
        for (ProductAttributeGroup attributeGroup : productAttributeGroups) {
            attributeValues.addAll(attributeGroup.getAttributeValues());
        }

        for (int i = 0; i < split.length; i++) {
            for (AttributeValue attributeValue : attributeValues) {
                if (attributeValue.getAttributeValue().equals(split[i])) {
                    list.add(attributeValue.getCustomerCode());
                    break;
                }
            }
        }
        if (CollectionUtils.isNotEmpty(list)) {
            thirdProductPropertyId = StringUtils.join(list, ",");
        }
        return thirdProductPropertyId;
    }

    private BaseCreateOrderRequest convent2CreateOrderDto(CreateOrderBaseVo createOrderVo, ShoppingCartGoodsDto shoppingCartGoodsDto) {
        UserDeliveryInfoDto deliveryInfoDto = createOrderVo.getUserDeliveryInfoDto();
        BaseCreateOrderRequest createOrderDto = getCreateOrderDto(createOrderVo);
        long deliveryAmount = 0;
        if (deliveryInfoDto != null) {
            deliveryAmount = deliveryInfoDto.getRealDeliveryAmount();
        }
        Long packageAmount = shoppingCartGoodsDto.getPackageAmount() == null ? 0L : shoppingCartGoodsDto.getPackageAmount();
        createOrderDto.setAmount(shoppingCartGoodsDto.getTotalAmount() + deliveryAmount + packageAmount);
        // 解析购物车信息
        List<ShoppingCartGoodsDto.CartGoodsDetailDto> cartGoodsDetailDtos = shoppingCartGoodsDto.getProducts();
        List<CreateOrderProductRequest> products = new ArrayList<>();
        ArrayList<CreateOrderAccountRequest> orderAccountDtos = new ArrayList<>();
        // 根据购物车商品信息获取优惠信息
        int orderAccountIndex = 0;
        for (ShoppingCartGoodsDto.CartGoodsDetailDto cartGoodsDetailDto : cartGoodsDetailDtos) {
            Integer qty = cartGoodsDetailDto.getQty();
            if (qty > 0) {
                CreateOrderProductRequest createOrderProductDto = orderAdapter.convent2OrderProduct(cartGoodsDetailDto);
                createOrderProductDto.setIgnoreProductPrice(1);
                products.add(createOrderProductDto);
                if (CollectionUtils.isNotEmpty(cartGoodsDetailDto.getActivityDiscountsDtos())) {
                    createOrderProductDto.setAccounts(orderAdapter.getAccounts(createOrderProductDto, cartGoodsDetailDto.getActivityDiscountsDtos()));
                }
            }
        }
        createOrderDto.setProducts(products);

        if (deliveryAmount > 0) {
            CreateOrderAccountRequest createOrderAccountDto = CreateOrderAccountRequest.builder()
                    .accountId("")
                    .name("配送费")
                    .price(deliveryAmount)
                    .accountType(orderAdapter.getQueryOrderAccountType(OldOrderAccountType.getByCode(OrderAccountType.DELIVERY_AMOUNT.getCode())))
                    .sequence(orderAccountIndex++)
                    .build();
            orderAccountDtos.add(createOrderAccountDto);
        }
        if (packageAmount > 0) {
            CreateOrderAccountRequest createOrderAccountDto = CreateOrderAccountRequest.builder()
                    .accountId("")
                    .name("包装费")
                    .price(packageAmount)
                    .accountType(orderAdapter.getQueryOrderAccountType(OldOrderAccountType.getByCode(OrderAccountType.PACK_AMOUNT.getCode())))
                    .sequence(orderAccountIndex++)
                    .build();
            orderAccountDtos.add(createOrderAccountDto);
        }

        createOrderDto.setAccounts(CollectionUtils.isNotEmpty(orderAccountDtos) ? orderAccountDtos : Collections.emptyList());

        //设置库存扣减
        if (CollectionUtils.isNotEmpty(shoppingCartGoodsDto.getStocks())) {
            List<ActivityUpdateStockRequest.StockBeanDto> stocks = new ArrayList<>();
            for (SubtractStockVO stockVO : shoppingCartGoodsDto.getStocks()) {
                ActivityUpdateStockRequest.StockBeanDto stockBeanDto = new ActivityUpdateStockRequest.StockBeanDto();
                stockBeanDto.setActivityCode(stockVO.getActivityCode());
                stockBeanDto.setActivityStock(stockVO.getActivityStock() == null ? 1 : stockVO.getActivityStock());
                if (CollectionUtils.isNotEmpty(stockVO.getGoodsStock())) {
                    List<GoodsStockDTO> goodsStockDTOS = new ArrayList<>();
                    stockVO.getGoodsStock().forEach(goods -> {
                        GoodsStockDTO goodsStockDTO = new GoodsStockDTO();
                        goodsStockDTO.setBenefitSeq(goods.getBenefitSeq());
                        goodsStockDTO.setGoodsId(goods.getGoodsId());
                        int stock = goods.getStock() == null ? 1 : goods.getStock();
                        goodsStockDTO.setStock(stock);
                        goodsStockDTOS.add(goodsStockDTO);
                    });
                    stockBeanDto.setGoodsStock(goodsStockDTOS);
                }
                stocks.add(stockBeanDto);
            }
            ActivityUpdateStockRequest activityUpdateStockRequest = new ActivityUpdateStockRequest();
            activityUpdateStockRequest.setStock(stocks);
            createOrderDto.setActivityUpdateStockRequest(activityUpdateStockRequest);
        }
        return createOrderDto;
    }

    private BaseCreateOrderRequest getCreateOrderDto(CreateOrderBaseVo createOrderVo) {
        UserDeliveryInfoDto userDeliveryInfoDto = createOrderVo.getUserDeliveryInfoDto();
        String remark = StringUtils.isNotBlank(createOrderVo.getOrderRemark()) ? createOrderVo.getOrderRemark() : "";
        BaseCreateOrderRequest createOrderDto = new BaseCreateOrderRequest();
        createOrderDto.setCompanyId(createOrderVo.getPartnerId());
        createOrderDto.setShopId(createOrderVo.getShopId());
        createOrderDto.setThirdShopId(createOrderVo.getThirdShopId());
        createOrderDto.setShopName(createOrderVo.getStoreName());
        createOrderDto.setUserId(createOrderVo.getUserId());
        createOrderDto.setUserName(userDeliveryInfoDto.getReceiveUserName());
        createOrderDto.setPhone(userDeliveryInfoDto.getReceiveMobile());
        createOrderDto.setAddress(userDeliveryInfoDto.getReceiveAddress());
        createOrderDto.setLatitude(userDeliveryInfoDto.getUserLatitude());
        createOrderDto.setLongitude(userDeliveryInfoDto.getUserLongitude());
        createOrderDto.setOrderType(QueryOrderType.TAKE_OUT);
        createOrderDto.setPayType(QueryPayType.ONLINE_PAY);
        createOrderDto.setSource(OrderSourceType.SAASMALL.getCode());
        createOrderDto.setSourceName(OrderSourceType.SAASMALL.getDesc());
        createOrderDto.setOrderClient(OrderClientType.SAASMALL);
        createOrderDto.setRemark(remark);
        createOrderDto.setGmtExpect(null);
        BaseCreateOrderRequest.DeliveryTypeInfo deliveryTypeInfo = new BaseCreateOrderRequest.DeliveryTypeInfo();
        deliveryTypeInfo.setDeliveryType(QueryDeliveryType.THIRD);
        createOrderDto.setAddInfo(deliveryTypeInfo);
        createOrderDto.setAmount(0L);
        createOrderDto.setBarCounter(createOrderVo.getTableNumber());
        createOrderDto.setProvince(userDeliveryInfoDto.getReceiveProvince());
        createOrderDto.setCity(userDeliveryInfoDto.getReceiveCity());
        createOrderDto.setRegion(userDeliveryInfoDto.getReceiveRegion());
        createOrderDto.setMenuType(BusinessTypeEnum.SAAS_MALL.getName());
        return createOrderDto;
    }

}
