package cn.freemud.service.universal;

import cn.freemud.entities.dto.GetCouponDetailResponseDto;
import cn.freemud.entities.dto.shoppingCart.ShoppingCartGoodsDto;
import cn.freemud.entities.vo.CreateOrderBaseVo;
import cn.freemud.entities.vo.GetMemberCouponRequestVo;
import cn.freemud.entities.vo.ShoppingCartInfoRequestVo;
import cn.freemud.enums.OrderMarketType;
import cn.freemud.enums.ResponseResult;
import cn.freemud.interceptor.ServiceException;
import cn.freemud.service.CouponService;
import cn.freemud.utils.LogUtil;
import com.freemud.application.sdk.api.log.ApiLog;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author : xh.Z
 * @email : fisherman0510@163.com
 * @Date : 2021/4/15 下午4:51
 * @description :
 */
@Component
public class CommonCheckOrderHandle {

    @Autowired
    private CouponService couponService;

    /**
     * 优惠券的校验操作
     *
     * @param createOrderVo
     * @param shoppingCartInfoRequestVo
     */
    public void diyCheckCouponCode(CreateOrderBaseVo createOrderVo, ShoppingCartInfoRequestVo shoppingCartInfoRequestVo) {
        // 如果使用优惠券或者商品券，校验 couponCode
        ApiLog.info("校验优惠券", createOrderVo, shoppingCartInfoRequestVo);
        if (StringUtils.isNotBlank(createOrderVo.getCouponCode())) {
            checkCouponCode(createOrderVo, shoppingCartInfoRequestVo);
        }

        // 如果批量使用优惠券或者商品券，校验 couponCode
        List<ShoppingCartInfoRequestVo.couponCode> couponCodes = new ArrayList<>();
        if (createOrderVo.getCouponCodes() != null && !createOrderVo.getCouponCodes().isEmpty()) {
            batchCheckCouponCodes(createOrderVo, shoppingCartInfoRequestVo, couponCodes);
        }
        shoppingCartInfoRequestVo.setCouponCodes(couponCodes);
    }

    /**
     * 拼团商品 逻辑
     * 商城订单 没有该操作
     *
     * @param createOrderVo
     * @param shoppingCartGoodsDto
     */
    public void collageOrderHandle(CreateOrderBaseVo createOrderVo, ShoppingCartGoodsDto shoppingCartGoodsDto) {
        if (this.isCollageOrder(createOrderVo)) {
            ApiLog.info("拼单商品 业务处理", createOrderVo, shoppingCartGoodsDto);
            // 处理拼单加购人信息
            List<ShoppingCartGoodsDto.CartGoodsDetailDto> products = shoppingCartGoodsDto.getProducts();
            ShoppingCartGoodsDto.CartGoodsDetailDto createUserGood = products.stream().filter(good -> createOrderVo.getUserId().equals(good.getUserId())).findFirst().orElse(null);

            if (null == createUserGood) {
                // 若拼单发起人未购买商品，则将赠品按购物车行分给加购人
                products.stream().filter(good -> null == good.getUserId()).collect(Collectors.toList()).forEach(cartGoodsNullUser -> {
                    ShoppingCartGoodsDto.CartGoodsDetailDto parentGood = products.stream().filter(good -> good.getCartGoodsUid().equals(cartGoodsNullUser.getCartGoodsUid())).findFirst().orElse(null);
                    cartGoodsNullUser.setUserId(parentGood == null ? createOrderVo.getUserId() : parentGood.getUserId());
                    cartGoodsNullUser.setOpenId(parentGood == null ? null : parentGood.getOpenId());
                    cartGoodsNullUser.setUserName(parentGood == null ? null : parentGood.getUserName());
                    cartGoodsNullUser.setPhotoUrl(parentGood == null ? null : parentGood.getPhotoUrl());
                });
            } else {
                products.stream().filter(good -> null == good.getUserId()).collect(Collectors.toList()).forEach(cartGoodsNullUser -> {
                    cartGoodsNullUser.setUserId(createUserGood.getUserId());
                    cartGoodsNullUser.setOpenId(createUserGood.getOpenId());
                    cartGoodsNullUser.setUserName(createUserGood.getUserName());
                    cartGoodsNullUser.setPhotoUrl(createUserGood.getPhotoUrl());
                });
            }
        }
    }

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


    private void checkCouponCode(CreateOrderBaseVo createOrderVo, ShoppingCartInfoRequestVo shoppingCartInfoRequestVo) {
        // 校验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());
    }

    /**
     * 校验使用 优惠券集合
     *
     * @param createOrderVo
     * @param shoppingCartInfoRequestVo
     * @param couponCodes
     */
    private void batchCheckCouponCodes(CreateOrderBaseVo createOrderVo,
                                       ShoppingCartInfoRequestVo shoppingCartInfoRequestVo,
                                       List<ShoppingCartInfoRequestVo.couponCode> couponCodes) {
        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());
        }
    }

    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);
        }

    }

}
