package com.liquidnet.service.goblin.service.impl;

import com.liquidnet.common.cache.redis.util.RedisUtil;
import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.CurrentUtil;
import com.liquidnet.service.base.PagedResult;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.goblin.dto.manage.vo.AnticipateValueVo;
import com.liquidnet.service.goblin.dto.vo.*;
import com.liquidnet.service.goblin.service.GoblinCouponService;
import com.liquidnet.service.goblin.service.IGoblinNftGoodsAppService;
import com.liquidnet.service.goblin.service.manage.IGoblinGoodsAnticipateMgService;
import com.liquidnet.service.goblin.util.GoblinMongoUtils;
import com.liquidnet.service.goblin.util.GoblinRedisUtils;
import com.liquidnet.service.goblin.util.ObjectUtil;
import com.liquidnet.service.goblin.util.QueueUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

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

@Service
@Slf4j
public class GoblinNftGoodsAppServiceImpl implements IGoblinNftGoodsAppService {

    @Autowired
    private GoblinRedisUtils goblinRedisUtils;
    @Autowired
    MongoTemplate mongoTemplate;
    @Autowired
    QueueUtils queueUtils;
    @Autowired
    GoblinMongoUtils mongoUtils;
    @Autowired
    RedisUtil redisUtil;
    @Autowired
    GoblinCouponService goblinCouponService;
    @Autowired
    IGoblinGoodsAnticipateMgService goblinGoodsAnticipateMgService;

    final static int size = 40;

    @Override
    public ResponseDto<PagedResult<GoblinNftGoodsSkuListVo>> goodsList(int page) {
        List<String> skuIdList = goblinRedisUtils.getGoblinNftGoodsInfoListVo();
        List<GoblinNftGoodsSkuListVo> skuList = ObjectUtil.getGoblinNftGoodsSkuListVoArrayList();
        if (CollectionUtil.isEmpty(skuIdList) || page > 1) {// 查mongo
            //条件
            Query query = Query.query(
                    Criteria.where("skuType").is(1).and("delFlg").is("0")
                            .and("status").is("3").and("shelvesStatus").is("3")
                            .and("skuAppear").is("0")
            );
            // 分页 排序:按照开售时间
            Pageable pageable = PageRequest.of(page - 1, size, Sort.by(Sort.Direction.ASC, "saleStartTime"));
            query.with(pageable);
            // 查询
            List<GoblinGoodsSkuInfoVo> skuInfoVos = mongoTemplate.find(query, GoblinGoodsSkuInfoVo.class, GoblinGoodsSkuInfoVo.class.getSimpleName());
            for (GoblinGoodsSkuInfoVo skuInfoVo : skuInfoVos) {
                // 获取预约相关
                AnticipateValueVo anticipateValueVo = goblinGoodsAnticipateMgService.getAnticipateValueBySkuId(skuInfoVo.getSkuId(), 0);
                // sku信息
                GoblinNftGoodsSkuListVo nftGoodsSkuInfoVo = GoblinNftGoodsSkuListVo.getNew().copy(skuInfoVo, anticipateValueVo);
                // spu信息
                GoblinGoodsInfoVo goodsInfoVo = goblinRedisUtils.getGoodsInfoVo(skuInfoVo.getSpuId());
                GoblinNftGoodsSpuInfoVo nftGoodsSpuInfoVo = GoblinNftGoodsSpuInfoVo.getNew().copy(goodsInfoVo);
                nftGoodsSkuInfoVo.setGoblinNftGoodsSpuInfoVo(nftGoodsSpuInfoVo);
                // 库存
                HashMap<String, Integer> stockHashMap = getIsStock(skuInfoVo.getSkuId(), skuInfoVo.getUnbox(), skuInfoVo.getSoldoutStatus(), goodsInfoVo.getSkuIdList());
                nftGoodsSkuInfoVo.setIsStock(stockHashMap.get("isStock"));
                // 写入列表
                skuList.add(nftGoodsSkuInfoVo);
                skuIdList.add(nftGoodsSkuInfoVo.getSkuId());
            }
            if (page <= 1) {
                goblinRedisUtils.setGoblinNftGoodsInfoListVo(skuIdList);
            }
        } else {
            for (String skuId : skuIdList) {
                // 获取预约相关
                AnticipateValueVo anticipateValueVo = goblinGoodsAnticipateMgService.getAnticipateValueBySkuId(skuId, 0);
                // sku信息
                GoblinGoodsSkuInfoVo skuInfoVo = goblinRedisUtils.getGoodsSkuInfoVo(skuId);
                GoblinNftGoodsSkuListVo goblinNftGoodsSkuListVo = GoblinNftGoodsSkuListVo.getNew().copy(skuInfoVo, anticipateValueVo);
                // spu信息
                GoblinGoodsInfoVo goodsInfoVo = goblinRedisUtils.getGoodsInfoVo(skuInfoVo.getSpuId());
                GoblinNftGoodsSpuInfoVo nftGoodsSpuInfoVo = GoblinNftGoodsSpuInfoVo.getNew().copy(goodsInfoVo);
                goblinNftGoodsSkuListVo.setGoblinNftGoodsSpuInfoVo(nftGoodsSpuInfoVo);
                // 库存
                HashMap<String, Integer> stockHashMap = getIsStock(skuId, skuInfoVo.getUnbox(), skuInfoVo.getSoldoutStatus(), goodsInfoVo.getSkuIdList());
                goblinNftGoodsSkuListVo.setIsStock(stockHashMap.get("isStock"));
                // 写入列表
                skuList.add(goblinNftGoodsSkuListVo);
            }
        }
        // 库存售罄排序
        List<GoblinNftGoodsSkuListVo> listSort = skuList.stream().sorted(Comparator.comparing(GoblinNftGoodsSkuListVo::getIsStock).reversed()).collect(Collectors.toList());

        PagedResult<GoblinNftGoodsSkuListVo> listVoPagedResult = ObjectUtil.getGoblinNftGoodsSkuListVoPagedResult();
        listVoPagedResult.setList(listSort).setPageSize(size).setCurrentPage(page);
        return ResponseDto.success(listVoPagedResult);
    }

    @Override
    public GoblinNftGoodsSkuInfoVo goodsDetail(String skuId) {
        GoblinGoodsSkuInfoVo skuInfoVo = goblinRedisUtils.getGoodsSkuInfoVo(skuId);
        if (goblinRedisUtils.getSkuAllStatusShow(skuInfoVo)) {
            //获取预约相关
            AnticipateValueVo anticipateValueVo = goblinGoodsAnticipateMgService.getAnticipateValueBySkuId(skuId, 1);

            GoblinNftGoodsSkuInfoVo nftGoodsSkuInfoVo = GoblinNftGoodsSkuInfoVo.getNew().copy(skuInfoVo, anticipateValueVo);
            // 限购数量
            Integer buyCount = 0;
            String userId = CurrentUtil.getCurrentUid();
            if (StringUtils.isNotBlank(userId)) {
                buyCount = goblinRedisUtils.getSkuCountByUid(userId, skuId);
            }
            if (null != skuInfoVo.getBuyLimit() && 0 != skuInfoVo.getBuyLimit()) {
                nftGoodsSkuInfoVo.setCanBuyNum(skuInfoVo.getBuyLimit() - buyCount);
            }
            // spu信息
            GoblinGoodsInfoVo goodsInfoVo = goblinRedisUtils.getGoodsInfoVo(skuInfoVo.getSpuId());
            GoblinNftGoodsDetailSpuInfoVo nftGoodsDetailSpuInfoVo = GoblinNftGoodsDetailSpuInfoVo.getNew().copy(goodsInfoVo);
            nftGoodsSkuInfoVo.setGoblinNftGoodsDetailSpuInfoVo(nftGoodsDetailSpuInfoVo);
            // 库存
            HashMap<String, Integer> stockHashMap = getIsStock(skuId, skuInfoVo.getUnbox(), skuInfoVo.getSoldoutStatus(), goodsInfoVo.getSkuIdList());
            nftGoodsSkuInfoVo.setIsStock(stockHashMap.get("isStock"));
            // 总库存
            if (skuInfoVo.getUnbox().equals("1")) {
                nftGoodsSkuInfoVo.setSkuStock(stockHashMap.get("totalStock"));
            }
            // 系统时间
            nftGoodsSkuInfoVo.setSystime(LocalDateTime.now());
            return nftGoodsSkuInfoVo;
        } else {
            return null;
        }
    }

    // 判断是否售罄
    private HashMap<String, Integer> getIsStock(String skuId, String unbox, String soldoutStatus, List<String> skuIdList) {
        HashMap<String, Integer> returnMap = CollectionUtil.mapStringInteger();
        Integer isStock = 0;
        Integer totalStock = 0;
        if (null == soldoutStatus || soldoutStatus.equals("0")) {// 未设置售罄 查询库存
            int surplusStock = 0;
            if (unbox.equals("0")) {// 不是盲盒
                surplusStock = goblinRedisUtils.getSkuStock(null, skuId);
            } else {
                for (String skuIdItem : skuIdList) {// 盲盒计算所有sku库存总数
                    if (skuIdItem.equals(skuId)) {// 过滤自己
                        continue;
                    }
                    GoblinGoodsSkuInfoVo itemVo = goblinRedisUtils.getGoodsSkuInfoVo(skuIdItem);
                    surplusStock += goblinRedisUtils.getSkuAllStatusStock(itemVo);
                    totalStock += goblinRedisUtils.getSkuTotalStock(itemVo);
                }
            }
            if (surplusStock > 0) {
                isStock = 1;
            }
        }
        returnMap.put("isStock", isStock);
        returnMap.put("totalStock", totalStock);
        return returnMap;
    }

    @Override
    public Boolean exchange(String code) {
        try {
            // 验证
            // 使用
            // 下单
            return true;
        } catch (Exception e) {
            log.error("cityVote5Error", e);
            return false;
        }
    }

}
