package com.liquidnet.service.kylin.utils;

import com.liquidnet.common.cache.redis.util.RedisUtil;
import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.service.goblin.constant.GoblinRedisConst;
import com.liquidnet.service.goblin.constant.GoblinStatusConst;
import com.liquidnet.service.goblin.dto.vo.GoblinGoodsInfoVo;
import com.liquidnet.service.goblin.dto.vo.GoblinGoodsSkuInfoVo;
import com.liquidnet.service.goblin.dto.vo.GoblinListCollectVo;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Component;

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

@Component
public class GoblinRedisUtils {

    @Autowired
    RedisUtil redisUtil;

    @Autowired
    GoblinMongodbUtils goblinMongoUtils;


    /**
     * 获取 包含分段购的sku详情 HASHMAP
     *
     * @param now   当前时间
     * @param skuId skuId
     * @return
     */
    public HashMap<String, Object> getGoodsSkuInfoVo(LocalDateTime now, String skuId) {
        GoblinGoodsSkuInfoVo vo = getGoodsSkuInfoVo(skuId);
        if (null == vo) {
            return null;
        }
        HashMap<String, Object> map = CollectionUtil.mapStringObject();
        LocalDateTime nextSaleStartTime = null;
        if (null == vo.getSaleStartTime() || now.isAfter(vo.getSaleStartTime())) {//普通商品已开售
            map.put("vo", vo);
            map.put("tagType", null);
            map.put("listId", null);
            map.put("whiteType", null);
            map.put("baseSaleStartTime", vo.getSaleStartTime());
            map.put("nextSaleStartTime", null);
        } else {//未开售
            GoblinListCollectVo collectVo = getCollectByNow(now, skuId);
            Integer tagType = null;
            Integer whiteType = null;
            String listId = null;
            LocalDateTime baseSaleStartTime = vo.getSaleStartTime();
            if (collectVo != null) {
                vo.setPrice(collectVo.getPrice());
                vo.setPriceV(collectVo.getPriceV());
                vo.setProductId(collectVo.getProductId());
                vo.setSaleStartTime(collectVo.getTimeStart());
                vo.setSaleStopTime(collectVo.getTimeEnd());
                listId = collectVo.getListId();
                whiteType = collectVo.getWhiteType();
                tagType = collectVo.getTagType();
            }
            GoblinListCollectVo collectNext = getCollectByNowNext(now, skuId);
            if (collectNext != null) {
                if (tagType == null) {
                    tagType = collectNext.getTagType();
                }
                //todo 逻辑修改 开售时间
                if (collectVo == null) {
                    vo.setSaleStartTime(collectNext.getTimeStart());
                    vo.setSaleStopTime(collectNext.getTimeEnd());
                }
                nextSaleStartTime = collectNext.getTimeStart();
            }
            map.put("vo", vo);
            map.put("tagType", tagType);
            map.put("listId", listId);
            map.put("whiteType", whiteType);
            map.put("baseSaleStartTime", baseSaleStartTime);
            map.put("nextSaleStartTime", nextSaleStartTime);
        }
        return map;
    }

    /**
     * 单品信息
     *
     * @param skuId 单品ID
     * @return GoblinGoodsSkuInfoVo
     */
    public GoblinGoodsSkuInfoVo getGoodsSkuInfoVo(String skuId) {
        String pre = GoblinStatusConst.MarketPreStatus.getPre(skuId);
        if (pre != null && pre.equals(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue())) {

            String rk = GoblinRedisConst.BASIC_GOODS_SKU.concat(skuId.split(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue())[0]);
            GoblinGoodsSkuInfoVo vo = (GoblinGoodsSkuInfoVo) redisUtil.get(rk);
            if (null == vo && null != (vo = goblinMongoUtils.getGoodsSkuInfoVo(skuId))) {
                redisUtil.set(rk, vo);
            }
            if (vo == null) {
                return vo;
            }
            String marketrk = GoblinRedisConst.BASIC_GOODS_SKU.concat(skuId);
            GoblinGoodsSkuInfoVo marketVo = (GoblinGoodsSkuInfoVo) redisUtil.get(marketrk);
            if (null == marketVo && null != (marketVo = goblinMongoUtils.getGoodsSkuInfoVo(skuId))) {
                redisUtil.set(marketrk, marketVo);
            }
            if (marketVo == null) {
                return marketVo;
            }

            vo.setSpuId(marketVo.getSpuId());
            vo.setSkuId(marketVo.getSkuId());
            vo.setPrice(marketVo.getPrice());
            vo.setPriceMember(marketVo.getPriceMember());
            vo.setSkuStock(marketVo.getSkuStock());
            vo.setBuyLimit(marketVo.getBuyLimit());
            vo.setBuyRoster(marketVo.getBuyRoster());
            vo.setBuyFactor(marketVo.getBuyFactor());
//            vo.setDelFlg("0");
            vo.setDelFlg(marketVo.getDelFlg().equals("1") ? marketVo.getDelFlg() : vo.getDelFlg());
            vo.setMarketId(marketVo.getMarketId());
            vo.setCreatedAt(LocalDateTime.now());
            return vo;
        } else {
            String rk = GoblinRedisConst.BASIC_GOODS_SKU.concat(skuId);
            GoblinGoodsSkuInfoVo vo = (GoblinGoodsSkuInfoVo) redisUtil.get(rk);
            if (null == vo && null != (vo = goblinMongoUtils.getGoodsSkuInfoVo(skuId))) {
                redisUtil.set(rk, vo);
            }
            return vo;
        }
    }



    /**
     * 根据时间获取当前分段购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;
        return collectNext;
    }

    public List<GoblinListCollectVo> getGoblinListCollect(String skuId) {
        Object obj = redisUtil.get(GoblinRedisConst.LIST_COLLECT.concat(skuId));
        if (obj == null) {
            return ObjectUtil.getGoblinListCollectVo();
        } else {
            List<GoblinListCollectVo> list = (List<GoblinListCollectVo>) obj;
            list = list.stream().sorted(Comparator.comparing(GoblinListCollectVo::getTimeStart)).collect(Collectors.toList());
            return list;
        }
    }

    /**
     * 根据时间获取当前分段购vo
     *
     * @param now
     * @param skuId
     * @return
     */
    public GoblinListCollectVo getCollectByNow(LocalDateTime now, String skuId) {
        GoblinListCollectVo collectVo = null;
        GoblinListCollectVo collectTemp = 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;
                break;
            } else if (collectVoItem.getTimeEnd() != null && now.isAfter(collectVoItem.getTimeEnd())) {
                collectTemp = null;
            }
        }
        if (collectVo == null) {
            collectVo = collectTemp;
        }
        return collectVo;
    }



    /**
     * 商品基础信息
     *
     * @param spuId 商品ID
     * @return GoblinGoodsInfoVo
     */
    public GoblinGoodsInfoVo getGoodsInfoVo(String spuId) {
        String pre = GoblinStatusConst.MarketPreStatus.getPre(spuId);
        if (pre != null && pre.equals(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue())) {
            String[] spuSplitArr = spuId.split(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue());
            String rk = GoblinRedisConst.BASIC_GOODS.concat(spuSplitArr[0]);
            GoblinGoodsInfoVo vo = (GoblinGoodsInfoVo) redisUtil.get(rk);
            if (null == vo && null != (vo = goblinMongoUtils.getGoodsInfoVo(spuId))) {
                redisUtil.set(rk, vo);
            }
            if (vo == null) {
                return vo;
            }
            String marketrk = GoblinRedisConst.BASIC_GOODS.concat(spuId);
            GoblinGoodsInfoVo marketVo = (GoblinGoodsInfoVo) redisUtil.get(marketrk);
            if (null == marketVo && null != (marketVo = goblinMongoUtils.getGoodsInfoVo(spuId))) {
                redisUtil.set(marketrk, marketVo);
            }
            if (marketVo == null) {
                return marketVo;
            }
            vo.setSpuId(marketVo.getSpuId());
            List<String> skuIdList = CollectionUtil.linkedListString();
            for (String skuIds : vo.getSkuIdList()) {
                skuIdList.add(skuIds.concat(pre).concat(spuSplitArr[1]));
            }
            vo.setSkuIdList(skuIdList);
            vo.setPriceGe(marketVo.getPriceGe());
            vo.setPriceLe(marketVo.getPriceLe());
            vo.setMarketId(marketVo.getMarketId());
            vo.setDelFlg(marketVo.getDelFlg().equals("1") ? marketVo.getDelFlg() : vo.getDelFlg());
            return vo;
        } else {
            String rk = GoblinRedisConst.BASIC_GOODS.concat(spuId);
            GoblinGoodsInfoVo vo = (GoblinGoodsInfoVo) redisUtil.get(rk);
            if (null == vo && null != (vo = goblinMongoUtils.getGoodsInfoVo(spuId))) {
                redisUtil.set(rk, vo);
            }
            return vo;
        }
    }
}
