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

import com.github.pagehelper.PageInfo;
import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.CurrentUtil;
import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.service.base.PagedResult;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.base.SqlMapping;
import com.liquidnet.service.base.constant.MQConst;
import com.liquidnet.service.goblin.dto.vo.GoblinGoodsSkuInfoVo;
import com.liquidnet.service.goblin.dto.vo.GoblinListDetailsItemVo;
import com.liquidnet.service.goblin.dto.vo.GoblinListDetailsVo;
import com.liquidnet.service.goblin.dto.vo.GoblinListVo;
import com.liquidnet.service.goblin.param.GoblinListCreateItemParam;
import com.liquidnet.service.goblin.param.GoblinListCreateParam;
import com.liquidnet.service.goblin.param.GoblinListUpdateParam;
import com.liquidnet.service.goblin.service.manage.IGoblinListService;
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 org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * <p>
 * 商城-名单表 服务实现类
 * </p>
 *
 * @author liquidnet
 * @since 2022-04-29
 */
@Service
public class GoblinListServiceImpl implements IGoblinListService {

    @Autowired
    GoblinRedisUtils redisUtils;
    @Autowired
    GoblinMongoUtils mongoUtils;
    @Autowired
    QueueUtils queueUtils;

    @Override
    public ResponseDto<PageInfo<GoblinListVo>> getList(String name, Integer page) {
        PageInfo<GoblinListVo> pageResult;
        HashMap<String, Object> map = mongoUtils.getGoblinListVo(name, CurrentUtil.getCurrentUid(), page);
        List<GoblinListDetailsVo> detailsVoList = (List<GoblinListDetailsVo>) map.get("data");
        List<GoblinListVo> voList = ObjectUtil.getGoblinListVo();
        for (GoblinListDetailsVo item : detailsVoList) {
            GoblinListVo vo = GoblinListVo.getNew();
            vo.setListId(item.getListId());
            vo.setName(item.getName());
            vo.setAdvanceMin(item.getAdvanceMin());
            vo.setSkuCount(item.getItemVo().size());
            vo.setHasBlack(item.getBlackUrl().equals("") ? 0 : 1);
        }
        pageResult = new PageInfo(voList);
        pageResult.setTotal((Long) map.get("total"));
        return ResponseDto.success(pageResult);
    }

    @Override
    public ResponseDto<GoblinListDetailsVo> getDetails(String listId) {
        GoblinListDetailsVo vo = redisUtils.getGoblinListDetailsVo(listId);
        if (vo == null || !vo.getUid().equals(CurrentUtil.getCurrentUid())) {
            return ResponseDto.failure("信息错误");
        }
        for (GoblinListDetailsItemVo item : vo.getItemVo()) {
            GoblinGoodsSkuInfoVo skuVo = redisUtils.getGoodsSkuInfoVo(item.getSkuId());
            item.setSkuName(skuVo.getName());
            if (skuVo.getUnbox().equals("0")) {
                item.setSurplusStock(redisUtils.getSkuStock(null, item.getSkuId()));
                item.setStock(skuVo.getSkuStock());
            } else {
                List<String> skuIdList = redisUtils.getGoodsInfoVo(item.getSpuId()).getSkuIdList();
                int surplusStock = 0;
                int stock = 0;
                for (String skuIdItem : skuIdList) {// 盲盒计算所有sku库存总数
                    if (skuIdItem.equals(item.getSkuId())) {// 过滤自己
                        stock += skuVo.getSkuStock();
                        continue;
                    }
                    GoblinGoodsSkuInfoVo itemVo = redisUtils.getGoodsSkuInfoVo(skuIdItem);
                    surplusStock += redisUtils.getSkuAllStatusStock(itemVo);
                    stock += itemVo.getSkuStock();
                }
                item.setSurplusStock(surplusStock);
                item.setStock(stock);
            }
        }
        return ResponseDto.success(vo);
    }

    @Override
    public ResponseDto<Boolean> create(GoblinListCreateParam param) {
        LinkedList<String> sqls = CollectionUtil.linkedListString();
        sqls.add(SqlMapping.get("goblin_list_insert"));
        sqls.add(SqlMapping.get("goblin_list_detail_insert"));
        LinkedList<Object[]> goblinList = CollectionUtil.linkedListObjectArr();
        LinkedList<Object[]> goblinListDetails = CollectionUtil.linkedListObjectArr();
        LocalDateTime now = LocalDateTime.now();

        GoblinListDetailsVo vo = GoblinListDetailsVo.getNew();
        List<GoblinListDetailsItemVo> voItemList = ObjectUtil.goblinListDetailsItemVoArrayList();
        vo.setListId(IDGenerator.nextTimeId2());
        vo.setUid(CurrentUtil.getCurrentUid());
        vo.setName(param.getName());
        vo.setAdvanceMin(param.getAdvanceMin());
        vo.setWhiteType(param.getWhiteType());
        //判断 白名单类型
        if (param.getWhiteType().equals(1)) {//需要xls文件
            if (param.getWhiteUrl() == null || param.getWhiteUrl().equals("")) {
                return ResponseDto.failure("未上传指定用户文件");
            }
            vo.setWhiteUrl(param.getWhiteUrl());
        } else {//不需要xls文件
            vo.setWhiteUrl("");
        }
        vo.setBlackUrl(param.getBlackUrl() == null ? "" : param.getBlackUrl());
        for (GoblinListCreateItemParam item : param.getItemParams()) {
            GoblinListDetailsItemVo itemVo = GoblinListDetailsItemVo.getNew();
            itemVo.setSkuId(item.getSkuId());
            itemVo.setSpuId(item.getSpuId());
            // 白名单
            queueUtils.sendMsgByRedisXls(param.getWhiteUrl(), "", "3", item.getSkuId());
            // 黑名单
            queueUtils.sendMsgByRedisXls(param.getBlackUrl(), "", "4", item.getSkuId());
            goblinListDetails.add(new Object[]{
                    vo.getListId(), itemVo.getSpuId(), itemVo.getSkuId(), now
            });
        }
        vo.setItemVo(voItemList);
        redisUtils.setGoblinListDetailsVo(vo);
        mongoUtils.insertGoblinListDetailsVo(vo);
        goblinList.add(new Object[]{
                vo.getListId(), vo.getUid(), vo.getName(), vo.getWhiteType(), vo.getWhiteUrl(), vo.getAdvanceMin(), vo.getBlackUrl(), now
        });
        queueUtils.sendMsgByRedis(MQConst.GoblinQueue.GOBLIN_STORE_MARKET.getKey(), SqlMapping.gets(sqls, goblinList, goblinListDetails));
        return ResponseDto.success();
    }

    @Override
    public ResponseDto<Boolean> update(GoblinListUpdateParam param) {
        String whiteUrl = "";
        String blackUrl = "";
        LocalDateTime now = LocalDateTime.now();
        GoblinListDetailsVo vo = redisUtils.getGoblinListDetailsVo(param.getListId());
        if (vo == null || !vo.getUid().equals(CurrentUtil.getCurrentUid())) {
            return ResponseDto.failure("信息错误");
        }
        whiteUrl = vo.getWhiteUrl();
        blackUrl = vo.getBlackUrl();
        //判断 白名单类型
        vo.setWhiteType(param.getWhiteType());
        if (param.getWhiteType().equals(1)) {//需要xls文件
            if (param.getWhiteUrl() == null || param.getWhiteUrl().equals("")) {
                return ResponseDto.failure("未上传指定用户文件");
            }
            vo.setWhiteUrl(param.getWhiteUrl());
        } else {//不需要xls文件
            vo.setWhiteUrl("");
        }
        vo.setBlackUrl(param.getBlackUrl() == null ? "" : param.getBlackUrl());
        for (GoblinListDetailsItemVo item : vo.getItemVo()) {
            // 白名单
            queueUtils.sendMsgByRedisXls(param.getWhiteUrl(), whiteUrl, "3", item.getSkuId());
            // 黑名单
            queueUtils.sendMsgByRedisXls(param.getBlackUrl(), blackUrl, "4", item.getSkuId());
        }
        redisUtils.setGoblinListDetailsVo(vo);
        mongoUtils.changeGoblinListDetailsVo(param.getListId(), vo);
        //todo sql入库
        queueUtils.sendMsgByRedis(MQConst.GoblinQueue.GOBLIN_STORE_MARKET.getKey(),
                SqlMapping.get("goblin_list_update", param.getWhiteUrl(), param.getWhiteType(), param.getBlackUrl(), now, param.getListId()));
        return ResponseDto.success();
    }
}
