package com.hfkj.service.goods.impl;

import com.hfkj.common.exception.ErrorCode;
import com.hfkj.common.exception.ErrorHelp;
import com.hfkj.common.exception.SysCode;
import com.hfkj.dao.GoodsSpecsMapper;
import com.hfkj.entity.GoodsMsg;
import com.hfkj.entity.GoodsSpecs;
import com.hfkj.entity.GoodsSpecsExample;
import com.hfkj.service.goods.GoodsSpecsService;
import com.hfkj.service.goods.GoodsVpdService;
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.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service("goodsSpecsService")
public class GoodsSpecsServiceImpl implements GoodsSpecsService {

    @Resource
    private GoodsSpecsMapper goodsSpecsMapper;

    @Resource
    private GoodsVpdService goodsVpdService;

    @Autowired
    private RedisTemplate redisTemplate;


    @Override
    public void create(GoodsSpecs goodsSpecs) {
        goodsSpecsMapper.insert(goodsSpecs);
    }

    @Override
    public void update(GoodsSpecs goodsSpecs) {
        goodsSpecsMapper.updateByPrimaryKeySelective(goodsSpecs);
    }

    @Override
    public void delete(Long id, Boolean fullDelete) {
        if (fullDelete) {
            goodsSpecsMapper.deleteByPrimaryKey(id);
        } else {
            GoodsSpecs goodsSpecs = queryDetail(id);
            goodsSpecs.setStatus(0);
            goodsSpecs.setUpdateTime(new Date());
            update(goodsSpecs);
        }

        goodsVpdService.deleteSpecsId(id);

    }

    @Override
    public GoodsSpecs queryDetail(Long id) {
        return goodsSpecsMapper.selectByPrimaryKey(id);
    }

    @Override
    public GoodsSpecs queryDetailByGoodsId(Long id) {
        GoodsSpecsExample goodsSpecsExample = new GoodsSpecsExample();
        goodsSpecsExample.createCriteria().andIdEqualTo(id);

        List<GoodsSpecs> goodsSpecs = goodsSpecsMapper.selectByExample(goodsSpecsExample);

        if (!goodsSpecs.isEmpty()) {
            return goodsSpecs.get(0);
        }

        return null;
    }

    @Override
    public GoodsSpecs queryDetailByMap(Map<String, Object> map) {
        return null;
    }

    @Override
    public List<GoodsSpecs> getList(Map<String, Object> map) {

        GoodsSpecsExample goodsSpecsExample = new GoodsSpecsExample();
        GoodsSpecsExample.Criteria criteria = goodsSpecsExample.createCriteria();

        if (MapUtils.getLong(map, "goodsId") != null) {
            criteria.andGoodsIdEqualTo(MapUtils.getLong(map, "goodsId"));
        }
        criteria.andStatusNotEqualTo(0);


        return goodsSpecsMapper.selectByExample(goodsSpecsExample);
    }

    @Override
    public void editStockNum(Long specsId, Integer num , Integer type) {
        String key = "GOODS_STOCK_NUM";

        GoodsSpecs goodsSpecs = queryDetailByGoodsId(specsId);
        // 分布式锁占坑
        Boolean lock = redisTemplate.opsForValue().setIfAbsent(key, specsId);

        try {

            if(Boolean.TRUE.equals(lock)) {

                if (type == 1) {
                    // 加锁成功，处理业务
                    goodsSpecs.setStock(goodsSpecs.getStock() + num);
                } else {
                    if (goodsSpecs.getStock() < num) {
                        throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, goodsSpecs.getName() + "库存不足");
                    }
                    // 加锁成功，处理业务
                    goodsSpecs.setStock(goodsSpecs.getStock() - num);
                }

                update(goodsSpecs);

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

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