package com.liquidnet.service.order.utils;

import com.fasterxml.jackson.core.type.TypeReference;
import com.liquidnet.common.cache.redis.util.RedisUtil;
import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.goblin.constant.GoblinRedisConst;
import com.liquidnet.service.goblin.constant.GoblinStatusConst;
import com.liquidnet.service.goblin.dto.vo.*;
import com.liquidnet.service.kylin.constant.KylinRedisConst;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;

@Component
public class GoblinRedisUtils {
    @Autowired
    RedisUtil redisUtil;
    @Autowired
    GoblinMongoUtils goblinMongoUtils;

    private int randomMax = 10;


    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);
    }

    public int decrSkuStock(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.decr(rk, stock);
    }

    public int getSkuStock(String skuId) {
        String rk = GoblinRedisConst.REAL_STOCK_SKU.concat(skuId);
        Object obj = redisUtil.get(rk);
        if (obj == null) {
            return 0;
        } else {
            return (int) obj;
        }
    }

    public GoblinStoreInfoVo getStoreInfoVo(String storeId) {
        String rk = GoblinRedisConst.BASIC_STORE.concat(storeId);
        GoblinStoreInfoVo vo = (GoblinStoreInfoVo) redisUtil.get(rk);
        if (null == vo && null != (vo = goblinMongoUtils.getStoreInfoVo(storeId))) {
            redisUtil.set(rk, vo);
        }
        return vo;
    }

    /* ---------------------------------------- 商品数据源 ---------------------------------------- */

    /**
     * 商品基础信息
     *
     * @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;
        }
    }

    /**
     * 单品信息
     *
     * @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;
        }
    }

    //获取 用户sku购买个数
    public Integer getSkuCountByUid(String uid, String skuId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_BUY_COUNT.concat(uid + ":skuId:" + skuId);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return 0;
        } else {
            return (Integer) obj;
        }
    }

    //获取 用户是否可购买
    public boolean getSkuCanBuyByUid(String mobile, String skuId) {
        String redisKey = GoblinRedisConst.REDIS_CAN_BUY.concat(skuId + ":").concat(mobile);
        return redisUtil.hasKey(redisKey);
    }

    // 增加 用户sku购买个数
    public int incrSkuCountByUid(String uid, String skuId, int number) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_BUY_COUNT.concat(uid + ":skuId:" + skuId);
        return (int) redisUtil.incr(redisKey, number);
    }

    // 减少 用户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);
    }

    // 增加 sku销量
    public int incrSkuSaleCount(String spuId, String skuId, int number) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_SALE_COUNT.concat(skuId);
        incrSpuSaleCount(spuId, number);
        return (int) redisUtil.incr(redisKey, number);
    }

    // 增加 spu销量
    private int incrSpuSaleCount(String spuId, int number) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_SALE_SPU_COUNT.concat(spuId);
        return (int) redisUtil.incr(redisKey, number);
    }

    // 赋值 订单相关vo
    public void setGoblinOrder(String orderId, GoblinStoreOrderVo vo) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_ORDER.concat(orderId);
        redisUtil.set(redisKey, vo);
    }

    // 赋值 订单相关Skuvo
    public void setGoblinOrderSku(String orderSkuId, GoblinOrderSkuVo vo) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_ORDER_SKU.concat(orderSkuId);
        redisUtil.set(redisKey, vo);
    }

    // 获取 订单相关vo
    public GoblinStoreOrderVo getGoblinOrder(String orderId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_ORDER.concat(orderId);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return null;
        } else {
            return (GoblinStoreOrderVo) obj;
        }
    }

    // 获取 订单相关Skuvo
    public GoblinOrderSkuVo getGoblinOrderSkuVo(String orderSkuId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_ORDER_SKU.concat(orderSkuId);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return null;
        } else {
            return (GoblinOrderSkuVo) obj;
        }
    }

    // 获取 订单id列表
    public List<String> getOrderList(String uid) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_ORDER_LIST.concat(uid);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return CollectionUtil.arrayListString();
        } else {
            return (List<String>) obj;
        }
    }

    // 添加 订单id列表
    public void addOrderList(String uid, String orderId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_ORDER_LIST.concat(uid);
        List<String> list = getOrderList(uid);
        if (list.size() >= 40) {
            list.remove(0);
            list.add(orderId);
        } else {
            list.add(orderId);
        }
        redisUtil.set(redisKey, list);
    }

    // 获取 订单id列表
    public List<String> getZhengzaiOrderList(String uid) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_ORDER_ZHENGZAI_LIST.concat(uid);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return CollectionUtil.arrayListString();
        } else {
            return (List<String>) obj;
        }
    }

    // 添加 订单id列表
    public void addZhengzaiOrderList(String uid, String orderId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_ORDER_ZHENGZAI_LIST.concat(uid);
        List<String> list = getZhengzaiOrderList(uid);
        list.add(orderId);
        redisUtil.set(redisKey, list);
    }

    //主订单下包含的子订单
    public void setMasterCode(String masterCode, String orderIds) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_ORDER_MASTER.concat(masterCode);
        redisUtil.set(redisKey, orderIds);
    }

    public String[] getMasterCode(String masterCode) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_ORDER_MASTER.concat(masterCode);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return null;
        } else {
            return ((String) obj).split(",");
        }
    }

    //主订单对应的出货吗
    public void setOffCode(String writeOffCode, String masterCode) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_ORDER_OFFCODE.concat(writeOffCode);
        redisUtil.set(redisKey, masterCode);
    }

    //覆盖 退款订单vo
    public void setBackOrderVo(String backOrderId, GoblinBackOrderVo vo) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_ORDER_BACK.concat(backOrderId);
        redisUtil.set(redisKey, vo);
    }

    public TempCouponVo getTempCoupon(String ucouponId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_TEMP_COUPON.concat(ucouponId);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return null;
        } else {
            return (TempCouponVo) obj;
        }
    }

    // 获取 快递vo
    public List<GoblinMailVo> getGoblinMail(String orderId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_MAIL.concat(orderId);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return ObjectUtil.goblinMailVo();
        } else {
            return (List<GoblinMailVo>) obj;
        }
    }

    public List<GoblinUserCouponVo> getUserCouponVos(String uid) {
        String rk = GoblinRedisConst.USER_COUPON.concat(uid);
        String valStr = (String) redisUtil.get(rk);
        List<GoblinUserCouponVo> vos;
        if (StringUtils.isEmpty(valStr)) {
            return ObjectUtil.getGoblinUserCouponVo();
        } else {
            vos = JsonUtils.fromJson(valStr, new TypeReference<List<GoblinUserCouponVo>>() {
            });
        }
        return vos;
    }

    public List<String> getStoreCouponSpuIds(String storeCouponId) {
        String rk = GoblinRedisConst.STORE_COUPON_RULE.concat(storeCouponId);
        String valStr = (String) redisUtil.get(rk);
        List<String> strs;
        if (StringUtils.isEmpty(valStr)) {
            GoblinStoreCouponBasicVo storeCouponBasicVo = goblinMongoUtils.getMgtStoreCouponBasicVo(storeCouponId);
            strs = null == storeCouponBasicVo ? null : storeCouponBasicVo.getSpuIdList();
            if (!CollectionUtils.isEmpty(strs)) {
                redisUtil.set(rk, JsonUtils.toJson(strs));
            }
        } else {
            strs = JsonUtils.fromJson(valStr, new TypeReference<List<String>>() {
            });
        }
        return strs;
    }

    public boolean setUserCouponVos(String uid, List<GoblinUserCouponVo> vos) {
        return redisUtil.set(GoblinRedisConst.USER_COUPON.concat(uid), JsonUtils.toJson(vos));
    }

    // 1普通会员 2老会员
    public Integer getMember(String uid) {
        String redisKey = KylinRedisConst.ADAM_IS_MEMBER
                .concat(uid);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return null;
        } else {
            return (Integer) obj;
        }
    }

    // 添加 订单id下的退款订单id
    public void addBackOrderByOrderId(String orderId, String backOrderId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_BACK_ORDER_ID.concat(orderId);
        List<String> list = getBackOrderByOrderId(orderId);
        list.add(backOrderId);
        redisUtil.set(redisKey, list);
    }

    // 获取 订单id下的退款订单id
    public List<String> getBackOrderByOrderId(String orderId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_BACK_ORDER_ID.concat(orderId);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return CollectionUtil.arrayListString();
        } else {
            return (List<String>) obj;
        }
    }

    public boolean getNftNumAccount(String userId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_NFT_NUM_ACCOUNT.concat(userId);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return false;
        } else {
            return true;
        }
    }

    /* ----------------------------------- 我的藏品生成 ----------------------------------- */

    /**
     * 标记订单藏品生成
     */
    public boolean markGenUserDigitalArtwork(String uid, String skuId, String orderId) {
        return redisUtil.set(GoblinRedisConst.USER_DIGITAL_ARTWORK_GENMARK.concat(uid).concat(skuId).concat(orderId), 1, 259200);
    }

    /**
     * 判断订单藏品生成
     */
    public boolean hasGenUserDigitalArtwork(String uid, String skuId, String orderId) {
        return redisUtil.hasKey(GoblinRedisConst.USER_DIGITAL_ARTWORK_GENMARK.concat(uid).concat(skuId).concat(orderId));
    }

    /**
     * 缓存用户藏品详情
     */
    public boolean setGoblinUserDigitalArtworkVo(GoblinUserDigitalArtworkVo vo) {
        return redisUtil.set(GoblinRedisConst.USER_DIGITAL_ARTWORK.concat(vo.getArtworkId()), vo);
    }

    /**
     * 获取用户藏品ID集合
     */
    public List<String> getGoblinUserDigitalArtworkIds(String uid) {
        return (List<String>) redisUtil.get(GoblinRedisConst.USER_DIGITAL_ARTWORK_IDS.concat(uid));
    }

    /**
     * 缓存用户藏品ID集合
     */
    public boolean setGoblinUserDigitalArtworkIds(String uid, List<String> userDigitalArtworkIds) {
        return redisUtil.set(GoblinRedisConst.USER_DIGITAL_ARTWORK_IDS.concat(uid), userDigitalArtworkIds);
    }

    /**
     * 缓存并更新用户藏品ID集合
     */
    public boolean addGoblinUserDigitalArtworkIds(String uid, String artworkId) {
        List<String> ids = this.getGoblinUserDigitalArtworkIds(uid);
        if (CollectionUtils.isEmpty(ids)) {
            ids = CollectionUtil.arrayListString();
            ids.add(artworkId);
        } else {
            ids.add(0, artworkId);
            int size = ids.size();
            if (size > 30) ids.remove(size - 1);
        }
        return redisUtil.set(GoblinRedisConst.USER_DIGITAL_ARTWORK_IDS.concat(uid), ids);
    }

    /**
     * 缓存用户累计藏品数
     */
    public long incrGoblinUserDigitalArtworks(String uid) {
        return redisUtil.incr(GoblinRedisConst.USER_DIGITAL_ARTWORK_CT.concat(uid), 1);
    }

    /* ----------------------------------- ---------- ----------------------------------- */

    /**
     * 记录用户是否购买过技术部数字藏品
     * @param uid
     */
    public void setBuyNftTec(String uid) {
        String rdk = GoblinRedisConst.BUY_NFT_TEC.concat(uid);
        redisUtil.set(rdk, 1);
    }

    /* -----------------------------------  ----------------------------------- */
}
