package com.liquidnet.service.platform.service.impl.candy;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liquidnet.common.cache.redis.util.AbstractRedisUtil;
import com.liquidnet.common.cache.redis.util.RedisDataSourceUtil;
import com.liquidnet.service.adam.constant.AdamRedisConst;
import com.liquidnet.service.base.OrderCloseMapping;
import com.liquidnet.service.base.constant.MQConst;
import com.liquidnet.service.candy.constant.CandyRedisConst;
import com.liquidnet.service.candy.dto.CandyCommonCouponBasicDto;
import com.liquidnet.service.candy.dto.CandyCouponRuleDto;
import com.liquidnet.service.candy.dto.CandyUserCouponBasicDto;
import com.liquidnet.service.candy.entity.CandyUserCoupon;
import com.liquidnet.service.candy.mapper.CandyCommonCouponMapper;
import com.liquidnet.service.candy.mapper.CandyCouponRuleMapper;
import com.liquidnet.service.candy.mapper.CandyUserCouponMapper;
import com.liquidnet.service.platform.utils.QueueUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class PlatformCandyUserCouponService extends ServiceImpl<CandyUserCouponMapper, CandyUserCoupon> {
    @Autowired
    private CandyUserCouponMapper candyUserCouponMapper;
    @Autowired
    private CandyCouponRuleMapper candyCouponRuleMapper;
    @Autowired
    private CandyCommonCouponMapper candyCommonCouponMapper;
    @Autowired
    private PlatformCandyUserCouponService platformCandyUserCouponService;
    @Autowired
    private QueueUtils queueUtils;
    @Autowired
    private RedisDataSourceUtil redisDataSourceUtil;

    /**
     * @param uCouponUidList 内容 uCouponId,uid List
     * @param uCouponIdList  内容 uCouponId List
     * @return
     */
    public Boolean useBackCoupon(ArrayList<String> uCouponUidList, ArrayList<String> uCouponIdList) {
        //修改数据库
        CandyUserCoupon userCoupon = CandyUserCoupon.getNew();
        userCoupon.setState(1);
        platformCandyUserCouponService.update(userCoupon, new UpdateWrapper<CandyUserCoupon>().in("ucoupon_id", uCouponIdList));
        //sendRedis
        int forSize = 500;
        int forCount = uCouponUidList.size() % forSize == 0 ? uCouponUidList.size() / forSize : (uCouponUidList.size() / forSize) + 1;
        for (int i = 0; i < forCount; i++) {
            LinkedList<String> mqList = new LinkedList<>();
            for (int y = 0; y < forSize; y++) {
                try {
                    String t = uCouponUidList.get(i * 500 + y);
                    mqList.add(t);
                } catch (Exception e) {
                    break;
                }
            }
            queueUtils.sendMsgByRedis(MQConst.CandyQueue.COUPON_ORDER_BACK.getKey(), OrderCloseMapping.get(mqList));
        }
        return true;
    }

    public List<CandyUserCouponBasicDto> ucouponBasicDtoByUidProcessing(String uid) {
        AbstractRedisUtil redisCandyUtil = redisDataSourceUtil.getRedisCandyUtil();
        if (null == redisCandyUtil.get(AdamRedisConst.INFO_USER.concat(uid))) return null;

        List<CandyUserCouponBasicDto> basicDtoList = candyUserCouponMapper.selectMultiForUserCouponBasicDto(uid);
        if (!CollectionUtils.isEmpty(basicDtoList)) {
            List<String> couponIdList = basicDtoList.stream().map(CandyUserCouponBasicDto::getCouponId).collect(Collectors.toList());

            List<CandyCouponRuleDto> couponRuleDtoList = candyCouponRuleMapper.selectListForCouponRuleDto(couponIdList);

            Map<String, List<CandyCouponRuleDto>> couponRuleDtoListMap = couponRuleDtoList.stream().collect(Collectors.groupingBy(CandyCouponRuleDto::getCouponId));

//            Map<String, List<CandyUserCouponBasicDto>> basicDtoListMap = basicDtoList.stream().collect(Collectors.groupingBy(CandyUserCouponBasicDto::getCouponId));

            basicDtoList.forEach(dto -> {
                dto.setUseRules(couponRuleDtoListMap.get(dto.getCouponId()));
            });

            redisCandyUtil.set(CandyRedisConst.BASIC_USER_COUPON.concat(uid), basicDtoList);
        }
        return basicDtoList;
    }

    public List<CandyCommonCouponBasicDto> ccouponBasicDtoByUidProcessing(LocalDateTime ucreatedAt) {
        List<CandyCommonCouponBasicDto> basicDtoList = candyCommonCouponMapper.selectMultiForCommonCouponBasicDto(ucreatedAt);
        if (!CollectionUtils.isEmpty(basicDtoList)) {
            List<String> couponIdList = basicDtoList.stream().map(CandyCommonCouponBasicDto::getCouponId).collect(Collectors.toList());

            List<CandyCouponRuleDto> couponRuleDtoList = candyCouponRuleMapper.selectListForCouponRuleDto(couponIdList);

            Map<String, List<CandyCouponRuleDto>> couponRuleDtoListMap = couponRuleDtoList.stream().collect(Collectors.groupingBy(CandyCouponRuleDto::getCouponId));

            basicDtoList.forEach(dto -> {
                dto.setUseRules(couponRuleDtoListMap.get(dto.getCouponId()));
            });

            redisDataSourceUtil.getRedisCandyUtil().set(CandyRedisConst.BASIC_COMMON_COUPON, basicDtoList);
        }
        return basicDtoList;
    }
}
