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.GoodsMsgMapper;
import com.hfkj.entity.GoodsBrand;
import com.hfkj.entity.GoodsMsg;
import com.hfkj.entity.GoodsMsgExample;
import com.hfkj.service.goods.GoodsMsgService;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
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("goodsMsgService")
public class GoodsMsgServiceImpl implements GoodsMsgService {

    @Resource
    private GoodsMsgMapper goodsMsgMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public void create(GoodsMsg goodsMsg) {
        goodsMsgMapper.insert(goodsMsg);
    }

    @Override
    public void update(GoodsMsg goodsMsg) {
        goodsMsgMapper.updateByPrimaryKeySelective(goodsMsg);
    }

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

    @Override
    public GoodsMsg queryDetail(Long id) {
        return goodsMsgMapper.selectByPrimaryKey(id);
    }

    @Override
    public GoodsMsg queryDetailByMap(Map<String, Object> map) {
        GoodsMsgExample example = new GoodsMsgExample();
        GoodsMsgExample.Criteria criteria = example.createCriteria();

        if (MapUtils.getLong(map, "goodsType") != null) {
            criteria.andGoodsTypeEqualTo(MapUtils.getLong(map, "goodsType"));
        }
        if (MapUtils.getLong(map, "goodsTypeParent") != null) {
            criteria.andGoodsTypeParentEqualTo(MapUtils.getLong(map, "goodsTypeParent"));
        }
        if (MapUtils.getInteger(map, "type") != null) {
            criteria.andTypeEqualTo(MapUtils.getInteger(map, "type"));
        }
        if (MapUtils.getLong(map, "goodsBrand") != null) {
            criteria.andGoodsBrandEqualTo(MapUtils.getLong(map, "goodsBrand"));
        }
        if (MapUtils.getLong(map, "merId") != null) {
            criteria.andMerIdEqualTo(MapUtils.getLong(map, "merId"));
        }

        List<GoodsMsg> list = goodsMsgMapper.selectByExample(example);
        if (!list.isEmpty()) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public List<GoodsMsg> getList(Map<String, Object> map) {
        GoodsMsgExample example = new GoodsMsgExample();
        GoodsMsgExample.Criteria criteria = example.createCriteria();

        if (MapUtils.getLong(map, "goodsType") != null) {
            criteria.andGoodsTypeEqualTo(MapUtils.getLong(map, "goodsType"));
        }
        if (MapUtils.getLong(map, "goodsTypeParent") != null) {
            criteria.andGoodsTypeParentEqualTo(MapUtils.getLong(map, "goodsTypeParent"));
        }
        if (MapUtils.getInteger(map, "type") != null) {
            criteria.andTypeEqualTo(MapUtils.getInteger(map, "type"));
        }
        if (MapUtils.getLong(map, "goodsBrand") != null) {
            criteria.andGoodsBrandEqualTo(MapUtils.getLong(map, "goodsBrand"));
        }
        if (MapUtils.getLong(map, "merId") != null) {
            criteria.andMerIdEqualTo(MapUtils.getLong(map, "merId"));
        }
        if (StringUtils.isNotBlank(MapUtils.getString(map, "title"))) {
            criteria.andTitleLike("%"+MapUtils.getString(map, "title")+"%");
        }
        if (MapUtils.getInteger(map, "status") != null) {
            criteria.andStatusEqualTo(MapUtils.getInteger(map, "status"));
        } else {
            criteria.andStatusNotEqualTo(0);
        }

        if (MapUtils.getInteger(map, "time") != null && MapUtils.getInteger(map, "time") == 1) {
            example.setOrderByClause("create_time desc");
        } else {
            example.setOrderByClause("update_time desc");
        }

        if (MapUtils.getInteger(map, "saleNum") != null && MapUtils.getInteger(map, "saleNum") == 2) {
            example.setOrderByClause("sale_num desc");
        }

        return goodsMsgMapper.selectByExample(example);
    }

    @Override
    public void editSaleNum(Long goodsId, Integer num , Integer type) {

        String key = "GOODS" + goodsId;
        // 分布式锁占坑
        Boolean lock = redisTemplate.opsForValue().setIfAbsent(key, goodsId);


        try {

            GoodsMsg goodsMsg = queryDetail(goodsId);
            if (goodsMsg != null) {

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

                    if (type == 1) {
                        goodsMsg.setSaleNum(goodsMsg.getSaleNum() + num);
                    } else if (type == 2){
                        goodsMsg.setSaleNum(goodsMsg.getSaleNum() - num);
                    }

                    update(goodsMsg);
                } else {
                    // 加锁失败，重试
                    Thread.sleep(100);
                    editSaleNum(goodsId , num , type);
                }


            }

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

    }
}
