/**
 * All rights Reserved, Designed By www.freemud.cn
 *
 * @Title: CheckOrder
 * @Package cn.freemud.service.impl
 * @Description:
 * @author: ping.wu
 * @date: 2019/5/8 10:01
 * @version V1.0
 * @Copyright: 2019 www.freemud.cn Inc. All rights reserved.
 * 注意：本内容仅限于上海非码科技内部传阅，禁止外泄以及用于其他的商业目
 */
package cn.freemud.service;

import cn.freemud.base.util.DateUtil;
import cn.freemud.constant.ResponseCodeConstant;
import cn.freemud.constant.StoreConstant;
import cn.freemud.entities.bo.CreateOrderBo;
import cn.freemud.entities.dto.StoreDeliveryInfoDto;
import cn.freemud.entities.dto.UserDeliveryInfoDto;
import cn.freemud.entities.dto.delivery.DeliveryBaseResponse;
import cn.freemud.entities.dto.delivery.GetDeliveryFlagRequest;
import cn.freemud.entities.dto.delivery.GetDeliveryFlagResponseDto;
import cn.freemud.entities.dto.order.BusinessDate;
import cn.freemud.entities.dto.shoppingCart.GetShoppingCartGoodsApportionDto;
import cn.freemud.entities.dto.shoppingCart.ShoppingCartGoodsDto;
import cn.freemud.entities.vo.CreateOrderBaseVo;
import cn.freemud.entities.vo.CreateOrderVo;
import cn.freemud.entities.vo.GetProductsVo;
import cn.freemud.entities.vo.ShoppingCartInfoRequestVo;
import cn.freemud.enums.*;
import cn.freemud.interceptor.ServiceException;
import cn.freemud.service.adapter.OrderCheckAdapter;
import cn.freemud.service.impl.ItemServiceImpl;
import cn.freemud.service.impl.StoreServiceImpl;
import cn.freemud.service.order.OrderRelationFactory;
import cn.freemud.service.order.OrderRelationService;
import cn.freemud.service.thirdparty.DeliveryFeiginClient;
import cn.freemud.service.thirdparty.ShoppingCartClient;
import cn.freemud.utils.AppLogUtil;
import com.alibaba.fastjson.JSONObject;
import com.freemud.api.assortment.datamanager.entity.db.AssortmentOpenPlatformIappWxappConfig;
import com.freemud.api.assortment.datamanager.entity.db.AssortmentOpenPlatformPartnerStoreDeliveryConfig;
import com.freemud.api.assortment.datamanager.entity.vo.AssortmentCustomerInfoVo;
import com.freemud.api.assortment.datamanager.manager.AssortmentOpenPlatformIappWxappConfigManager;
import com.freemud.api.assortment.datamanager.manager.AssortmentOpenPlatformPartnerStoreDeliveryConfigManager;
import com.freemud.application.sdk.api.base.BaseResponse;
import com.freemud.application.sdk.api.log.LogThreadLocal;
import com.freemud.application.sdk.api.membercenter.request.QueryReceiveAddressRequest;
import com.freemud.application.sdk.api.membercenter.request.StatisticalPropertyRequest;
import com.freemud.application.sdk.api.membercenter.response.GetSvcInfoByMemberIdResponse;
import com.freemud.application.sdk.api.membercenter.response.QueryReceiveAddressResponse;
import com.freemud.application.sdk.api.membercenter.service.MemberCenterService;
import com.freemud.application.sdk.api.membercenter.service.MemberPropertyService;
import com.freemud.application.sdk.api.storecenter.request.QueryDeliveryRequest;
import com.freemud.application.sdk.api.storecenter.request.StoreInfoRequest;
import com.freemud.application.sdk.api.storecenter.response.QueryDeliverDetailResponse;
import com.freemud.application.sdk.api.storecenter.response.StoreResponse;
import com.freemud.application.sdk.api.storecenter.service.StoreCenterService;
import com.freemud.sdk.api.assortment.order.enums.StoreDeliveryMethod;
import com.google.common.collect.Lists;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.awt.geom.Point2D;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Component
@Log4j2
public abstract class CheckOrderUniversal {

    @Autowired
    private ShoppingCartClient shoppingCartClient;
    @Autowired
    private DeliveryFeiginClient deliveryFeiginClient;

    //会员SDK
    @Autowired
    private MemberPropertyService memberPropertyService;

    @Autowired
    private OrderRelationFactory orderRelationFactory;
    @Autowired
    private StoreCenterService storeCenterService;
    @Autowired
    private AssortmentOpenPlatformIappWxappConfigManager openPlatformIappWxappConfigManager;
    @Autowired
    private AssortmentOpenPlatformPartnerStoreDeliveryConfigManager deliveryConfigManager;
    @Autowired
    private MemberCenterService memberCenterService;
    @Autowired
    private StoreServiceImpl storeService;
    @Autowired
    private ItemServiceImpl itemService;

    // 配送费逻辑是否使用旧的
    @Value("${store.delivery.use.old}")
    private boolean storeDeliveryUseOld;

    @Value("${coco.partnerId}")
    private String cocoPartnerId;


    /**
     * 是否校验 会员svc卡信息
     * 商城是不校验的
     * app saas 校验
     *
     * @return
     */
    protected boolean checkCardCode() {
        return true;
    }


    /**
     * 逻辑校验
     *
     * @param createOrderBo
     * @param trackingNo
     */
    public void checkCreateOrderParam(CreateOrderBo createOrderBo, String trackingNo) {
        // 通用参数校验  直接复写该接口 如果不适用
        checkUniversalCreateOrderParam(createOrderBo, trackingNo);
        // 自定义参数校验
        checkCustomCreateOrderParam(createOrderBo);
    }

    /**
     * 通用参数校验 fisherman-> 需要重新核实 公共校验是否都通用  删除个性校验 到自定义校验中
     * 先抽主流程, 验证通过, 留钩子校验自定义流程
     * 1.校验用户login              ok
     * 2.validate  shoppincat      ok
     * 3.validate  store           ok
     * 4.validate  cardcode        ok
     *
     * @param createOrderBo
     * @param trackingNo
     */
    public void checkUniversalCreateOrderParam(CreateOrderBo createOrderBo, String trackingNo) {

        // begin  没问题的内容
        //校验会员svc卡信息  fisherman app/saas 需要校验  商城订单不需要 要重写checkCardCode()方法
        if (checkCardCode()) {
            checkCardCode(createOrderBo.getCreateOrderBaseVo(), createOrderBo.getUserLoginInfoDto());
        }

        // 查询购物车（内部校验券点餐方式，券是否可用） 校验当前订单类型的下单参数   主流程
        ShoppingCartGoodsDto shoppingCartGoodsDto = checkShoppingCartGoodsDto(createOrderBo.getCreateOrderBaseVo());
        createOrderBo.setShoppingCartGoodsDto(shoppingCartGoodsDto);
        // end

        // 查询门店信息 营业时间、营业状态，服务器当前时间在营业时间内 点餐桌号      主流程
        StoreResponse.BizVO storeResponseDto = checkOrderByStore(createOrderBo, trackingNo, true);
        createOrderBo.setStoreResponseDto(storeResponseDto);


        // fisherman 这里的逻辑 master上好像没有了 在saas订单中
        List<String> spuIds = new ArrayList<>();
        for (ShoppingCartGoodsDto.CartGoodsDetailDto cartGoodsDetailDto : createOrderBo.getShoppingCartGoodsDto().getProducts()) {
            spuIds.add(StringUtils.isNotBlank(cartGoodsDetailDto.getSpuId()) ? cartGoodsDetailDto.getSpuId() : cartGoodsDetailDto.getSkuId());
        }
        Map<String, GetProductsVo> products = itemService.getSpuProducts(spuIds, createOrderBo.getCreateOrderBaseVo().getPartnerId(),
                createOrderBo.getCreateOrderBaseVo().getShopId(), createOrderBo.getCreateOrderBaseVo().getMenuType());
        createOrderBo.setProducts(products);

    }


    public abstract void checkCustomCreateOrderParam(CreateOrderBo createOrderBo);

    public void checkCardCode(CreateOrderBaseVo createOrderBaseVo, AssortmentCustomerInfoVo userLoginInfoDto) {
        if (StringUtils.isBlank(createOrderBaseVo.getCardCode())) {
            return;
        }
        StatisticalPropertyRequest request = new StatisticalPropertyRequest();
        request.setPartnerId(createOrderBaseVo.getPartnerId());
        request.setMemberId(userLoginInfoDto.getMemberId());
        BaseResponse<List<GetSvcInfoByMemberIdResponse>> responseDTO = memberPropertyService.getSvcInfoByMemberId(request, LogThreadLocal.getTrackingNo());
        if (!ResponseResult.SUCCESS.getCode().equals(responseDTO.getCode()) || responseDTO.getData() == null
                || responseDTO.getData().size() == 0) {
            throw new ServiceException(ResponseResult.USER_SVC_CARD_ERROR);
        }
        //svc卡无效
        boolean b = true;
        for (GetSvcInfoByMemberIdResponse getSvcInfoByMemberIdResponse : responseDTO.getData()) {
            if (createOrderBaseVo.getCardCode().equals(getSvcInfoByMemberIdResponse.getCardCode()) && getSvcInfoByMemberIdResponse.getStatusFlag() == 0) {
                b = false;
            }
        }
        if (b) {
            throw new ServiceException(ResponseResult.USER_SVC_CARD_ERROR);
        }
    }

    /**
     * 下单门店相关校验
     */
    protected StoreResponse.BizVO checkOrderByStore(CreateOrderBo createOrderBo, String trackingNo, boolean isCheck) {
        CreateOrderBaseVo createOrderBaseVo = createOrderBo.getCreateOrderBaseVo();
        String partnerId = createOrderBaseVo.getPartnerId();
        String shopId = createOrderBaseVo.getShopId();

        // 获取门店信息
        StoreResponse storeResponse = getStoreInfo(partnerId, shopId, trackingNo);
        if (storeResponse == null || storeResponse.getBizVO() == null) {
            throw new ServiceException(ResponseResult.STORE_NOT_FOUND);
        }
        if (isCheck) {
            //订单预约单检查
            OrderCheckAdapter.check(createOrderBaseVo, storeResponse);
        }
        StoreResponse.BizVO storeResponseDto = storeResponse.getBizVO();
        // 校验门店是否停业 1 营业 2 停业 3 繁忙置休
        if (storeResponseDto.getActiveFlag() == null || storeResponseDto.getActiveFlag() != 1) {
            throw new ServiceException(ResponseResult.STORE_ITEM_STOP_BUSINESS);
        }
        createOrderBaseVo.setStoreName(storeResponseDto.getStoreName());
        createOrderBaseVo.setStoreAddress(storeResponseDto.getAddress());
        createOrderBaseVo.setThirdShopId(storeResponseDto.getThirdPartCode());
        createOrderBaseVo.setStoreNameEn(storeResponseDto.getStoreNameEn());
        return storeResponseDto;
    }

    /**
     * 查询门店信息
     */
    private StoreResponse getStoreInfo(String partnerId, String shopId, String trackingNo) {
        // 获取门店信息
        StoreInfoRequest storeInfoRequest = new StoreInfoRequest(partnerId, shopId, null);
        return storeCenterService.getStoreInfo(storeInfoRequest, trackingNo);
    }


    public ShoppingCartGoodsDto checkShoppingCartGoodsDto(CreateOrderBaseVo createOrderBaseVo) {
        // 校验购物车 以及校验优惠券 fisherman -> 噩梦开始的地方
        ShoppingCartGoodsDto shoppingCartGoodsDto = getShoppingCartGoodsDto(createOrderBaseVo);
        long deliveryAmount = 0;
        long discountDeliveryAmount = 0;
        if (createOrderBaseVo.getMenuType().equals(BusinessTypeEnum.SAAS_DELIVERY.getCode())) {
            deliveryAmount = shoppingCartGoodsDto.getDeliveryAmount() == null ? 9L : shoppingCartGoodsDto.getDeliveryAmount();
            discountDeliveryAmount = shoppingCartGoodsDto.getDeliveryAmount() == null ? 9L : shoppingCartGoodsDto.getDeliveryAmount();
            if (shoppingCartGoodsDto.getIsDiscountDelivery() && deliveryAmount > shoppingCartGoodsDto.getDiscountDeliveryAmount()) {
                discountDeliveryAmount = shoppingCartGoodsDto.getDiscountDeliveryAmount();
            }
        }
        shoppingCartGoodsDto.setDeliveryAmount(deliveryAmount);
        shoppingCartGoodsDto.setDiscountDeliveryAmount(discountDeliveryAmount);
        shoppingCartGoodsDto.setPackageAmount(shoppingCartGoodsDto.getPackageAmount() == null ? 0L : shoppingCartGoodsDto.getPackageAmount());
        return shoppingCartGoodsDto;
    }

    /**
     * 渠道类型
     *
     * @return
     */
    protected abstract OrderChannelType getChannelType();

    private ShoppingCartInfoRequestVo initShoppingCartInfoRequestVoBuilder(CreateOrderBaseVo createOrderVo) {
        ShoppingCartInfoRequestVo.BuyMemberCard buyMemberCard = null;
        // 商城订单 没有会员卡
        if (createOrderVo.getBuyMemberCard() != null && checkCardCode()) {
            buyMemberCard = new ShoppingCartInfoRequestVo.BuyMemberCard();
            buyMemberCard.setPaidId(createOrderVo.getBuyMemberCard().getPaidId());
            buyMemberCard.setRuleId(createOrderVo.getBuyMemberCard().getRuleId());
        }
        return ShoppingCartInfoRequestVo.builder()
                .partnerId(createOrderVo.getPartnerId())
                .shopId(createOrderVo.getShopId())
                .version(createOrderVo.getVersion())
                .sessionId(createOrderVo.getSessionId())
                .orderType(createOrderVo.getOrderType())
                .reachStoreType(createOrderVo.getReachStoreType())
                .flag(CouponFlag.NO.getCode())
                .receiveId(createOrderVo.getReceiveId())
                .useCustomerScore(createOrderVo.getUseCustomerScore())
                .channelType(getChannelType().getCode())
                .buyMemberCard(buyMemberCard)
                .menuType(createOrderVo.getMenuType())
                .build();
    }

    /**
     * 优惠券校验
     * 商城订单没有优惠券  saas app有
     */
    protected void diyCheckCouponCode(CreateOrderBaseVo createOrderVo, ShoppingCartInfoRequestVo shoppingCartInfoRequestVo) {

    }

    // 校验购物车优惠信息请求对象
    protected abstract GetShoppingCartGoodsApportionDto getShoppingCartGoodsApportionDto(CreateOrderBaseVo createOrderVo,
                                                                                         ShoppingCartInfoRequestVo shoppingCartInfoRequestVo);


    protected cn.freemud.base.entity.BaseResponse<ShoppingCartGoodsDto> checkShoppingCartGoods(CreateOrderBaseVo createOrderVo,
                                                                                               ShoppingCartInfoRequestVo shoppingCartInfoRequestVo) {
        GetShoppingCartGoodsApportionDto requestDto = getShoppingCartGoodsApportionDto(createOrderVo, shoppingCartInfoRequestVo);
        // 若为拼单类型，购物车信息从新的拼单购物车获取 update by miaohui for 【ID1010972】 多人拼单
        cn.freemud.base.entity.BaseResponse<ShoppingCartGoodsDto> apportionResponse;
        if (this.isCollageOrder(createOrderVo)) {
            apportionResponse = shoppingCartClient.getCollageShoppingCartGoodsApportion(requestDto);
        } else {
            apportionResponse = shoppingCartClient.getShoppingCartGoodsApportionNew(requestDto);
        }
        AppLogUtil.infoLog("获取购物车详情", requestDto, apportionResponse);
        if (!ObjectUtils.equals(ResponseCodeConstant.RESPONSE_SUCCESS_STR, apportionResponse.getCode())) {
            ResponseResult responseResult = ResponseResult.getResponseResult(apportionResponse.getCode());
            throw new ServiceException(responseResult != null ? responseResult : ResponseResult.SHOPPING_CART_GETINFO_ERROR);
        }
        if (apportionResponse.getResult() == null || CollectionUtils.isEmpty(apportionResponse.getResult().getProducts())) {
            throw new ServiceException(ResponseResult.SHOPPING_CART_GETINFO_INVAILD);
        }
        ShoppingCartGoodsDto shoppingCartGoodsDto = apportionResponse.getResult();
        if (shoppingCartGoodsDto.getOriginalTotalAmount() == null) {
            throw new ServiceException(ResponseResult.SHOPPING_CART_GETINFO_INVAILD);
        }
        // 相同校验  end  有其他校验 自己实现 再定义方法处理
        return apportionResponse;
    }

    public ShoppingCartGoodsDto getShoppingCartGoodsDto(CreateOrderBaseVo createOrderVo) {
        ShoppingCartInfoRequestVo shoppingCartInfoRequestVo = this.initShoppingCartInfoRequestVoBuilder(createOrderVo);

        // fisherman  优惠券校验--> 商城订单没有优惠券  saas app有
        diyCheckCouponCode(createOrderVo, shoppingCartInfoRequestVo);

        // 通过购物车获取优惠信息 公共校验
        cn.freemud.base.entity.BaseResponse<ShoppingCartGoodsDto> apportionResponse = checkShoppingCartGoods(createOrderVo, shoppingCartInfoRequestVo);
        ShoppingCartGoodsDto shoppingCartGoodsDto = apportionResponse.getResult();

        // 拼单处理逻辑 商城没有
        collageOrderHandle(createOrderVo, shoppingCartGoodsDto);
        return shoppingCartGoodsDto;
    }

    /**
     * 拼团商品 逻辑
     * 商城订单 没有该操作
     *
     * @param createOrderVo
     * @param shoppingCartGoodsDto
     */
    protected void collageOrderHandle(CreateOrderBaseVo createOrderVo, ShoppingCartGoodsDto shoppingCartGoodsDto) {

    }


    /**
     * 查询小程序自提外卖配置信息 校验当前订单类型的下单参数 校验外卖是否满足起送条件
     *
     * @param createOrderBo
     */
    protected void checkOrderByOrderType(CreateOrderBo createOrderBo) {
        CreateOrderBaseVo createOrderVo = createOrderBo.getCreateOrderBaseVo();
        StoreResponse.BizVO storeResponseDto = createOrderBo.getStoreResponseDto();
        AssortmentCustomerInfoVo userLoginInfoDto = createOrderBo.getUserLoginInfoDto();
        ShoppingCartGoodsDto shoppingCartGoodsDto = createOrderBo.getShoppingCartGoodsDto();

        // 下单时间校验
        OrderRelationService orderRelationService = orderRelationFactory.getCreateOrderTimeCheckService(createOrderVo.getPartnerId());
        orderRelationService.createOrderTimeCheck(storeResponseDto, createOrderVo);

        //非到店或者外卖，类型错误
        if (!(CreateOrderType.COLLECT_GOODS.getCode().equals(createOrderVo.getOrderType()) ||
                CreateOrderType.TAKE_OUT.getCode().equals(createOrderVo.getOrderType()))) {
            throw new ServiceException(ResponseResult.PARAMETER_MISSING);
        }

        // TODO: 2020/6/16 门店校验处理
        String takeMealFlag = createOrderVo.getTakeMealFlag();
        String takeMealTimes = createOrderVo.getTakeMealTime();

        //立即送达
        if ("0".equals(takeMealFlag) || (StringUtils.isEmpty(createOrderVo.getExpectTime()) && StringUtils.isEmpty(takeMealTimes))) {
            //未营业无预约时间无法下单
            if (!StoreConstant.BUSINESS.equals(storeResponseDto.getState())) {
                throw new ServiceException(ResponseResult.STORE_ITEM_CHECK_CLOSE);
            }
            // 外卖单选择立即送达的话，下单时间必须在店铺外卖时间内
            if (createOrderVo.getOrderType().compareTo(CreateOrderType.TAKE_OUT.getCode()) == 0) {
                checkTakeOutTime(storeResponseDto, new Date(), new Date(), true);
            }
        }
        //有预约时间
        if (StringUtils.isNotBlank(takeMealTimes) || StringUtils.isNotBlank(createOrderVo.getExpectTime())) {
            // 设置预约时间
            Date takeMealDateTime = getOrderExpectTime(takeMealFlag, takeMealTimes, createOrderVo.getExpectTime(),
                    CreateOrderType.getByCode(createOrderVo.getOrderType()), storeResponseDto.getServiceTime(), storeResponseDto);
            if (takeMealDateTime != null) {
                //校验预约时间
                checkOrderExpectTime(createOrderVo, storeResponseDto, takeMealDateTime);
                //重新赋值为yyyy-MM-dd HH:mm:ss格式字符串时间
                createOrderVo.setExpectTime(DateUtil.convert2String(takeMealDateTime, "yyyy-MM-dd HH:mm:ss"));
            }
        }

        String appId = userLoginInfoDto.getWxAppId();
        // 校验小程序是否支持到店或者外卖
        AssortmentOpenPlatformIappWxappConfig config = openPlatformIappWxappConfigManager.selectIappWxappConfigByWxAppId(appId);
        // 自提校验
        if (CreateOrderType.COLLECT_GOODS.getCode().equals(createOrderVo.getOrderType())) {
            if (config == null || config.getTakeInside() == null || config.getTakeInside() != 1) {
                throw new ServiceException(ResponseResult.ORDER_WXAPP_NOT_ENABLE_COLLECT_GOODS);
            }
            if (storeResponseDto.getIsSelfMention() == null || storeResponseDto.getIsSelfMention() != 1) {
                throw new ServiceException(ResponseResult.STORE_NOT_ENABLE_COLLECT_GOODS);
            }
            createOrderVo.setUserName(userLoginInfoDto.getNickName());
            createOrderVo.setMobile(userLoginInfoDto.getMobile());
        }

        // 自提校验
        if (CreateOrderType.COLLECT_GOODS.getCode().equals(createOrderVo.getOrderType())) {
            if (config == null || config.getTakeInside() == null || config.getTakeInside() != 1) {
                throw new ServiceException(ResponseResult.ORDER_WXAPP_NOT_ENABLE_COLLECT_GOODS);
            }
            if (storeResponseDto.getIsSelfMention() == null || storeResponseDto.getIsSelfMention() != 1) {
                throw new ServiceException(ResponseResult.STORE_NOT_ENABLE_COLLECT_GOODS);
            }
            createOrderVo.setUserName(userLoginInfoDto.getNickName());
            createOrderVo.setMobile(userLoginInfoDto.getMobile());
        }

        // 校验外卖信息
        if (CreateOrderType.TAKE_OUT.getCode().equals(createOrderVo.getOrderType())) {
            if (config == null || config.getTakeaway() == null || config.getTakeaway() == 0) {
                throw new ServiceException(ResponseResult.STORE_ITEM_NOT_DELIVERY);
            }
            if (storeResponseDto.getDelivery() == null || storeResponseDto.getDelivery() == 2) {
                throw new ServiceException(ResponseResult.STORE_ITEM_NOT_DELIVERY);
            }
            if (StringUtils.isBlank(storeResponseDto.getDeliveryHoursDay())) {
                throw new ServiceException(ResponseResult.STORE_ITEM_NOT_DELIVERY);
            }
            //获取门店配送信息
            StoreDeliveryInfoDto storeDeliveryInfoDto;
            if (storeDeliveryUseOld) {
                storeDeliveryInfoDto = getStoreDeliveryInfo(storeResponseDto, config, appId);
            } else {
                storeDeliveryInfoDto = getNewStoreDeliveryInfo(storeResponseDto, config, appId, LogThreadLocal.getTrackingNo());
            }
            //coco自配送提前45分钟，禁止下单
            if (cocoPartnerId.equals(createOrderVo.getPartnerId()) &&
                    CreateOrderType.TAKE_OUT.getCode().equals(createOrderVo.getOrderType()) &&
                    "self".equals(storeDeliveryInfoDto.getDeliveryType())
            ) {
                //即时单是下单时间，预约单是预约单时间
                Date orderDate = createOrderVo.getExpectTime() != null
                        ? DateUtil.convert2Date(createOrderVo.getExpectTime(), DateUtil.FORMAT_YYYY_MM_DD_HHMMSS)
                        : new Date();
                Date todayEnd = DateUtil.setEndDay(new Date());
                boolean toDay = orderDate.before(todayEnd);
                BusinessDate businessDate = getStoreBusinessDate(storeResponseDto, toDay);
                boolean businessEndDate = (DateUtils.addMinutes(orderDate, 45).compareTo(businessDate.getEndDate()) >= 0);
                if (businessEndDate) {
                    throw new ServiceException(ResponseResult.STORE_SELF_ERROR);
                }
            }
            //todo : 这里不再支持从表中获取门店配送信息 改用接口方式调用
            //外卖起送条件（1:杯数，2:金额）
            if (!Arrays.asList(1, 2).contains(storeDeliveryInfoDto.getDeliveryCondition())) {
                throw new ServiceException(ResponseResult.STORE_DISCONTENT_DELIVERY_CONDITION);
            }
            if (1 == storeDeliveryInfoDto.getDeliveryCondition()) {
                int sum = shoppingCartGoodsDto.getProducts().stream().mapToInt(ShoppingCartGoodsDto.CartGoodsDetailDto::getQty).sum();
                if (sum < storeDeliveryInfoDto.getFreeDeliveryCup()) {
                    throw new ServiceException(ResponseResult.STORE_DISCONTENT_DELIVERY_CUP);
                }
            }
            //订单金额小于起送费提示
            else if ((2 == storeDeliveryInfoDto.getDeliveryCondition() && storeDeliveryInfoDto.getDeliveryLimitAmount() > shoppingCartGoodsDto.getTotalAmount()) && !cocoPartnerId.contains(createOrderVo.getPartnerId())) {
                throw new ServiceException(ResponseResult.STORE_DISCONTENT_DELIVERY_FEE);
            }

            storeDeliveryInfoDto.setEnableTakeaway(true);
            // 校验收货地址是否可配送
            this.checkReceiveAddress(storeDeliveryInfoDto, createOrderVo, storeResponseDto.getStoreCode());
        }

    }

    /**
     * 校验收货地址是否可配送
     */
    protected void checkReceiveAddress(StoreDeliveryInfoDto storeDeliveryInfoDto, CreateOrderBaseVo createOrderVo, String storeCode) {
        //校验收货地址是否可配送
        String receiveId = createOrderVo.getReceiveId();
        String trackingNo = LogThreadLocal.getTrackingNo();
        QueryReceiveAddressRequest request = new QueryReceiveAddressRequest(receiveId, storeDeliveryInfoDto.getPartnerId());
        BaseResponse<QueryReceiveAddressResponse> queryReceiveAddressResponse = memberCenterService.queryReceiveAddressById(request, trackingNo);
        if (!ResponseResult.SUCCESS.getCode().equals(queryReceiveAddressResponse.getCode()) || queryReceiveAddressResponse.getData() == null) {
            throw new ServiceException(ResponseResult.USER_GETRECEIVEADDRESS_ERROR);
        }
        QueryReceiveAddressResponse receiveAddressResult = queryReceiveAddressResponse.getData();
        UserDeliveryInfoDto userDeliveryInfoDto = storeService.getUserDeliveryInfo(storeDeliveryInfoDto, receiveAddressResult.getLongitude(),
                receiveAddressResult.getLatitude());
        if (!userDeliveryInfoDto.getUserEnableTakeaway()) {
            throw new ServiceException(ResponseResult.ORDER_TAKE_OUT_ADDRESS_NOT_DELIVERY);
        }
        if (BusinessTypeEnum.SAAS_DELIVERY.getCode().equals(createOrderVo.getMenuType())) {
            String s = this.checkDeliveryType(createOrderVo, storeCode, trackingNo);
            userDeliveryInfoDto.getStoreDeliveryInfoDto().setDeliveryType(s);
        }
        userDeliveryInfoDto.setReceiveUserName(receiveAddressResult.getReceiveName());
        userDeliveryInfoDto.setReceiveMobile(StringUtils.isEmpty(receiveAddressResult.getMobile()) ? receiveAddressResult.getReceiveMobile() : receiveAddressResult.getMobile());
        String receiveAddress = receiveAddressResult.getReceiveAddress();
        if (StringUtils.isNotBlank(receiveAddress)) {
            userDeliveryInfoDto.setReceiveAddress(receiveAddress);
            if (receiveAddress.contains("officeName") && receiveAddress.contains("address")) {
                JSONObject jsonObject = JSONObject.parseObject(receiveAddress);
                userDeliveryInfoDto.setReceiveOfficeName(jsonObject.getString("officeName"));
                userDeliveryInfoDto.setReceiveAddress(jsonObject.getString("address"));
            }
        }
        createOrderVo.setUserName(receiveAddressResult.getReceiveName());
        createOrderVo.setMobile(StringUtils.isEmpty(receiveAddressResult.getMobile()) ? receiveAddressResult.getReceiveMobile() : receiveAddressResult.getMobile());
        createOrderVo.setUserDeliveryInfoDto(userDeliveryInfoDto);
    }

    public String checkDeliveryType(CreateOrderBaseVo createOrderVo, String storeCode, String trackingNo) {
        String code = "";
        QueryDeliveryRequest request = new QueryDeliveryRequest();
        request.setStoreCode(storeCode);
        request.setPartnerId(createOrderVo.getPartnerId());
        request.setUserLatitude(createOrderVo.getLatitude());
        request.setUserLongitude(createOrderVo.getLongitude());
        BaseResponse<QueryDeliverDetailResponse> query = storeCenterService.queryDeliverDetail(request, trackingNo);
        if (null == query || !ResponseResult.SUCCESS.getCode().equals(query.getCode())) {
            throw new ServiceException(ResponseResult.STORE_DDELIVERY_METHOD);
        }
        String method = query.getData().getDeliveryMethod();
        //StoreDeliveryMethod.
        code = StoreDeliveryMethod.getCodeByType(method);
        if (StringUtils.isBlank(code)) {
            throw new ServiceException(ResponseResult.STORE_DDELIVERY_METHOD);
        }
        return code;
    }

    /**
     * 获取门店配送信息
     */
    public StoreDeliveryInfoDto getStoreDeliveryInfo(StoreResponse.BizVO storeResponseDto,
                                                     AssortmentOpenPlatformIappWxappConfig openPlatformIappWxappConfig, String wxAppid) {
        StoreDeliveryInfoDto storeDeliveryInfoDto = new StoreDeliveryInfoDto();
        storeDeliveryInfoDto.setPartnerId(storeResponseDto.getPartnerId());
        storeDeliveryInfoDto.setStoreId(storeResponseDto.getStoreCode());
        storeDeliveryInfoDto.setStoreName(storeResponseDto.getStoreName());
        storeDeliveryInfoDto.setStoreNameEn(storeResponseDto.getStoreNameEn());
        // 查询外卖配送信息
        AssortmentOpenPlatformPartnerStoreDeliveryConfig deliveryConfig = deliveryConfigManager.findByPartnerIdAndStoreCode(storeResponseDto.getPartnerId(),
                storeResponseDto.getStoreCode());
        if (deliveryConfig == null) {
            throw new ServiceException(ResponseResult.STORE_ITEM_NOT_DELIVERY);
        }
        // 判断门店是否启用外卖，只有当小程序开通外卖，且门店开通外卖,设置 外卖配送时间 才开启外卖功能
        storeDeliveryInfoDto.setDeliveryLimitAmount(deliveryConfig == null ? 0 : deliveryConfig.getDeliveryLimitAmount());
        storeDeliveryInfoDto.setDeliveryAmount(deliveryConfig == null ? 0 : deliveryConfig.getDeliveryAmount());
        storeDeliveryInfoDto.setDefaultDeliveryRange(deliveryConfig == null ? 0L : deliveryConfig.getDefaultDeliveryRange());
        storeDeliveryInfoDto.setAddRangeAmount(deliveryConfig == null ? 0L : deliveryConfig.getAddRangeAmount());
        storeDeliveryInfoDto.setAddRangeCount(deliveryConfig == null ? 0L : deliveryConfig.getAddRangeCount());
        storeDeliveryInfoDto.setPoint2DList(getDeliveryPoint2DList(storeResponseDto.getDistributionScope()));
        storeDeliveryInfoDto.setDeliveryHoursDay(storeResponseDto.getDeliveryHoursDay());
        storeDeliveryInfoDto.setLongitude(storeResponseDto.getLongitude());
        storeDeliveryInfoDto.setLatitude(storeResponseDto.getLatitude());
        storeDeliveryInfoDto.setScopeConfig(storeResponseDto.getScopeConfig());
        if (StringUtils.isNotEmpty(storeResponseDto.getDeliveryRadius())) {
            storeDeliveryInfoDto.setDeliveryRadius(Integer.valueOf(storeResponseDto.getDeliveryRadius()));
        } else {
            storeDeliveryInfoDto.setDeliveryRadius(0);
        }
        // 只有小程序设置了外卖，并且开通了第三方配送账户，才是第三方配送单
        if (openPlatformIappWxappConfig == null) {
            openPlatformIappWxappConfig = openPlatformIappWxappConfigManager.selectIappWxappConfigByWxAppId(wxAppid);
        }
        if (openPlatformIappWxappConfig == null) {
            storeDeliveryInfoDto.setDeliveryType("self");
            storeDeliveryInfoDto.setPushOrderTime(0);
        } else {
            //如果是coco查询配送服务判断是平台配送还是自配送
            if (cocoPartnerId.equals(storeResponseDto.getPartnerId())) {
                GetDeliveryFlagRequest getDeliveryFlagRequest = new GetDeliveryFlagRequest();
                getDeliveryFlagRequest.setPartnerId(storeResponseDto.getPartnerId());
                getDeliveryFlagRequest.setStoreId(storeResponseDto.getStoreId());
                DeliveryBaseResponse<GetDeliveryFlagResponseDto> deliveryBaseResponse = deliveryFeiginClient.getThirdDeliveryFlag(getDeliveryFlagRequest);
                if (deliveryBaseResponse.getCode() == 100 && deliveryBaseResponse.getData() != null && deliveryBaseResponse.getData().isThirdDeliveryFlag()) {
                    storeDeliveryInfoDto.setDeliveryType("third");
                    storeDeliveryInfoDto.setPushOrderTime(0);
                } else {
                    storeDeliveryInfoDto.setDeliveryType("self");
                    storeDeliveryInfoDto.setPushOrderTime(0);
                }
            } else {
                if (ObjectUtils.equals(openPlatformIappWxappConfig.getTakeType(), 1)) {
                    storeDeliveryInfoDto.setDeliveryType("self");
                    storeDeliveryInfoDto.setPushOrderTime(0);
                } else {
                    storeDeliveryInfoDto.setDeliveryType("third");
                    storeDeliveryInfoDto.setPushOrderTime(0);
                }
            }
        }
        return storeDeliveryInfoDto;
    }

    /**
     * 获取门店配送信息
     */
    public StoreDeliveryInfoDto getNewStoreDeliveryInfo(StoreResponse.BizVO storeResponseDto,
                                                        AssortmentOpenPlatformIappWxappConfig openPlatformIappWxappConfig, String wxAppid, String trackingNo) {
        StoreDeliveryInfoDto storeDeliveryInfoDto = new StoreDeliveryInfoDto();
        storeDeliveryInfoDto.setPartnerId(storeResponseDto.getPartnerId());
        storeDeliveryInfoDto.setStoreId(storeResponseDto.getStoreCode());
        storeDeliveryInfoDto.setStoreName(storeResponseDto.getStoreName());
        // 查询外卖配送信息
        QueryDeliveryRequest queryDeliveryRequest = new QueryDeliveryRequest();
        queryDeliveryRequest.setPartnerId(storeResponseDto.getPartnerId());
        queryDeliveryRequest.setStoreCode(storeResponseDto.getStoreCode());
        BaseResponse<QueryDeliverDetailResponse> queryDeliverDetailResponse = storeCenterService.queryDeliverDetail(queryDeliveryRequest, trackingNo);
        if (queryDeliverDetailResponse == null || !ResponseResult.SUCCESS.getCode().equals(queryDeliverDetailResponse.getCode()) || queryDeliverDetailResponse.getData() == null) {
            throw new ServiceException(ResponseResult.STORE_ITEM_NOT_DELIVERY);
        }
        QueryDeliverDetailResponse deliveryDetail = queryDeliverDetailResponse.getData();
        // 判断门店是否启用外卖，只有当小程序开通外卖，且门店开通外卖,设置 外卖配送时间 才开启外卖功能
        storeDeliveryInfoDto.setDeliveryLimitAmount(StringUtils.isBlank(deliveryDetail.getMinOrderPrice()) ? 0L : Long.parseLong(deliveryDetail.getMinOrderPrice()));
        storeDeliveryInfoDto.setDeliveryAmount(StringUtils.isBlank(deliveryDetail.getDeliveryFee()) ? 0L : Long.parseLong(deliveryDetail.getDeliveryFee()));
        storeDeliveryInfoDto.setDefaultDeliveryRange(StringUtils.isBlank(deliveryDetail.getDeliveryRange()) ? 0L : Long.parseLong(deliveryDetail.getDeliveryRange()));
        storeDeliveryInfoDto.setAddRangeAmount(StringUtils.isBlank(deliveryDetail.getAddRangeAmount()) ? 0L : Long.parseLong(deliveryDetail.getAddRangeAmount()));
        storeDeliveryInfoDto.setAddRangeCount(StringUtils.isBlank(deliveryDetail.getAddRange()) ? 0L : Long.parseLong(deliveryDetail.getAddRange()));
        storeDeliveryInfoDto.setPoint2DList(getDeliveryPoint2DList(storeResponseDto.getDistributionScope()));
        storeDeliveryInfoDto.setDeliveryHoursDay(storeResponseDto.getDeliveryHoursDay());
        storeDeliveryInfoDto.setLongitude(storeResponseDto.getLongitude());
        storeDeliveryInfoDto.setLatitude(storeResponseDto.getLatitude());
        storeDeliveryInfoDto.setScopeConfig(storeResponseDto.getScopeConfig());
        if (StringUtils.isNotEmpty(storeResponseDto.getDeliveryRadius())) {
            storeDeliveryInfoDto.setDeliveryRadius(Integer.valueOf(storeResponseDto.getDeliveryRadius()));
        } else {
            storeDeliveryInfoDto.setDeliveryRadius(0);
        }
        // 只有小程序设置了外卖，并且开通了第三方配送账户，才是第三方配送单
        if (openPlatformIappWxappConfig == null) {
            openPlatformIappWxappConfig = openPlatformIappWxappConfigManager.selectIappWxappConfigByWxAppId(wxAppid);
        }
        if (openPlatformIappWxappConfig == null) {
            storeDeliveryInfoDto.setDeliveryType("self");
            storeDeliveryInfoDto.setPushOrderTime(0);
        } else {
            //如果是coco查询配送服务判断是平台配送还是自配送
            if (cocoPartnerId.equals(storeResponseDto.getPartnerId())) {
                GetDeliveryFlagRequest getDeliveryFlagRequest = new GetDeliveryFlagRequest();
                getDeliveryFlagRequest.setPartnerId(storeResponseDto.getPartnerId());
                getDeliveryFlagRequest.setStoreId(storeResponseDto.getStoreId());
                DeliveryBaseResponse<GetDeliveryFlagResponseDto> deliveryBaseResponse = deliveryFeiginClient.getThirdDeliveryFlag(getDeliveryFlagRequest);
                if (deliveryBaseResponse.getCode() == 100 && deliveryBaseResponse.getData() != null && deliveryBaseResponse.getData().isThirdDeliveryFlag()) {
                    storeDeliveryInfoDto.setDeliveryType("third");
                    storeDeliveryInfoDto.setPushOrderTime(0);
                } else {
                    storeDeliveryInfoDto.setDeliveryType("self");
                    storeDeliveryInfoDto.setPushOrderTime(0);
                }
            } else {
                if (ObjectUtils.equals(openPlatformIappWxappConfig.getTakeType(), 1)) {
                    storeDeliveryInfoDto.setDeliveryType("self");
                    storeDeliveryInfoDto.setPushOrderTime(0);
                } else {
                    storeDeliveryInfoDto.setDeliveryType("third");
                    storeDeliveryInfoDto.setPushOrderTime(0);
                }
            }
        }
        storeDeliveryInfoDto.setDeliveryCondition(deliveryDetail.getDeliveryType());
        storeDeliveryInfoDto.setFreeDeliveryCup(deliveryDetail.getFreeDeliveryCup());
        return storeDeliveryInfoDto;
    }

    /**
     * 获取配送范围内集合
     */
    public List<Point2D.Double> getDeliveryPoint2DList(String distributionScope) {
        if (StringUtils.isBlank(distributionScope)) {
            return Collections.emptyList();
        }
        /**
         * 如果点不为整数，返回空
         */
        String[] points = distributionScope.split(",");
        if (points.length % 2 != 0) {
            return Collections.emptyList();
        }
        List<String> pointList = Arrays.asList(points);
        List<Point2D.Double> point2DList = Lists.newArrayList();
        for (int i = 0; i < pointList.size(); i++) {
            Double pointX = Double.parseDouble(pointList.get(i));
            Double pointY = Double.parseDouble(pointList.get(++i));
            point2DList.add(new Point2D.Double(pointX, pointY));
        }
        return point2DList;
    }

    public void checkOrderExpectTime(CreateOrderBaseVo createOrderVo, StoreResponse.BizVO storeResponseDto, Date takeMealDateTime) {
        if (takeMealDateTime == null) {
            return;
        }
        //获取门店当天营业时间
        Date todayEndDate = null;
        List<String> todayBusinessTimes = storeCenterService.getTodayBusinessTime(Integer.parseInt(storeResponseDto.getBusinessType()), storeResponseDto.getBusinessHoursDay());
        if (CollectionUtils.isEmpty(todayBusinessTimes)) {
            throw new ServiceException(ResponseResult.STORE_BUSINESS_HOUR_ERROR);
        }
        BusinessDate businessDate = getStoreBusinessDate(todayBusinessTimes.get(todayBusinessTimes.size() - 1), true);
        todayEndDate = businessDate.getEndDate();
        //在当天营业时间内
        boolean expectTimeInTodayBusinessTime = true;
        Date date = new Date();
        Date newDate = DateUtil.convert2Date(date, DateUtil.FORMAT_yyyyMMdd_date);
        newDate = DateUtil.addDays(newDate, 1);
        //隔天预约(在明日凌晨之后且在门店营业结束之后)
        if (takeMealDateTime.after(todayEndDate) && takeMealDateTime.after(newDate)) {
            expectTimeInTodayBusinessTime = false;
        }
        if (expectTimeInTodayBusinessTime) {
            boolean inTodayBusinessTime = true;
            for (String todayTime : todayBusinessTimes) {
                //每段营业时间校验
                BusinessDate businessDate2 = getStoreBusinessDate(todayTime, true);
                if (takeMealDateTime.getTime() >= businessDate2.getStartDate().getTime()
                        && takeMealDateTime.getTime() <= businessDate2.getEndDate().getTime()) {
                    inTodayBusinessTime = false;
                    break;
                }
            }
            if (inTodayBusinessTime) {
                throw new ServiceException(ResponseResult.ORDER_TAKEMEALTIME_INVAILD);
            }
        }
        //隔天预约
        if (!expectTimeInTodayBusinessTime) {
            List<String> nextDayBusinessTimes = storeCenterService.getNextDayBusinessTime(Integer.parseInt(storeResponseDto.getBusinessType()), storeResponseDto.getBusinessHoursDay());
            boolean inNextDayBusinessTime = true;
            for (String nextDayTime : nextDayBusinessTimes) {
                BusinessDate storeNextBusinessDate = getStoreBusinessDate(nextDayTime, false);
                if (takeMealDateTime.getTime() >= storeNextBusinessDate.getStartDate().getTime()
                        && takeMealDateTime.getTime() <= storeNextBusinessDate.getEndDate().getTime()) {
                    inNextDayBusinessTime = false;
                    break;
                }
            }
            if (inNextDayBusinessTime) {
                throw new ServiceException(ResponseResult.ORDER_TAKEMEALTIME_INVALID);
            }
        }

        if (CreateOrderType.TAKE_OUT.getCode().equals(createOrderVo.getOrderType())) {
            checkTakeOutTime(storeResponseDto, date, takeMealDateTime, expectTimeInTodayBusinessTime);
        }
    }

    /**
     * 检验订单是否在外卖时间内
     *
     * @param storeResponseDto              店铺信息
     * @param now                           当前时间
     * @param takeMealDateTime              预约单送达时间/即时单下单时间
     * @param expectTimeInTodayBusinessTime 是否在当日营业时间内
     */
    protected void checkTakeOutTime(StoreResponse.BizVO storeResponseDto, Date now, Date takeMealDateTime, boolean expectTimeInTodayBusinessTime) {
        String deliveryStr = storeResponseDto.getDeliveryHoursDay().replace("-", ",")
                .replace("_", ",");
        String[] deliverys = deliveryStr.split(",");
        Date deliveryStartDate = null;
        Date deliveryEndDate = null;
        if (deliverys.length == 2) {
            SimpleDateFormat hhmmss = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            SimpleDateFormat yyyyMMdd = new SimpleDateFormat("yyyy-MM-dd");
            String startDateTimeStr = yyyyMMdd.format(now) + " " + deliverys[0] + ":00";
            String endDateTimeStr = yyyyMMdd.format(now) + " " + deliverys[1] + ":00";
            try {
                deliveryStartDate = hhmmss.parse(startDateTimeStr);
                deliveryEndDate = hhmmss.parse(endDateTimeStr);
            } catch (ParseException e) {
                AppLogUtil.errorLog("getStoreDeliveryInfo_error", endDateTimeStr, null,e);
            }
        }
        if (deliveryStartDate == null || deliveryEndDate == null) {
            throw new ServiceException(ResponseResult.ORDER_CREATE_TIME_NOT_DELIVERY);
        }
        // 校验预约配送时间
        if (expectTimeInTodayBusinessTime && (takeMealDateTime.before(deliveryStartDate) || takeMealDateTime.after(deliveryEndDate))) {
            throw new ServiceException(ResponseResult.ORDER_CREATE_TIME_NOT_DELIVERY);
        }
        Date nextDeliveryStartDate = DateUtil.addDays(deliveryStartDate, 1);
        Date nextDeliveryEndDate = DateUtil.addDays(deliveryEndDate, 1);
        // 隔日预约外卖校验预约配送时间
        if (!expectTimeInTodayBusinessTime && (takeMealDateTime.before(nextDeliveryStartDate) || takeMealDateTime.after(nextDeliveryEndDate))) {
            throw new ServiceException(ResponseResult.ORDER_CREATE_TIME_NOT_DELIVERY);
        }
    }

    public Date getOrderExpectTime(String takeMealFlag, String takeMealTimes, String expectTime,
                                   CreateOrderType createOrderType, Integer serviceTime, StoreResponse.BizVO storeResponseDto) {
        Date takeMealDateTime = null;
        //0=到店单我已到店、外卖单尽快送出
        if (StringUtils.isNotBlank(takeMealFlag) && "0".equals(takeMealFlag)) {
            return takeMealDateTime;
        }
        if (StringUtils.isBlank(takeMealTimes) && StringUtils.isBlank(expectTime)) {
            return takeMealDateTime;
        }
        //兼容门店隔日预约单格式修改，HH:mm变yyyy-MM-dd HH:mm，前端未升级，未按要求传
        if (StringUtils.isNotBlank(takeMealTimes) && takeMealTimes.length() > 5) {
            expectTime = takeMealTimes + ":00";
        }

        Date date = new Date();
        //takeMealTimes格式必须为HH:mm
        if (StringUtils.isNotBlank(takeMealTimes) && takeMealTimes.length() <= 5) {
            StringBuffer takeMealTime = new StringBuffer("");
            takeMealTime = takeMealTime.append(DateUtil.convert2String(date, "yyyy-MM-dd"))
                    .append(" ").append(takeMealTimes).append(":00");
            takeMealDateTime = DateUtil.convert2Date(takeMealTime.toString(), "yyyy-MM-dd HH:mm:ss");
            Date newDate = DateUtil.convert2Date(date, DateUtil.FORMAT_yyyyMMdd_date);
            newDate = DateUtil.addDays(newDate, 1);

            //获取门店当天营业结束时间
            Date todayEndDate = null;
            List<String> todayBusinessTimes = storeCenterService.getTodayBusinessTime(Integer.parseInt(storeResponseDto.getBusinessType()), storeResponseDto.getBusinessHoursDay());
            if (CollectionUtils.isEmpty(todayBusinessTimes)) {
                throw new ServiceException(ResponseResult.STORE_BUSINESS_HOUR_ERROR);
            }
            BusinessDate businessDate = getStoreBusinessDate(todayBusinessTimes.get(todayBusinessTimes.size() - 1), true);
            todayEndDate = businessDate.getEndDate();

            //隔天营业的预约时间处理  计算出预约时间在当前时间之前，预约时间加1天 newDate.before(todayEndDate)=隔天营业
            if (takeMealDateTime != null && takeMealDateTime.before(date) && newDate.before(todayEndDate)) {
                takeMealDateTime = DateUtil.addDays(takeMealDateTime, 1);
            }
        }
        if (StringUtils.isNotBlank(expectTime)) {
            takeMealDateTime = DateUtil.convert2Date(expectTime, "yyyy-MM-dd HH:mm:ss");
        }
        //当顾客指定送达时间小于当前时间,订单记录类型为即时单
        if (takeMealDateTime != null && takeMealDateTime.before(date)) {
            takeMealDateTime = null;
        }
        //当顾客指定送达时间小于当前时间+提前预约时间时，订单记录类型为即时单
        if (CreateOrderType.TAKE_OUT.equals(createOrderType) && takeMealDateTime != null
                && serviceTime != null && takeMealDateTime.before(DateUtil.addMinutes(date, serviceTime))) {
            takeMealDateTime = null;
        }
        return takeMealDateTime;
    }

    /**
     * 获取门店营业时间
     *
     * @param storeResponseDto
     * @param toDay            true 今日,false 明天
     * @return
     */
    protected BusinessDate getStoreBusinessDate(StoreResponse.BizVO storeResponseDto, boolean toDay) {
        List<String> todayBusinessTimes = storeCenterService.getTodayBusinessTime(Integer.parseInt(storeResponseDto.getBusinessType()), storeResponseDto.getBusinessHoursDay());
        if (CollectionUtils.isEmpty(todayBusinessTimes)) {
            throw new ServiceException(ResponseResult.STORE_BUSINESS_HOUR_ERROR);
        }
        BusinessDate businessDate = getStoreBusinessDate(todayBusinessTimes.get(todayBusinessTimes.size() - 1), toDay);
        return businessDate;
    }

    public void checkOrderExpectTime(CreateOrderVo createOrderVo, StoreResponse.BizVO storeResponseDto, Date takeMealDateTime) {
        if (takeMealDateTime == null) {
            return;
        }
        //获取门店当天营业时间
        Date todayEndDate = null;
        List<String> todayBusinessTimes = storeCenterService.getTodayBusinessTime(Integer.parseInt(storeResponseDto.getBusinessType()), storeResponseDto.getBusinessHoursDay());
        if (CollectionUtils.isEmpty(todayBusinessTimes)) {
            throw new ServiceException(ResponseResult.STORE_BUSINESS_HOUR_ERROR);
        }
        BusinessDate businessDate = getStoreBusinessDate(todayBusinessTimes.get(todayBusinessTimes.size() - 1), true);
        todayEndDate = businessDate.getEndDate();
        //在当天营业时间内
        boolean expectTimeInTodayBusinessTime = true;
        Date date = new Date();
        Date newDate = DateUtil.convert2Date(date, DateUtil.FORMAT_yyyyMMdd_date);
        newDate = DateUtil.addDays(newDate, 1);
        //隔天预约(在明日凌晨之后且在门店营业结束之后)
        if (takeMealDateTime.after(todayEndDate) && takeMealDateTime.after(newDate)) {
            expectTimeInTodayBusinessTime = false;
        }
        if (expectTimeInTodayBusinessTime) {
            boolean inTodayBusinessTime = true;
            for (String todayTime : todayBusinessTimes) {
                //每段营业时间校验
                BusinessDate businessDate2 = getStoreBusinessDate(todayTime, true);
                if (takeMealDateTime.getTime() >= businessDate2.getStartDate().getTime()
                        && takeMealDateTime.getTime() <= businessDate2.getEndDate().getTime()) {
                    inTodayBusinessTime = false;
                    break;
                }
            }
            if (inTodayBusinessTime) {
                throw new ServiceException(ResponseResult.ORDER_TAKEMEALTIME_INVAILD);
            }
        }
        //隔天预约
        if (!expectTimeInTodayBusinessTime) {
            List<String> nextDayBusinessTimes = storeCenterService.getNextDayBusinessTime(Integer.parseInt(storeResponseDto.getBusinessType()), storeResponseDto.getBusinessHoursDay());
            boolean inNextDayBusinessTime = true;
            for (String nextDayTime : nextDayBusinessTimes) {
                BusinessDate storeNextBusinessDate = getStoreBusinessDate(nextDayTime, false);
                if (takeMealDateTime.getTime() >= storeNextBusinessDate.getStartDate().getTime()
                        && takeMealDateTime.getTime() <= storeNextBusinessDate.getEndDate().getTime()) {
                    inNextDayBusinessTime = false;
                    break;
                }
            }
            if (inNextDayBusinessTime) {
                throw new ServiceException(ResponseResult.ORDER_TAKEMEALTIME_INVALID);
            }
        }

        if (CreateOrderType.TAKE_OUT.getCode().equals(createOrderVo.getOrderType())) {
            checkTakeOutTime(storeResponseDto, date, takeMealDateTime, expectTimeInTodayBusinessTime);
        }
    }

    public BusinessDate getStoreBusinessDate(String businessHoursDay, boolean today) {
        BusinessDate businessDate = new BusinessDate();
        //设置营业开始和结束时间
        String businessHourStr = businessHoursDay.replace("-", ",").replace("_", ",");
        String[] businessHours = businessHourStr.split(",");
        if (businessHours.length != 2) {
            throw new ServiceException(ResponseResult.STORE_NOT_FOUND);
        }
        Date date = new Date();
        if (!today) {
            date = DateUtil.addDays(date, 1);
        }
        String startDateTimeStr = DateUtil.convert2String(date, DateUtil.FORMAT_YMD) + " " + businessHours[0] + ":00";
        String endDateTimeStr = DateUtil.convert2String(date, DateUtil.FORMAT_YMD) + " " + businessHours[1] + ":00";
        Date startDateTime;
        Date endDateTime;
        startDateTime = DateUtil.convert2Date(startDateTimeStr, DateUtil.FORMAT_YYYY_MM_DD_HHMMSS);
        SimpleDateFormat hhmmss = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            endDateTime = hhmmss.parse(endDateTimeStr);
        } catch (ParseException e) {
            throw new ServiceException(ResponseResult.STORE_BUSINESS_HOUR_ERROR);
        }
        //隔天营业时间处理
        if (startDateTime.after(endDateTime)) {
            endDateTime = DateUtil.addDays(endDateTime, 1);
        }
        // 校验门店是否打烊，打烊了则不让操作
        if (startDateTime == null || endDateTime == null) {
            throw new ServiceException(ResponseResult.STORE_ITEM_STOP_BUSINESS);
        }
        businessDate.setStartDate(startDateTime);
        businessDate.setEndDate(endDateTime);
        return businessDate;
    }


    /**
     * 判断是否为拼单订单
     *
     * @param createOrderVo
     * @return
     */
    private boolean isCollageOrder(CreateOrderBaseVo createOrderVo) {
        return createOrderVo.getMarketingType() != null && OrderMarketType.COLLAGE.getIndex() == createOrderVo.getMarketingType();
    }


}
