/**
 * 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.impl;

import cn.freemud.base.constant.Version;
import cn.freemud.base.util.DateUtil;
import cn.freemud.constant.ResponseCodeConstant;
import cn.freemud.constant.StoreConstant;
import cn.freemud.entities.dto.*;
import cn.freemud.entities.dto.delivery.MCCafeDeliveryBaseResponse;
import cn.freemud.entities.dto.delivery.MCCafeDeliveryGetStoreIdResponse;
import cn.freemud.enums.*;
import cn.freemud.management.entities.dto.request.order.MCCafeCouponRequest;
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.*;
import cn.freemud.interceptor.ServiceException;
import cn.freemud.management.entities.dto.request.order.MCCafeCouponVo;
import cn.freemud.management.entities.dto.response.coupon.McdNetBatchQueryResponse;
import cn.freemud.manager.StoreTableNumberManager;
import cn.freemud.service.CouponService;
import cn.freemud.service.mccafe.CouponClientService;
import cn.freemud.service.mccafe.thirdparty.DeliveryFeiginMCCafeClient;
import cn.freemud.service.mccafe.thirdparty.DeliveryServiceFeiginMCCafeClient;
import cn.freemud.service.thirdparty.ShoppingCartClient;
import cn.freemud.service.thirdparty.StockClient;
import cn.freemud.utils.LogUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.freemud.api.assortment.datamanager.entity.db.AssortmentOpenPlatformIappWxappConfig;
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.api.assortment.datamanager.manager.customer.AssortmentCustomerInfoManager;
import com.freemud.application.sdk.api.base.BaseResponse;
import com.freemud.application.sdk.api.couponcenter.offline.response.CouponQueryResponse;
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.ordercenter.constant.ResponseConstant;
import com.freemud.application.sdk.api.ordercenter.enums.OrderClientType;
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.google.common.collect.Lists;
import com.google.gson.Gson;
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.Component;

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

@Component
public class CheckMCCafeOrder {

    @Autowired
    private StoreTableNumberManager storeTableNumberManager;
    @Autowired
    private AssortmentOpenPlatformIappWxappConfigManager openPlatformIappWxappConfigManager;
    @Autowired
    private AssortmentOpenPlatformPartnerStoreDeliveryConfigManager deliveryConfigManager;
    // 缓存取用户数据用
//    @Autowired
//    private UserServiceImpl userService;
    @Autowired
    private AssortmentCustomerInfoManager customerInfoManager;
    //门店SDK
    @Autowired
    private StoreCenterService storeCenterService;
    //会员SDK
    @Autowired
    private MemberCenterService memberCenterService;
    //会员SDK
    @Autowired
    private MemberPropertyService memberPropertyService;
    @Autowired
    private ShoppingCartClient shoppingCartClient;
    //    @Autowired
//    private OrderAdapter orderAdapter;
    @Autowired
    private StoreServiceImpl storeService;
    @Autowired
    private StockClient stockClient;
    @Autowired
    private ItemServiceImpl itemService;
    @Autowired
    private CouponService couponService;
    @Autowired
    private CouponClientService couponClientService;
    @Autowired
    private DeliveryFeiginMCCafeClient deliveryFeiginMCCafeClient;
    @Autowired
    private DeliveryServiceFeiginMCCafeClient deliveryServiceFeiginMCCafeClient;

    private static Gson gson = new Gson();
    /**
     * 下单会员相关校验
     */
    public AssortmentCustomerInfoVo checkOrderByMember(CreateOrderVo createOrderVo, String trackingNo) {
        // 通过sessionId查询缓存中会员id
        String sessionId = createOrderVo.getSessionId();
        AssortmentCustomerInfoVo userLoginInfoDto = customerInfoManager.getCustomerInfoByObject(sessionId);
        if (userLoginInfoDto == null || StringUtils.isEmpty(userLoginInfoDto.getMemberId())) {
            throw new ServiceException(ResponseResult.NOT_LOGIN);
        }

        createOrderVo.setUserId(userLoginInfoDto.getMemberId());
        return userLoginInfoDto;
    }


    public AssortmentCustomerInfoVo checkOrderByMemberNew(String sessionId, String cardCode) {
        // 通过sessionId查询缓存中会员id
        AssortmentCustomerInfoVo userLoginInfoDto = customerInfoManager.getCustomerInfoByObject(sessionId);
        if (userLoginInfoDto == null || StringUtils.isEmpty(userLoginInfoDto.getMemberId())) {
            throw new ServiceException(ResponseResult.NOT_LOGIN);
        }
        //校验会员svc卡信息
        checkCardCode(userLoginInfoDto.getPartnerId(),userLoginInfoDto.getMemberId(),cardCode);
        return userLoginInfoDto;
    }

    /**
     * 下单门店相关校验
     */
    public StoreResponse.BizVO checkOrderByStore(CreateOrderVo createOrderVo, String trackingNo) {
        String partnerId = createOrderVo.getPartnerId();
        String shopId = createOrderVo.getShopId();

        // 获取门店信息
        StoreInfoRequest storeInfoRequest = new StoreInfoRequest(partnerId, shopId,null);
        StoreResponse storeResponse = storeCenterService.getStoreInfo(storeInfoRequest, trackingNo);
        if (storeResponse == null || storeResponse.getBizVO() == null) {
            throw new ServiceException(ResponseResult.STORE_NOT_FOUND);
        }
        StoreResponse.BizVO storeResponseDto = storeResponse.getBizVO();
        // 校验门店是否营业
        if (storeResponseDto.getActiveFlag() == null || storeResponseDto.getActiveFlag() != 1 || storeResponseDto.getState() == null || storeResponseDto.getState().equals("3")) {
            throw new ServiceException(ResponseResult.STORE_CLOSED_FOREVER);
        }
        if (storeResponseDto.getActiveFlag() == 1 && storeResponseDto.getState().equals("2")) {
            throw new ServiceException(ResponseResult.STORE_CLOSED_THE_NIGHT);
        }
        createOrderVo.setStoreName(storeResponseDto.getStoreName());
        createOrderVo.setStoreAddress(storeResponseDto.getAddress());
        createOrderVo.setThirdShopId(storeResponseDto.getThirdPartCode());
        return storeResponseDto;
    }

    /**
     * 下单订单类型校验
     */
    public Integer checkOrderByOrderType(CreateOrderVo createOrderVo, AssortmentCustomerInfoVo userLoginInfoDto,
                                         StoreResponse.BizVO storeResponseDto, ShoppingCartGoodsDto shoppingCartGoodsDto, String trackingNo) {
        Integer pushOrderTime = 0;
        //非到店或者外卖，类型错误
        if (!(CreateOrderType.COLLECT_GOODS.getCode().equals(createOrderVo.getOrderType()) ||
                CreateOrderType.TAKE_OUT.getCode().equals(createOrderVo.getOrderType()))) {
            throw new ServiceException(ResponseResult.PARAMETER_MISSING);
        }

        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.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 = getNewStoreDeliveryInfo(storeResponseDto, config, appId, trackingNo);

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


        //下单时间校验
        String takeMealFlag = createOrderVo.getTakeMealFlag();
        String takeMealTime = createOrderVo.getTakeMealTime();
        String expectTime = createOrderVo.getExpectTime();
        Date now = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdf.setLenient(false);

        //立即送达
        if("0".equals(takeMealFlag)) {
            //未营业无预约时间无法下单
            if (!StoreConstant.BUSINESS.equals(storeResponseDto.getState())) {
                throw new ServiceException(ResponseResult.STORE_ITEM_CHECK_CLOSE);
            }
            createOrderVo.setExpectTime(null);
            // 校验下单时间是否在营业时间内
            checkOrderExpectTime(storeResponseDto, now);
            // 外卖单选择立即送达的话，下单时间必须在店铺外卖时间内
            if(createOrderVo.getOrderType().compareTo(CreateOrderType.TAKE_OUT.getCode()) == 0) {
                checkTakeOutTime(storeResponseDto, now);
            }
        }
        //有预约时间的自提单
        else if(CreateOrderType.COLLECT_GOODS.getCode().equals(createOrderVo.getOrderType()) && StringUtils.isNotBlank(takeMealTime)) {
            // 设置预约时间
            Integer minute = 0;
            try {
                minute = Integer.parseInt(takeMealTime);
            } catch (Exception e) {
                throw new ServiceException(ResponseResult.ORDER_TAKE_MEAL_TIME_ERROR);
            }
            if(null == minute || 0 == minute) {
                throw new ServiceException(ResponseResult.ORDER_TAKE_MEAL_TIME_ERROR);
            }

            Calendar calendar = Calendar.getInstance();
            calendar.setTime(now);
            calendar.add(Calendar.MINUTE, minute);
            Date takeMealDateTime = calendar.getTime();

            //当顾客指定送达时间小于当前时间,订单记录类型为即时单
            if (takeMealDateTime != null && takeMealDateTime.before(now)) {
                takeMealDateTime = null;
            }

            if(takeMealDateTime != null){
                //校验营业时间
                checkOrderExpectTime(storeResponseDto, takeMealDateTime);
                //重新赋值为yyyy-MM-dd HH:mm:ss格式字符串时间
                createOrderVo.setExpectTime(DateUtil.convert2String(takeMealDateTime, "yyyy-MM-dd HH:mm:ss"));
            } else {
                createOrderVo.setExpectTime(null);
            }
        }
        //有预约时间的外卖单
        else if(CreateOrderType.TAKE_OUT.getCode().equals(createOrderVo.getOrderType()) && StringUtils.isNotBlank(expectTime)) {
            Date takeOutDateTime = null;
            try {
                takeOutDateTime = sdf.parse(createOrderVo.getExpectTime()+":00");
            } catch (ParseException e) {
                try {
                    takeOutDateTime = sdf.parse(createOrderVo.getExpectTime());
                } catch (ParseException parseException) {
                    throw new ServiceException(ResponseResult.ORDER_TAKE_OUT_TIME_ERROR);
                }
            }

            //当顾客指定送达时间小于当前时间,订单记录类型为即时单
            if (takeOutDateTime != null && takeOutDateTime.before(now)) {
                takeOutDateTime = null;
            }
            //当顾客指定送达时间小于当前时间+提前预约时间时，订单记录类型为即时单
            if (takeOutDateTime != null && storeResponseDto.getServiceTime() != null
                    && takeOutDateTime.before(DateUtil.addMinutes(now, storeResponseDto.getServiceTime()))) {
                takeOutDateTime = null;
            }
            if(takeOutDateTime != null) {
                //校验营业时间
                checkOrderExpectTime(storeResponseDto, takeOutDateTime);
                //校验外卖时间
                checkTakeOutTime(storeResponseDto, takeOutDateTime);
                //重新赋值为yyyy-MM-dd HH:mm:ss格式字符串时间
                createOrderVo.setExpectTime(DateUtil.convert2String(takeOutDateTime, "yyyy-MM-dd HH:mm:ss"));
            } else {
                createOrderVo.setExpectTime(null);
            }
        } else {
            throw new ServiceException(ResponseResult.ORDER_MEALTIME_MISSING);
        }
        return pushOrderTime;
    }

    public void checkOrderExpectTime(StoreResponse.BizVO storeResponseDto, Date takeMealDateTime) {
        if (takeMealDateTime == null) {
            return;
        }
        //获取门店预约当天营业时间
        List<String> businessTimes = storeCenterService.getBusinessTimeByDate(com.freemud.application.sdk.api.util.DateUtil.convert2String
                (takeMealDateTime, com.freemud.application.sdk.api.util.DateUtil.FORMAT_yyyyMMdd_date), storeResponseDto.getBusinessHours());
        if (CollectionUtils.isEmpty(businessTimes)) {
            throw new ServiceException(ResponseResult.STORE_BUSINESS_HOUR_ERROR);
        }
        boolean inTodayBusinessTime = true;
        for (String businessTime : businessTimes) {
            //每段营业时间校验
            BusinessDate businessDate = getStoreBusinessDate(businessTime, takeMealDateTime, 1);
            if (takeMealDateTime.getTime() >= businessDate.getStartDate().getTime()
                    && takeMealDateTime.getTime() <= businessDate.getEndDate().getTime()) {
                inTodayBusinessTime = false;
                break;
            }
        }
        if (inTodayBusinessTime) {
            throw new ServiceException(ResponseResult.ORDER_TAKEMEALTIME_INVAILD);
        }
    }

    /**
     * 检验订单是否在外卖时间内
     * @param storeResponseDto 店铺信息
     * @param expectTime 预约单送达时间/即时单下单时间
     */
    private void checkTakeOutTime(StoreResponse.BizVO storeResponseDto, Date expectTime) {
        //获取门店预约当天外卖时间
        List<String> deliveryTimes = storeCenterService.getBusinessTimeByDate(com.freemud.application.sdk.api.util.DateUtil.convert2String
                (expectTime, com.freemud.application.sdk.api.util.DateUtil.FORMAT_yyyyMMdd_date), storeResponseDto.getDeliveryHours());
        if (CollectionUtils.isEmpty(deliveryTimes)) {
            throw new ServiceException(ResponseResult.STORE_BUSINESS_HOUR_ERROR);
        }
        boolean inTodayBusinessTime = true;
        for (String deliveryTime : deliveryTimes) {
            //每段营业时间校验
            BusinessDate deliveryDate = getStoreBusinessDate(deliveryTime, expectTime, 2);
            if (expectTime.getTime() >= deliveryDate.getStartDate().getTime()
                    && expectTime.getTime() <= deliveryDate.getEndDate().getTime()) {
                inTodayBusinessTime = false;
                break;
            }
        }
        if (inTodayBusinessTime) {
            throw new ServiceException(ResponseResult.ORDER_TAKEMEALTIME_INVAILD);
        }
    }

    /**
     *
     * @param businessHoursDay 营业时间段
     * @param date 点餐时间
     * @param dateType 时间类型 1营业时间 2外卖时间
     * @return
     */
    public BusinessDate getStoreBusinessDate(String businessHoursDay, Date date, Integer dateType){
        BusinessDate businessDate = new BusinessDate();
        //设置营业开始和结束时间
        String businessHourStr = businessHoursDay.replace("-", ",").replace("_", ",");
        String[] businessHours = businessHourStr.split(",");
        if (businessHours.length != 2) {
            throw new ServiceException(ResponseResult.STORE_NOT_FOUND);
        }
        String startDateTimeStr = DateUtil.convert2String(date, DateUtil.FORMAT_YMD) + " " + businessHours[0] + ":00";
        String endDateTimeStr = DateUtil.convert2String(date, DateUtil.FORMAT_YMD) + " " + businessHours[1] + ":00";
        Date startDateTime = DateUtil.convert2Date(startDateTimeStr, DateUtil.FORMAT_YYYY_MM_DD_HHMMSS);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdf.setLenient(true);
        Date endDateTime = null;
        try {
            endDateTime = sdf.parse(endDateTimeStr);
        } catch (ParseException e) {
            endDateTime = null;
        }
        if(null == startDateTime || null == endDateTime) {
            if(1 == dateType) {
                throw new ServiceException(ResponseResult.STORE_BUSINESS_HOUR_ERROR);
            } else {
                throw new ServiceException(ResponseResult.STORE_DELIVERY_HOUR_ERROR);
            }
        }
        businessDate.setStartDate(startDateTime);
        businessDate.setEndDate(endDateTime);
        return businessDate;
    }

    public ShoppingCartGoodsDto getShoppingCartGoodsDto(CreateOrderVo createOrderVo) {
        ShoppingCartInfoRequestVo.BuyMemberCard buyMemberCard = null;
        if (createOrderVo.getBuyMemberCard() != null) {
            buyMemberCard = new ShoppingCartInfoRequestVo.BuyMemberCard();
            buyMemberCard.setPaidId(createOrderVo.getBuyMemberCard().getPaidId());
            buyMemberCard.setRuleId(createOrderVo.getBuyMemberCard().getRuleId());
        }
        ShoppingCartInfoRequestVo shoppingCartInfoRequestVo = 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())
                .buyMemberCard(buyMemberCard)
                .menuType(createOrderVo.getMenuType())
                .build();
        // 如果使用优惠券或者商品券，校验 couponCode
        if (StringUtils.isNotBlank(createOrderVo.getCouponCode())) {
            // 校验couponCode
            GetCouponDetailResponseDto getCouponDetailResponseDto = couponService.getMemberCoupon(GetMemberCouponRequestVo.builder()
                    .partnerId(createOrderVo.getPartnerId())
                    .couponCode(createOrderVo.getCouponCode()).build());
            if (Objects.equals(getCouponDetailResponseDto, null) || CollectionUtils.isEmpty(getCouponDetailResponseDto.getDetails())
                    || getCouponDetailResponseDto.getDetails().get(0).getActive() == null
                    || getCouponDetailResponseDto.getDetails().get(0).getActive().getActiveCode() == null) {
                if ((CollectionUtils.isNotEmpty(getCouponDetailResponseDto.getDetails().get(0).getActiveRestrictionVOS())
                        && CollectionUtils.isEmpty(getCouponDetailResponseDto.getDetails().get(0).getActiveRestrictionVOS().stream()
                        .filter(a -> Objects.equals(a.getStoreIdPartner(), createOrderVo.getShopId())).collect(Collectors.toList()))
                )) {
                    throw new ServiceException(ResponseResult.COUPON_SHOP_NOTSUPPORT);
                } else {
                    throw new ServiceException(ResponseResult.COUPON_GETINFO_INVAILD);
                }
            }
            String activeCode = getCouponDetailResponseDto.getDetails().get(0).getActive().getActiveCode();
            // 校验点餐方式,查询购物车接口内部已校验
            shoppingCartInfoRequestVo.setCouponCode(createOrderVo.getCouponCode());
            // 活动code
            shoppingCartInfoRequestVo.setActivityCode(activeCode);
            shoppingCartInfoRequestVo.setCardCode(createOrderVo.getCardCode());
        }
        // 通过购物车获取优惠信息
        GetShoppingCartGoodsApportionDto requestDto = new GetShoppingCartGoodsApportionDto();
        requestDto.setShoppingCartInfoRequestVo(shoppingCartInfoRequestVo);
        //加价购商品 校验放购物车校验
        requestDto.setPremiumExchangeActivity(createOrderVo.getPremiumExchangeActivity());
        cn.freemud.base.entity.BaseResponse<ShoppingCartGoodsDto> apportionResponse = shoppingCartClient.getShoppingCartGoodsApportionNew(requestDto);
        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);
        }
        return shoppingCartGoodsDto;
    }



    public ShoppingCartGoodsDto getMCCafeShoppingCartGoodsDto(CreateOrderVo createOrderVo, AssortmentCustomerInfoVo userLoginInfoDto) {
        ShoppingCartInfoRequestVo shoppingCartInfoRequestVo = 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())
                .buyMemberCard(null)
                .menuType(createOrderVo.getMenuType())
                .build();
        List<MCCafeCouponVo> couponCodeList = new ArrayList<>();
        if("remove".equals(createOrderVo.getCouponCode())) {
            createOrderVo.setCouponCode("");
        }
        if("remove".equals(createOrderVo.getFreightCouponCode())) {
            createOrderVo.setFreightCouponCode("");
        }
        if (StringUtils.isNotBlank(createOrderVo.getCouponCode())) {
            couponCodeList.add(new MCCafeCouponVo(createOrderVo.getCouponCode()));
        }
        if (StringUtils.isNotBlank(createOrderVo.getFreightCouponCode())) {
            couponCodeList.add(new MCCafeCouponVo(createOrderVo.getFreightCouponCode()));
        }
        if (CollectionUtils.isNotEmpty(couponCodeList)) {
            // 校验couponCode
            MCCafeCouponRequest mcCafeCouponRequest = MCCafeCouponRequest.builder()
                    .ver(88)
                    .reqtype(CouponReqTypeEnum.BATCH_QUERY.getCode())
                    .partnerId(Integer.parseInt(createOrderVo.getPartnerId()))
                    .store_id(createOrderVo.getShopId())
                    .station_id("1")
                    .operator_id(createOrderVo.getUserId())
                    .channel(UserLoginChannelEnum.ALIPAY.getCode().equals(userLoginInfoDto.getChannel())?MCCafeChannelEnum.MOCOFFEE_ZFB.getName():MCCafeChannelEnum.MOCOFFEE_WX.getName())
                    .couponlist(couponCodeList)
                    .sign("skip")
                    .build();
            McdNetBatchQueryResponse mcdNetBatchQueryResponse = couponClientService.batchQuery(mcCafeCouponRequest);
            if (mcdNetBatchQueryResponse == null || !ResponseCodeConstant.RESPONSE_SUCCESS.equals(mcdNetBatchQueryResponse.getStatusCode())
                    || CollectionUtils.isEmpty(mcdNetBatchQueryResponse.getCouponlist())) {
                LogUtil.error("部分优惠券当前不可用", mcCafeCouponRequest, mcdNetBatchQueryResponse);
                throw new ServiceException(ResponseResult.COUPON_SHOP_NOTSUPPORT, "部分优惠券当前不可用");
            } else if(!ResponseCodeConstant.RESPONSE_SUCCESS.equals(mcdNetBatchQueryResponse.getCouponlist().get(0).getStatusCode())) {
                if(mcdNetBatchQueryResponse.getCouponlist().get(0).getCodeInfo() != null) {
                    LogUtil.error(mcdNetBatchQueryResponse.getCouponlist().get(0).getCodeInfo().getAct_name()+"当前不可用", mcCafeCouponRequest, mcdNetBatchQueryResponse);
                    throw new ServiceException(ResponseResult.COUPON_SHOP_NOTSUPPORT, mcdNetBatchQueryResponse.getCouponlist().get(0).getCodeInfo().getAct_name()+"当前不可用");
                } else {
                    LogUtil.error("部分优惠券暂时不可用", mcCafeCouponRequest, mcdNetBatchQueryResponse);
                    throw new ServiceException(ResponseResult.COUPON_SHOP_NOTSUPPORT, "部分优惠券暂时不可用");
                }
            }
            String activeCode = mcdNetBatchQueryResponse.getCouponlist().get(0).getCodeInfo().getAct_id();
            // 校验点餐方式,查询购物车接口内部已校验
            shoppingCartInfoRequestVo.setCouponCode(createOrderVo.getCouponCode());
            shoppingCartInfoRequestVo.setFreightCouponCode(createOrderVo.getFreightCouponCode());
            // 活动code
            shoppingCartInfoRequestVo.setActivityCode(activeCode);
            shoppingCartInfoRequestVo.setCardCode(createOrderVo.getCardCode());
        }
        // 通过购物车获取优惠信息
        GetShoppingCartGoodsApportionDto requestDto = new GetShoppingCartGoodsApportionDto();
        requestDto.setShoppingCartInfoRequestVo(shoppingCartInfoRequestVo);
        //加价购商品 校验放购物车校验
        requestDto.setPremiumExchangeActivity(createOrderVo.getPremiumExchangeActivity());
        cn.freemud.base.entity.BaseResponse<ShoppingCartGoodsDto> apportionResponse = shoppingCartClient.getMCCafeShoppingCartGoodsApportionNew(requestDto);
        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);
        }
        List<MCCafeCouponVo> mcCafeCouponVos = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(shoppingCartGoodsDto.getActivityDiscountsDtos())) {
            shoppingCartGoodsDto.getActivityDiscountsDtos().forEach(o-> {
                if(ActivityTypeEnum.TYPE_3.getCode().equals(o.getActivityType()) || ActivityTypeEnum.TYPE_32.getCode().equals(o.getActivityType())) {
                    mcCafeCouponVos.add(new MCCafeCouponVo(o.getActivityCode()));
                }
            });
        }
        if(CollectionUtils.isNotEmpty(mcCafeCouponVos)) {
            MCCafeCouponRequest mcCafeCouponRequest = MCCafeCouponRequest.builder()
                    .ver(88)
                    .reqtype(CouponReqTypeEnum.BATCH_QUERY.getCode())
                    .partnerId(Integer.parseInt(createOrderVo.getPartnerId()))
                    .store_id(createOrderVo.getShopId())
                    .station_id("1")
                    .operator_id(createOrderVo.getUserId())
                    .channel(UserLoginChannelEnum.ALIPAY.getCode().equals(userLoginInfoDto.getChannel())?MCCafeChannelEnum.MOCOFFEE_ZFB.getName():MCCafeChannelEnum.MOCOFFEE_WX.getName())
                    .couponlist(mcCafeCouponVos)
                    .sign("skip")
                    .build();
            McdNetBatchQueryResponse mcdNetBatchQueryResponse = couponClientService.batchQuery(mcCafeCouponRequest);
            if (mcdNetBatchQueryResponse == null || !ResponseCodeConstant.RESPONSE_SUCCESS.equals(mcdNetBatchQueryResponse.getStatusCode())
                    || CollectionUtils.isEmpty(mcdNetBatchQueryResponse.getCouponlist())) {
                LogUtil.error("部分优惠券当前不可用", mcCafeCouponRequest, mcdNetBatchQueryResponse);
                throw new ServiceException(ResponseResult.COUPON_SHOP_NOTSUPPORT, "部分优惠券当前不可用");
            } else {
                mcdNetBatchQueryResponse.getCouponlist().forEach(o -> {
                    if(!ResponseCodeConstant.RESPONSE_SUCCESS.equals(o.getStatusCode())) {
                        if(o.getCodeInfo() != null) {
                            LogUtil.error(o.getCodeInfo().getAct_name()+"当前不可用", mcCafeCouponRequest, mcdNetBatchQueryResponse);
                            throw new ServiceException(ResponseResult.COUPON_SHOP_NOTSUPPORT, o.getCodeInfo().getAct_name()+"当前不可用");
                        } else {
                            LogUtil.error("部分优惠券暂时不可用", mcCafeCouponRequest, mcdNetBatchQueryResponse);
                            throw new ServiceException(ResponseResult.COUPON_SHOP_NOTSUPPORT, "部分优惠券暂时不可用");
                        }
                    }
                });
            }
        }
        if(shoppingCartGoodsDto.getDeliveryAmount().longValue() != shoppingCartGoodsDto.getDiscountDeliveryAmount().longValue()) {
            shoppingCartGoodsDto.setIsDiscountDelivery(true);
        }
        return shoppingCartGoodsDto;
    }

    /**
     * 获取门店配送信息
     */
    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 {
            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 checkReceiveAddress(StoreDeliveryInfoDto storeDeliveryInfoDto, CreateOrderVo createOrderVo) {
        //校验收货地址是否可配送
        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();

        CreateOrderRequestDto createOrderRequestDto = new CreateOrderRequestDto();
        createOrderRequestDto.setLatitude(receiveAddressResult.getLatitude());
        createOrderRequestDto.setLongitude(receiveAddressResult.getLongitude());
        MCCafeDeliveryBaseResponse mcCafeDeliveryBaseResponse = deliveryServiceFeiginMCCafeClient.client(createOrderRequestDto);

        if (!ResponseConstant.SUCCESS_RESPONSE_CODE.equals(mcCafeDeliveryBaseResponse.getCode()) || null == mcCafeDeliveryBaseResponse.getData()) {
            throw new ServiceException(ResponseResult.ORDER_TAKE_OUT_ADDRESS_NOT_VALID);
        } else {
            List<MCCafeDeliveryGetStoreIdResponse> mcCafeDeliveryGetStoreIdResponseList = JSON.parseArray(mcCafeDeliveryBaseResponse.getData().toString(), MCCafeDeliveryGetStoreIdResponse.class);
            if(mcCafeDeliveryGetStoreIdResponseList.stream().noneMatch(o -> createOrderVo.getShopId().equals(o.getExtraId()))) {
                throw new ServiceException(ResponseResult.ORDER_TAKE_OUT_ADDRESS_NOT_DELIVERY);
            }
        }

        UserDeliveryInfoDto userDeliveryInfoDto = UserDeliveryInfoDto.builder()
                .userLongitude(receiveAddressResult.getLongitude())
                .userLatitude(receiveAddressResult.getLatitude())
                .deliveryLimitAmount(storeDeliveryInfoDto.getDeliveryLimitAmount())
                .userEnableTakeaway(true)
                .realDeliveryAmount(0l)
                .storeId(storeDeliveryInfoDto.getStoreId())
                .storeName(storeDeliveryInfoDto.getStoreName())
                .storeDeliveryInfoDto(storeDeliveryInfoDto).build();

        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 void checkCardCode(String partnerId,String memberId,String cardCode){
        if(StringUtils.isBlank(cardCode)){
            return;
        }
        StatisticalPropertyRequest request = new StatisticalPropertyRequest();
        request.setPartnerId(partnerId);
        request.setMemberId(memberId);
        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(cardCode.equals(getSvcInfoByMemberIdResponse.getCardCode()) && getSvcInfoByMemberIdResponse.getStatusFlag() == 0){
                b = false;
            }
        }
        if(b){
            throw new ServiceException(ResponseResult.USER_SVC_CARD_ERROR);
        }
    }

    public void checkOrderByStore(StoreResponse.BizVO storeResponseDto){
        // 校验门店是否停业 1 营业 2 停业 3 繁忙置休
        if (storeResponseDto.getActiveFlag() == null || storeResponseDto.getActiveFlag() != 1) {
            throw new ServiceException(ResponseResult.STORE_ITEM_STOP_BUSINESS);
        }
//        //设置营业开始和结束时间
//        String businessHourStr = storeResponseDto.getBusinessHoursDay().replace("-", ",").replace("_", ",");
//        String[] businessHours = businessHourStr.split(",");
//        if (businessHours.length != 2) {
//            throw new ServiceException(ResponseResult.STORE_NOT_FOUND);
//        }
//        Date date = new Date();
//        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);
//        }
//        storeResponseDto.setBusinessHoursDayStartTime(startDateTime);
//        storeResponseDto.setBusinessHoursDayEndTime(endDateTime);
//
//        // 校验门店是否打烊，打烊了则不让操作
//        if (storeResponseDto.getBusinessHoursDayStartTime() == null
//                || storeResponseDto.getBusinessHoursDayEndTime() == null) {
//            throw new ServiceException(ResponseResult.STORE_ITEM_STOP_BUSINESS);
//        }
    }

}
