package com.fzm.mall.server.front.order.service.impl;

import com.fzm.mall.server.front.constant.GoodMainConst;
import com.fzm.mall.server.front.goods.mapper.GoodSkuMapper;
import com.fzm.mall.server.front.goods.model.vo.SkuVo;
import com.fzm.mall.server.front.order.service.IOrderBindBoxService;
import com.fzm.mall.server.front.redis.GoodRedis;
import com.fzm.mall.server.front.redis.OrderRedis;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;

/**
 * @author wulixian
 * @since 2022/2/23
 */
@Slf4j
@Service
public class IOrderBindBoxServiceImpl implements IOrderBindBoxService {

    @Autowired
    private GoodSkuMapper goodSkuMapper;

    @Autowired
    private GoodRedis goodRedis;

    @Override
    public SkuVo genRandomSku(String goodsId) {
        long wStart = System.currentTimeMillis();
        SkuVo result = null;
        /**
         * 提前预热，减轻数据库压力
         */
        List<SkuVo> skuList = goodRedis.getEffecticveSku(goodsId);
        if(CollectionUtils.isEmpty(skuList)){
            log.error("redis中读取");
            /**
             * 从数据库获取库存大于0的盲盒sku列表
             */
            skuList = goodSkuMapper.listAvailableSku(goodsId);
            /**
             * 1分钟缓存
             */
            goodRedis.setEffecticveSku(goodsId, skuList, 1, TimeUnit.MINUTES);
        }
        while(!CollectionUtils.isEmpty(skuList)){
            int difficulty = skuList.stream().map(SkuVo::getDifficulty).findFirst().get();
            result = genRandomSku(skuList, difficulty);
            if (result == null) {
                throw new RuntimeException("库存不足!!!");
            }
            //加时间锁
            int i = goodSkuMapper.delStock(result.getSkuId(), GoodMainConst.BLIND_BOX_ORDER_SKU_NUM);
            if (i != 1) {
                /**
                 * 锁定库存失效，重置结果
                 */
                skuList.remove(result);
                result = null;
            }else{
                break;
            }
        }
        long wEnd = System.currentTimeMillis();
        log.info("循环耗时：" +(wEnd-wStart));
        /**
         * 将缓存更新
         */
        goodRedis.setEffecticveSku(goodsId, skuList, 1, TimeUnit.MINUTES);
        if (result == null) {
            throw new RuntimeException("库存不足!!!");
        }
        return result;
    }

    /**
     * @param prodList   从数据库获取的库存大于0的盲盒产品列表
     * @param difficulty 正整数[1,10]
     * @return 随机产品规格
     * @descprition 随机获得产品
     * @author lyz
     * @create 2022/2/14 9:42
     */
    public static SkuVo genRandomSku(List<SkuVo> prodList, int difficulty) {
        int hiddenWeight = difficulty == 10 ? 1 : (10 - difficulty);

        List<SkuVo> baseList = new ArrayList<>();
        for (SkuVo prodItem : prodList) {
            if (prodItem.getIsHide()) {
                for (int i = 0; i < hiddenWeight; i++) {
                    baseList.add(prodItem);
                }
            } else {
                for (int i = 0; i < difficulty; i++) {
                    baseList.add(prodItem);
                }
            }
        }

        //为了增加随机度，可以打开
        //Collections.shuffle(baseList);

        int base = baseList.size();
        int randomNum = ThreadLocalRandom.current().nextInt(base);
        return baseList.get(randomNum);
    }
}
