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.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
@Slf4j
public class GoblinNftGoodsAppServiceImpl implements IGoblinNftGoodsAppService {

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

    final static int size = 20;

    @Override
    public ResponseDto<PagedResult<GoblinNftGoodsSkuListVo>> goodsList(int page) {
        LocalDateTime now = LocalDateTime.now();
        List<String> startSkuIdList = goblinRedisUtils.getGoblinNftGoodsInfoListVo("1");
        List<String> notStartSkuIdList = goblinRedisUtils.getGoblinNftGoodsInfoListVo("2");
        List<String> soldOutSkuIdList = goblinRedisUtils.getGoblinNftGoodsInfoListVo("3");
        List<String> allIdList = Stream.of(startSkuIdList, notStartSkuIdList, soldOutSkuIdList).flatMap(Collection::stream).collect(Collectors.toList());

        int finalCount = (page - 1) * size;
        int initCount = page * size;
        if (finalCount < 0) {
            finalCount = 0;
        }
        int allSize = allIdList.size();
        if (initCount > allSize) {
            initCount = allSize;
        }
        List<GoblinNftGoodsSkuListVo> skuList = ObjectUtil.getGoblinNftGoodsSkuListVoArrayList();
        HashMap<String, Object> spuInfoList = CollectionUtil.mapStringObject();
        for (int i = finalCount; i < initCount; i++) {
            String skuId = allIdList.get(i);
            // sku信息
            HashMap<String, Object> map = goblinRedisUtils.getGoodsSkuInfoVo(now, skuId);
            GoblinGoodsSkuInfoVo skuInfoVo = (GoblinGoodsSkuInfoVo) map.get("vo");
            Integer tagType = (Integer) map.get("tagType");
            String listId = (String) map.get("listId");
            LocalDateTime baseSaleStartTime = (LocalDateTime) map.get("baseSaleStartTime");
            LocalDateTime nextSaleStartTime = (LocalDateTime) map.get("nextSaleStartTime");
            LocalDateTime firstSaleStartTime = (LocalDateTime) map.get("firstSaleStartTime");
            LocalDateTime firstSaleEndTime = (LocalDateTime) map.get("firstSaleEndTime");

            GoblinNftGoodsSkuListVo goblinNftGoodsSkuListVo = GoblinNftGoodsSkuListVo.getNew().copy(skuInfoVo);
            // spu信息
            Object spuInfoMap = spuInfoList.get(skuInfoVo.getSpuId());
            GoblinGoodsInfoVo goodsInfoVo = goblinRedisUtils.getGoodsInfoVo(skuInfoVo.getSpuId());
            if (null == spuInfoMap) {
                GoblinNftGoodsSpuInfoVo nftGoodsSpuInfoVo = GoblinNftGoodsSpuInfoVo.getNew().copy(goodsInfoVo);
                spuInfoList.put(skuInfoVo.getSpuId(), nftGoodsSpuInfoVo);
                goblinNftGoodsSkuListVo.setGoblinNftGoodsSpuInfoVo(nftGoodsSpuInfoVo);
            } else {
                goblinNftGoodsSkuListVo.setGoblinNftGoodsSpuInfoVo((GoblinNftGoodsSpuInfoVo) spuInfoMap);
            }
            // 链
            String routeType = "";
            if (skuInfoVo.getUnbox().equals("1")) {
                for (String routeSkuId : goodsInfoVo.getSkuIdList()) {
                    if ("".equals(routeType)) {
                        routeType = goblinRedisUtils.getGoodsSkuInfoVo(routeSkuId).getRouteType();
                    } else {
                        break;
                    }
                }
            } else {
                routeType = skuInfoVo.getRouteType();
            }
            //转赠时间
            Map<String, Long> artworkTransferConfMap = goblinRedisUtils.getUserDigitalArtworkTransferConfMap();
            goblinNftGoodsSkuListVo.setRouteType(routeType);
            goblinNftGoodsSkuListVo.setTransferTimeLimit(artworkTransferConfMap.get(routeType));
            goblinNftGoodsSkuListVo.setTransferable(1);
            goblinNftGoodsSkuListVo.setListId(listId);
            goblinNftGoodsSkuListVo.setBaseSaleStartTime(baseSaleStartTime);
            goblinNftGoodsSkuListVo.setNextSaleStartTime(nextSaleStartTime);
            goblinNftGoodsSkuListVo.setFirstSaleEndTime(firstSaleEndTime);
            goblinNftGoodsSkuListVo.setFirstSaleStartTime(firstSaleStartTime);

            // 库存、预约
            if (soldOutSkuIdList.contains(skuId)) {// 是售罄的
                goblinNftGoodsSkuListVo.setIsStock(0);
            } else {
                goblinNftGoodsSkuListVo.setIsStock(1);
                // 获取预约相关 未售罄的才查询预约
                AnticipateValueVo anticipateValueVo = goblinGoodsAnticipateMgService.getAnticipateValueBySkuId(skuId, 0);
                goblinNftGoodsSkuListVo.setAnticipateValueVo(anticipateValueVo);
            }
            goblinNftGoodsSkuListVo.setTagType(tagType);
            // 写入列表
            skuList.add(goblinNftGoodsSkuListVo);
        }

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

    /*@Override
    public ResponseDto<PagedResult<GoblinNftGoodsSkuListVo>> goodsList(int page) {
        List<String> startSkuIdList = goblinRedisUtils.getGoblinNftGoodsInfoListVo("1");
        List<String> notStartSkuIdList = goblinRedisUtils.getGoblinNftGoodsInfoListVo("2");
        List<String> soldOutSkuIdList = goblinRedisUtils.getGoblinNftGoodsInfoListVo("3");
        List<String> allIdList = Stream.of(startSkuIdList, notStartSkuIdList, soldOutSkuIdList).flatMap(Collection::stream).collect(Collectors.toList());

        int finalCount = (page - 1) * size;
        int initCount = page * size;
        if (finalCount < 0) {
            finalCount = 0;
        }
        int allSize = allIdList.size();
        if (initCount > allSize) {
            initCount = allSize;
        }
        List<GoblinNftGoodsSkuListVo> skuList = ObjectUtil.getGoblinNftGoodsSkuListVoArrayList();
        for (int i = finalCount; i < initCount; i++) {
            String skuId = allIdList.get(i);
            // sku信息
            GoblinNftGoodsSkuListVo goblinNftGoodsListInfoVo = goblinRedisUtils.getGoblinNftGoodsListInfoVo(skuId);
            if (null != goblinNftGoodsListInfoVo) {
                // 库存、预约
                if (soldOutSkuIdList.contains(skuId)) {// 是售罄的
                    goblinNftGoodsListInfoVo.setIsStock(0);
                } else {
                    goblinNftGoodsListInfoVo.setIsStock(1);
                }
                // 写入列表
                skuList.add(goblinNftGoodsListInfoVo);
            }
        }

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

    @Override
    public GoblinNftGoodsSkuInfoVo goodsDetail(String skuId) {
        // 1
        LocalDateTime now = LocalDateTime.now();
        HashMap<String, Object> map = goblinRedisUtils.getGoodsSkuInfoVo(now, skuId);
        if (null == map) {
            return null;
        }
        GoblinGoodsSkuInfoVo skuInfoVo = (GoblinGoodsSkuInfoVo) map.get("vo");
        Integer tagType = (Integer) map.get("tagType");
        String listId = (String) map.get("listId");
        LocalDateTime baseSaleStartTime = (LocalDateTime) map.get("baseSaleStartTime");
        LocalDateTime nextSaleStartTime = (LocalDateTime) map.get("nextSaleStartTime");
        LocalDateTime firstSaleStartTime = (LocalDateTime) map.get("firstSaleStartTime");
        LocalDateTime firstSaleEndTime = (LocalDateTime) map.get("firstSaleEndTime");
        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 = goblinOrderUtils.getIsStock(listId, skuId, skuInfoVo.getUnbox(), skuInfoVo.getSoldoutStatus(), goodsInfoVo.getSkuIdList());
            nftGoodsSkuInfoVo.setIsStock(stockHashMap.get("isStock"));
            // 总库存&链
            String routeType = "";
            if (skuInfoVo.getUnbox().equals("1")) {
                nftGoodsSkuInfoVo.setSkuStock(stockHashMap.get("totalStock"));
                for (String routeSkuId : goodsInfoVo.getSkuIdList()) {
                    if ("".equals(routeType)) {
                        routeType = goblinRedisUtils.getGoodsSkuInfoVo(routeSkuId).getRouteType();
                    } else {
                        break;
                    }
                }
            } else {
                routeType = skuInfoVo.getRouteType();
            }
            //转赠时间
            Map<String, Long> artworkTransferConfMap = goblinRedisUtils.getUserDigitalArtworkTransferConfMap();
            nftGoodsSkuInfoVo.setRouteType(routeType);
            nftGoodsSkuInfoVo.setTransferTimeLimit(artworkTransferConfMap.get(routeType));

            // 系统时间
            nftGoodsSkuInfoVo.setSystime(LocalDateTime.now());
            nftGoodsSkuInfoVo.setTagType(tagType);
            nftGoodsSkuInfoVo.setListId(listId);
            nftGoodsSkuInfoVo.setBaseSaleStartTime(baseSaleStartTime);
            nftGoodsSkuInfoVo.setNextSaleStartTime(nextSaleStartTime);
            nftGoodsSkuInfoVo.setFirstSaleEndTime(firstSaleEndTime);
            nftGoodsSkuInfoVo.setFirstSaleStartTime(firstSaleStartTime);
            // 是否开启兑换
            nftGoodsSkuInfoVo.setIsExchange(goblinRedisUtils.getIsExchange(skuId));
            // 待支付订单数量
            nftGoodsSkuInfoVo.setNotPayNum(goblinRedisUtils.getNotPayNum(skuId, listId));
            return nftGoodsSkuInfoVo;
        } else {
            return null;
        }
    }
}
