package com.liquidnet.service.consumer.order.utils;

import com.liquidnet.common.cache.redis.util.RedisUtil;
import com.liquidnet.service.goblin.constant.GoblinRedisConst;
import com.liquidnet.service.goblin.dto.vo.GoblinListCollectVo;
import com.liquidnet.service.goblin.dto.vo.GoblinNftOrderVo;
import com.mongodb.BasicDBObject;
import com.mongodb.client.result.UpdateResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.convert.MongoConverter;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Component
public class GoblinNftUtils {

    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private MongoConverter mongoConverter;

    private static final BasicDBObject basicDBObject = new BasicDBObject();

    // 库存
    public int decrSkuStock(String skuId, Integer stock) {
        String redisKey = GoblinRedisConst.REAL_STOCK_SKU.concat(skuId);
        return (int) redisUtil.decr(redisKey, stock);
    }

    public int incrSkuStock(String marketPre, String skuId, Integer stock) {
        String rk = GoblinRedisConst.REAL_STOCK_SKU;
        if (marketPre != null && !marketPre.equals("null")) {
            rk = rk.concat(marketPre + ":");
        }
        rk = rk.concat(skuId);
        return (int) redisUtil.incr(rk, stock);
    }

    // 减少 用户sku购买个数
    public int decrSkuCountByUid(String uid, String skuId, int number) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_BUY_COUNT.concat(uid + ":skuId:" + skuId);
        return (int) redisUtil.decr(redisKey, number);
    }

    // 订单详情vo
    public void setNftOrder(GoblinNftOrderVo vo) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_NFT_ORDER_INFO.concat(vo.getOrderId());
        redisUtil.set(redisKey, vo);
    }

    // 获取 订单详情vo
    public GoblinNftOrderVo getNftOrder(String orderId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_NFT_ORDER_INFO.concat(orderId);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return null;
        } else {
            return (GoblinNftOrderVo) obj;
        }
    }

    // 订单详情vo
    public void setGoblinNftOrderVo(GoblinNftOrderVo vo) {
        mongoTemplate.insert(vo, GoblinNftOrderVo.class.getSimpleName());
    }

    /**
     * 根据时间获取当前分段购vo 如果当前没有返回下一个
     *
     * @param now
     * @param skuId
     * @return
     */
    public GoblinListCollectVo getCollectByNowNext(LocalDateTime now, String skuId) {
        GoblinListCollectVo collectVo = null;
        GoblinListCollectVo collectTemp = null;
        GoblinListCollectVo collectNext = null;
        List<GoblinListCollectVo> collectVos = getGoblinListCollect(skuId);
        for (int i = 0; i < collectVos.size(); i++) {
            GoblinListCollectVo collectVoItem = collectVos.get(i);
            if (now.isAfter(collectVoItem.getTimeStart()) && collectVoItem.getTimeEnd() == null) {
                if (collectTemp == null || collectTemp.getTimeStart().isBefore(collectVoItem.getTimeStart())) {
                    collectTemp = collectVoItem;
                }
            } else if (now.isAfter(collectVoItem.getTimeStart()) && now.isBefore(collectVoItem.getTimeEnd())) {
                collectVo = collectVoItem;
            } else if (now.isBefore(collectVoItem.getTimeStart())) {
                if (collectNext == null || collectNext.getTimeStart().isAfter(collectNext.getTimeStart())) {
                    collectNext = collectVoItem;
                }
            }else if(collectVoItem.getTimeEnd() != null && now.isAfter(collectVoItem.getTimeEnd())){
                collectTemp = null;
            }
        }
        if (collectVo == null && collectTemp != null) {
            collectVo = collectTemp;
        } else if (collectVo == null) {
            collectVo = collectNext;
        }
        return collectVo;
    }

    /**
     * 分段购获取
     *
     * @param skuId
     * @return
     */
    public List<GoblinListCollectVo> getGoblinListCollect(String skuId) {
        Object obj = redisUtil.get(GoblinRedisConst.LIST_COLLECT.concat(skuId));
        if (obj == null) {
            return new ArrayList<>();
        } else {
            List<GoblinListCollectVo> list = (List<GoblinListCollectVo>) obj;
            list = list.stream().sorted(Comparator.comparing(GoblinListCollectVo::getTimeStart)).collect(Collectors.toList());
            return list;
        }
    }

    public UpdateResult updateGoblinNftOrderVo(GoblinNftOrderVo data) {
        BasicDBObject object = cloneBasicDBObject().append("$set", mongoConverter.convertToMongoType(data));
        return mongoTemplate.getCollection(GoblinNftOrderVo.class.getSimpleName()).updateOne(
                Query.query(Criteria.where("orderId").is(data.getOrderId())).getQueryObject(),
                object);
    }

    public static BasicDBObject cloneBasicDBObject() {
        return (BasicDBObject) basicDBObject.clone();
    }

}
