package com.hai.goods.service.impl;

import com.hai.common.exception.ErrorCode;
import com.hai.common.exception.ErrorHelp;
import com.hai.common.exception.SysCode;
import com.hai.dao.GoodsSkuMapper;
import com.hai.entity.GoodsDetailExample;
import com.hai.entity.GoodsSku;
import com.hai.entity.GoodsSkuExample;
import com.hai.entity.HighOrder;
import com.hai.goods.service.GoodsSkuService;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

@Service("goodsSkuService")
public class GoodsSkuServiceImpl implements GoodsSkuService {

    @Resource
    private GoodsSkuMapper goodsSkuMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public void insertGoodsSku(GoodsSku goodsSku) {
        goodsSkuMapper.insert(goodsSku);
    }

    @Override
    public void updateGoodsSku(GoodsSku goodsSku) {
        goodsSkuMapper.updateByPrimaryKey(goodsSku);
    }

    @Override
    public List<GoodsSku> getGoodsSkuList(Map<String, Object> map) {
        GoodsSkuExample example = new GoodsSkuExample();
        GoodsSkuExample.Criteria criteria = example.createCriteria();

        if (MapUtils.getString(map, "name") != null) {
            criteria.andNameLike("%" +  MapUtils.getString(map, "name") + "%");
        }
        if (MapUtils.getInteger(map, "status") != null) {
            criteria.andStatusEqualTo(MapUtils.getInteger(map, "status") );
        } else {
            criteria.andStatusNotEqualTo(0);
        }
        if (MapUtils.getLong(map, "goodsId") != null) {
            criteria.andGoodsIdEqualTo(MapUtils.getLong(map, "goodsId") );
        }
        if (MapUtils.getLong(map, "id") != null) {
            criteria.andIdEqualTo(MapUtils.getLong(map, "id") );
        }

        return goodsSkuMapper.selectByExample(example);
    }

    @Override
    public List<GoodsSku> getGoodsSkuList(Long goodsId) {
        GoodsSkuExample example = new GoodsSkuExample();
        GoodsSkuExample.Criteria criteria = example.createCriteria();
        criteria.andGoodsIdEqualTo(goodsId).andStatusEqualTo(1);

        return goodsSkuMapper.selectByExample(example);
    }

    @Override
    public GoodsSku findGoodsSkuById(Long id) {
        return goodsSkuMapper.selectByPrimaryKey(id);
    }

    @Override
    public void  decreaseStockNum(Long skuId, Integer num){
        String key = "GOODS_STOCK_NUM";

        GoodsSku goodsSku = findGoodsSkuById(skuId);

        try {
            // 分布式锁占坑
            Boolean lock = redisTemplate.opsForValue().setIfAbsent(key, skuId);

            if(Boolean.TRUE.equals(lock)) {
                if (goodsSku.getStock() < num) {
                    throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, goodsSku.getName() + "库存不足");
                }
                // 加锁成功，处理业务
                goodsSku.setStock(goodsSku.getStock() - num);

                updateGoodsSku(goodsSku);

            } else {
                // 加锁失败，重试
                Thread.sleep(100);
                decreaseStockNum(skuId , num);
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 删除key，释放锁
            redisTemplate.delete(key);
        }

    }
}
