/**
 * 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.util.DateUtil;
import cn.freemud.base.util.JsonUtil;
import cn.freemud.constant.ResponseCodeConstant;
import cn.freemud.constant.StoreConstant;
import cn.freemud.entities.dto.GetCouponDetailResponseDto;
import cn.freemud.entities.dto.StoreDeliveryInfoDto;
import cn.freemud.entities.dto.StoreResponseDto;
import cn.freemud.entities.dto.UserDeliveryInfoDto;
import cn.freemud.entities.dto.delivery.WeixinDeliveryAddressDto;
import cn.freemud.entities.dto.shoppingCart.GetShoppingCartGoodsApportionDto;
import cn.freemud.entities.dto.shoppingCart.ShoppingCartGoodsDto;
import cn.freemud.entities.dto.store.StoreMixResponseDto;
import cn.freemud.entities.vo.CreateOrderVo;
import cn.freemud.entities.vo.GetMemberCouponRequestVo;
import cn.freemud.entities.vo.ShoppingCartInfoRequestVo;
import cn.freemud.entities.vo.delivery.DeliveryAmountVo;
import cn.freemud.enums.BusinessTypeEnum;
import cn.freemud.enums.CouponFlag;
import cn.freemud.enums.OrderChannelType;
import cn.freemud.enums.ResponseResult;
import cn.freemud.interceptor.ServiceException;
import cn.freemud.service.CouponService;
import cn.freemud.service.delivery.ThirdDeliveryServiceImpl;
import cn.freemud.service.thirdparty.ShoppingCartClient;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.freemud.api.assortment.datamanager.entity.vo.AssortmentCustomerInfoVo;
import com.freemud.api.assortment.datamanager.manager.customer.AssortmentCustomerInfoManager;
import com.freemud.application.sdk.api.storecenter.request.StoreInfoRequest;
import com.freemud.application.sdk.api.storecenter.response.StoreResponse;
import com.freemud.application.sdk.api.storecenter.service.StoreCenterService;
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.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Component
public class CheckMallOrder {

    @Autowired
    private ShoppingCartClient shoppingCartClient;
    @Autowired
    private ThirdDeliveryServiceImpl thirdDeliveryService;
    @Autowired
    private AssortmentCustomerInfoManager customerInfoManager;
    @Autowired
    private StoreCenterService storeCenterService;
    @Autowired
    private StoreServiceImpl storeService;
    @Autowired
    private CouponService couponService;

    /**
     * 下单会员相关校验
     */
    public AssortmentCustomerInfoVo checkOrderByMember(CreateOrderVo createOrderVo) {
        // 通过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());
        createOrderVo.setUserName(userLoginInfoDto.getNickName());
        return userLoginInfoDto;
    }

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

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

        // 获取门店信息
        StoreMixResponseDto storeMixResponseDto = storeService.getStoreInfoNew(partnerId, shopId, false,false);
        if (storeMixResponseDto == null || storeMixResponseDto.getStoreInfo() == null) {
            throw new ServiceException(ResponseResult.STORE_NOT_FOUND);
        }
        StoreResponseDto storeResponseDto= storeMixResponseDto.getStoreInfo();
        // 校验门店是否停业 1 营业 2 停业 3 繁忙置休
        if (storeResponseDto.getActiveFlag() == null || storeResponseDto.getActiveFlag() != 1) {
            throw new ServiceException(ResponseResult.STORE_ITEM_STOP_BUSINESS);
        }
        if (!StoreConstant.BUSINESS.equals(storeResponseDto.getState())) {
            throw new ServiceException(ResponseResult.STORE_ITEM_CHECK_CLOSE);
        }
        //设置营业开始和结束时间
        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";
        Date startDateTime = DateUtil.convert2Date(startDateTimeStr, DateUtil.FORMAT_YYYY_MM_DD_HHMMSS);
        String endDateTimeStr = DateUtil.convert2String(date, DateUtil.FORMAT_YMD) + " " + businessHours[1] + ":00";
        SimpleDateFormat hhmmss = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date endDateTime;
        try {
            endDateTime = hhmmss.parse(endDateTimeStr);
        } catch (ParseException e) {
            throw new ServiceException(ResponseResult.STORE_BUSINESS_HOUR_ERROR);
        }
        storeResponseDto.setBusinessHoursDayStartTime(startDateTime);
        storeResponseDto.setBusinessHoursDayEndTime(endDateTime);

        createOrderVo.setStoreName(storeResponseDto.getStoreName());
        createOrderVo.setStoreAddress(storeResponseDto.getAddress());
        createOrderVo.setThirdShopId(storeResponseDto.getThirdPartCode());
        return storeResponseDto;
    }

    /**
     * 下单配送相关校验
     */
    public void checkOrderByDelivery(CreateOrderVo createOrderVo, AssortmentCustomerInfoVo userLoginInfoDto,
                                     StoreResponseDto storeResponseDto,Long totalAmount, String trackingNo) {
//        StoreDeliveryInfoDto storeDeliveryInfoDto = this.getStoreDeliveryInfo(storeResponseDto, userLoginInfoDto.getWxAppId());
//        //订单金额小于起送费提示
//        if (storeDeliveryInfoDto.getDeliveryLimitAmount() > totalAmount) {
//            throw new ServiceException(ResponseResult.STORE_DISCONTENT_DELIVERY_FEE);
//        }
//        storeDeliveryInfoDto.setEnableTakeaway(true);
        this.checkReceiveAddress(createOrderVo);
    }

    public ShoppingCartGoodsDto getShoppingCartGoodsDto(CreateOrderVo createOrderVo) {
        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())
                .useCustomerScore(createOrderVo.getUseCustomerScore())
                .channelType(OrderChannelType.SAASMALL.getCode())
                .menuType(BusinessTypeEnum.SAAS_MALL.getName())
                .buyType(createOrderVo.getBuyType())
                .province(createOrderVo.getProvince())
                .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);
                }
            }
            List<GetCouponDetailResponseDto.ActiveRedeemTimeInterval> activeRedeemTimeIntervalList = getCouponDetailResponseDto.getDetails().get(0).getActiveRedeemTimeIntervalList();
            checkCouonRedeemTime(activeRedeemTimeIntervalList);
            String activeCode = getCouponDetailResponseDto.getDetails().get(0).getActive().getActiveCode();
            // 校验点餐方式,查询购物车接口内部已校验
            shoppingCartInfoRequestVo.setCouponCode(createOrderVo.getCouponCode());
            // 活动code
            shoppingCartInfoRequestVo.setActivityCode(activeCode);
            shoppingCartInfoRequestVo.setCardCode(createOrderVo.getCardCode());
        }

        // 如果批量使用优惠券或者商品券，校验 couponCode
        List<ShoppingCartInfoRequestVo.couponCode> couponCodes = new ArrayList();
        if (createOrderVo.getCouponCodes() != null && !createOrderVo.getCouponCodes().isEmpty()) {
            createOrderVo.getCouponCodes().forEach(couponCode->{
                // 校验couponCode
                GetCouponDetailResponseDto getCouponDetailResponseDto = couponService.getMemberCoupon(GetMemberCouponRequestVo.builder()
                        .partnerId(createOrderVo.getPartnerId())
                        .couponCode(couponCode.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.couponCode coupon = new ShoppingCartInfoRequestVo.couponCode();
                coupon.setCouponCode(couponCode.getCouponCode());
                coupon.setActivityCode(activeCode);
                coupon.setIndex(couponCode.getIndex());
                couponCodes.add(coupon);
            });

            if(StringUtils.isEmpty(shoppingCartInfoRequestVo.getCardCode())){
                shoppingCartInfoRequestVo.setCardCode(createOrderVo.getCardCode());
            }
        }

        shoppingCartInfoRequestVo.setCouponCodes(couponCodes);

        // 通过购物车获取优惠信息
        GetShoppingCartGoodsApportionDto requestDto = new GetShoppingCartGoodsApportionDto();
        // 设置用户选择的买一赠一商品信息
        shoppingCartInfoRequestVo.setChooseGoods(JSONArray.parseArray(JSONObject.toJSONString(createOrderVo.getChooseGoods()), ShoppingCartInfoRequestVo.ChooseGood.class));
        requestDto.setShoppingCartInfoRequestVo(shoppingCartInfoRequestVo);
        //加价购商品 校验放购物车校验
        requestDto.setPremiumExchangeActivity(createOrderVo.getPremiumExchangeActivity());
        cn.freemud.base.entity.BaseResponse<ShoppingCartGoodsDto> apportionResponse = shoppingCartClient.getShoppingCartGoodsApportionNew(requestDto);
        if (ObjectUtils.equals(ResponseCodeConstant.USER_HAVE_NO_COUPON, apportionResponse.getCode())) {
            throw new ServiceException(ResponseResult.SHOPPING_CART_USER_HAVE_NO_COUPON,apportionResponse.getMessage());
        }
        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 void checkReceiveAddress( CreateOrderVo createOrderVo) {
        WeixinDeliveryAddressDto weixinDeliveryAddress = createOrderVo.getWeixinDeliveryAddress();
        if(weixinDeliveryAddress == null || StringUtils.isEmpty(weixinDeliveryAddress.getProvinceName())) {
            throw new ServiceException(ResponseResult.DELIVERY_INFO_ERROR);
        }
        UserDeliveryInfoDto userDeliveryInfoDto = UserDeliveryInfoDto.builder()
                .userEnableTakeaway(true)
                .receiveMobile(weixinDeliveryAddress.getTelNumber())
                .receiveUserName(weixinDeliveryAddress.getUserName())
                .receiveProvince(weixinDeliveryAddress.getProvinceName())
                .receiveCity(weixinDeliveryAddress.getCityName())
                .receiveRegion(weixinDeliveryAddress.getCountyName())
                .receiveAddress(weixinDeliveryAddress.getDetailInfo()).build();
        createOrderVo.setReceiveMobile(weixinDeliveryAddress.getTelNumber());
        createOrderVo.setReceiveAddress(weixinDeliveryAddress.getDetailInfo());
        createOrderVo.setReceiveUsername(weixinDeliveryAddress.getUserName());
        createOrderVo.setUserDeliveryInfoDto(userDeliveryInfoDto);
    }

    private void checkCouonRedeemTime(List<GetCouponDetailResponseDto.ActiveRedeemTimeInterval> activeRedeemTimeIntervalList) {
        boolean verificationPassed = false;
        if (CollectionUtils.isNotEmpty(activeRedeemTimeIntervalList)){
            for (GetCouponDetailResponseDto.ActiveRedeemTimeInterval dateLimit : activeRedeemTimeIntervalList){
                boolean dayCheck = true;
                String weekday = dateLimit.getWeekday(); // 日期限制 0011100 周日开始,0表示不可用
                if (StringUtils.isNotBlank(weekday)){ // 存在校验周几
                    char[] chars = weekday.toCharArray();
                    int dayOfWeek = LocalDate.now().getDayOfWeek().getValue();  // 从周一开始
                    if (dayOfWeek == 7){
                        dayOfWeek = 0;
                    }
                    if (Integer.parseInt(String.valueOf(chars[dayOfWeek])) == 0){ //限制
                        dayCheck = false;
                    }
                }
                boolean timeCheck = true;
                String begintime = dateLimit.getBegintime(); // 开始时间  00:00:00
                String endtime = dateLimit.getEndtime();  // 结束时间 12:59:59
                if (StringUtils.isNotBlank(begintime) && StringUtils.isNotBlank(endtime)){ // 存在校验时段
                    String[] beginTimeArr = begintime.split(":");
                    String[] endTimeArr = endtime.split(":");
                    LocalTime beginLocalTime = LocalTime.of(Integer.valueOf(beginTimeArr[0]), Integer.valueOf(beginTimeArr[1]), Integer.valueOf(beginTimeArr[2]));
                    LocalTime endLocalTime = LocalTime.of(Integer.valueOf(endTimeArr[0]), Integer.valueOf(endTimeArr[1]), Integer.valueOf(endTimeArr[2]));
                    LocalTime now = LocalTime.now();
                    if (now.isBefore(beginLocalTime) || now.isAfter(endLocalTime)){
                        timeCheck = false;
                    }
                }
                if (dayCheck && timeCheck){
                    verificationPassed = true;
                    break;
                }
            }
        } else {
            verificationPassed = true;
        }
        if (!verificationPassed){
            throw new ServiceException(ResponseResult.COUPON_DATETIME_INVAILD);
        }

    }

}
