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

import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.DateUtil;
import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.base.SqlMapping;
import com.liquidnet.service.base.constant.MQConst;
import com.liquidnet.service.goblin.constant.GoblinStatusConst;
import com.liquidnet.service.goblin.dto.manage.GoblinStoreZhengzaiCommonParam;
import com.liquidnet.service.goblin.dto.manage.GoblinStoreZhengzaiItemParam;
import com.liquidnet.service.goblin.dto.vo.*;
import com.liquidnet.service.goblin.entity.GoblinMarketingZhengzai;
import com.liquidnet.service.goblin.service.manage.IGoblinZhengzaiService;
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.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class GoblinZhengzaiServiceImpl implements IGoblinZhengzaiService {

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

    @Override
    public List<GoblinSelfMarketingVo> zhengzaiCanJoin(String storeId) {
        List<String> marketIds = redisUtils.getStoreZhengzaiRelation(storeId);
        List<GoblinSelfMarketingVo> voList = ObjectUtil.getGoblinSelfMarketingVoList();
        for (String selfMarketId : marketIds) {
            GoblinMarketingZhengzaiRelationVo zhengzaiRelationVo = redisUtils.getZhengzaiRelation(selfMarketId, storeId);
            if (DateUtil.compareStrDay(DateUtil.getNowTime(), zhengzaiRelationVo.getShowTime()) == 1) {
                voList.add(redisUtils.getSelfMarket(selfMarketId));
            }
        }
        return voList;
    }

    @Override
    public GoblinSelfMarketingVo zhengzaiCanJoinDetails(String marketId, String storeId) {
        GoblinMarketingZhengzaiRelationVo zhengzaiRelationVo = redisUtils.getZhengzaiRelation(marketId, storeId);
        if (DateUtil.compareStrDay(DateUtil.getNowTime(), zhengzaiRelationVo.getShowTime()) == 1) {
            return redisUtils.getSelfMarket(marketId);
        }
        return null;
    }

    @Override
    public ResponseDto<List<GoblinMarketSpuListVo>> zhengzaiSpuList(String marketId, String storeId, int page) {
        int size = 20;
        List<GoblinStoreMarketIsConfigVo> spuIds = redisUtils.getStoreMarketIsConfig(marketId, storeId);
        List<String> marketSpuList = spuIds.stream().map(GoblinStoreMarketIsConfigVo::getMarketSpuId).collect(Collectors.toList());
        List<GoblinMarketSpuListVo> voList = ObjectUtil.getGoblinMarketSpuListVoArrayList();
        int count = page * size;
        int startCount = (page - 1) * size;
        if (count >= marketSpuList.size()) {
            count = marketSpuList.size();
        }
        for (int i = startCount; i < count; i++) {
            GoblinMarketSpuListVo vo = GoblinMarketSpuListVo.getNew();
            String marketSpuId = marketSpuList.get(i);
            GoblinGoodsInfoVo spuVo = redisUtils.getGoodsInfoVo(marketSpuId);
            vo.setMarketSpuId(marketSpuId.split(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue())[0]);
            vo.setCoverPic(spuVo.getCoverPic());
            vo.setName(spuVo.getName());
            vo.setPriceGe(spuVo.getPriceGe());
            vo.setPriceLe(spuVo.getPriceLe());
            voList.add(vo);
        }
        return ResponseDto.success(voList);
    }

    @Override
    public ResponseDto<List<GoblinSelfZhengzaiSkuVo>> zhengzaiSkuList(String selfMarketId, String storeId, String spuId) {
        GoblinGoodsInfoVo marketSpuVo = redisUtils.getGoodsInfoVo(selfMarketId);
        List<String> marketSkuIdList = marketSpuVo.getSkuIdList();
        List<GoblinSelfZhengzaiSkuVo> voList = ObjectUtil.getGoblinSelfZhengzaiSkuVoArrayList();
        for (String marketSkuId : marketSkuIdList) {
            GoblinGoodsSkuInfoVo marketSkuVo = redisUtils.getGoodsSkuInfoVo(marketSkuId);
            GoblinGoodsSkuInfoVo skuVo = redisUtils.getGoodsSkuInfoVo(marketSkuId.split(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue())[0]);
            GoblinSelfZhengzaiSkuVo vo = GoblinSelfZhengzaiSkuVo.getNew();
            vo.setMarketSkuId(marketSkuId);
            vo.setSkuSpecList(marketSkuVo.getSkuSpecList());
            vo.setPrice(skuVo.getPrice());
            vo.setStock(skuVo.getStock());
            vo.setSkuStock(skuVo.getSkuStock());
            vo.setPriceMarketing(marketSkuVo.getPrice());
            vo.setStockMarketing(marketSkuVo.getSkuStock());
            vo.setBuyFactor(marketSkuVo.getBuyFactor());
            vo.setBuyLimit(marketSkuVo.getBuyLimit());
            vo.setBuyRoster(marketSkuVo.getBuyRoster());
            voList.add(vo);
        }
        return ResponseDto.success(voList);
    }

    @Override
    public ResponseDto<Boolean> zhengzaiSkuInsert(GoblinStoreZhengzaiCommonParam params) {
        LocalDateTime now = LocalDateTime.now();
        String marketSpuId = params.getSpuId().concat(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue()).concat(IDGenerator.marketGoodId(params.getSelfMarketId()));
        GoblinMarketRelationVo relationVo = GoblinMarketRelationVo.getNew();
        relationVo.setSpuId(params.getSpuId());
        List<String> skuList = CollectionUtil.arrayListString();//skuId数组
        List<String> marketSkuList = CollectionUtil.arrayListString();//活动skuId数组
        List<String> errorNameList = CollectionUtil.arrayListString();//修改失败的款式名称数组
        List<BigDecimal> priceList = CollectionUtil.arrayListBigDecimal();//价格集合
        LinkedList<String> sqls = CollectionUtil.linkedListString();
        sqls.add(SqlMapping.get("goblin.self.market.insertRelation"));
        LinkedList<Object[]> sqlsData = CollectionUtil.linkedListObjectArr();
        for (GoblinStoreZhengzaiItemParam item : params.getGoblinStoreZhengzaiItemParams()) {
            String zhengzaiId = IDGenerator.nextMilliId2();
            GoblinMarketingZhengzai bean = GoblinMarketingZhengzai.getNew();
            bean.setStoreId(params.getStoreId());
            bean.setSelfMarketId(params.getSelfMarketId());
            bean.setSpuId(params.getSpuId());
            bean.setZhengzaiId(zhengzaiId);
            bean.setSkuId(item.getSkuId());
            bean.setPriceMarketing(item.getPriceMarketing());
            bean.setStockMarketing(item.getStockMarketing());
            bean.setBuyLimit(item.getBuyLimit());
            bean.setBuyFactor(item.getBuyFactor());
            bean.setBuyRoster(item.getBuyRoster());
            bean.setDelFlag(0);
            bean.setCreatedAt(now);
            //mongo
            GoblinGoodsSkuInfoVo skuVo = redisUtils.getGoodsSkuInfoVo(item.getSkuId());
            //判断库存相关
            int restStock = redisUtils.decrSkuStock(null, item.getSkuId(), item.getStockMarketing());
            if (restStock < 0) {
                errorNameList.add(skuVo.getName());
                redisUtils.incrSkuStock(null, item.getSkuId(), item.getStockMarketing());
                continue;
            }
            redisUtils.setSkuStock(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue(), item.getSkuId(), item.getStockMarketing());
            skuVo.setSpuId(marketSpuId);
            skuVo.setSkuId(item.getSkuId().concat(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue()).concat(IDGenerator.marketGoodId(params.getSelfMarketId())));
            skuVo.setPrice(bean.getPriceMarketing());
            skuVo.setPriceMember(bean.getPriceMarketing());
            skuVo.setSkuStock(bean.getStockMarketing());
            skuVo.setBuyLimit(bean.getBuyLimit());
            skuVo.setBuyRoster(bean.getBuyRoster());
            skuVo.setBuyFactor(bean.getBuyFactor().toString());
            skuVo.setMarketId(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue().concat(params.getSelfMarketId()));
            mongoUtils.setGoodsSkuInfoVo(skuVo);
            //redis
            redisUtils.setGoodsSkuInfoVo(skuVo);
            //mysql
            sqlsData.add(new Object[]{zhengzaiId, bean.getSelfMarketId(), bean.getSpuId(), bean.getSpuId(), bean.getStoreId(), bean.getPriceMarketing(),
                    bean.getStockMarketing(), bean.getBuyFactor(), bean.getBuyRoster(), bean.getBuyLimit(), bean.getDelFlag(), bean.getCreatedAt()});
            marketSkuList.add(skuVo.getSkuId());
            skuList.add(item.getSkuId());
            priceList.add(item.getPriceMarketing());
        }
        if (errorNameList.size() == params.getGoblinStoreZhengzaiItemParams().size()) {
            return ResponseDto.failure(JsonUtils.toJson(errorNameList));
        }
        //mongo
        GoblinGoodsInfoVo spuVo = redisUtils.getGoodsInfoVo(params.getSpuId());
        spuVo.setSpuId(marketSpuId);
        spuVo.setSkuIdList(marketSkuList);
        //排序
        priceList = priceList.stream().sorted().collect(Collectors.toList());
        spuVo.setPriceGe(priceList.get(0));
        spuVo.setPriceLe(priceList.get(priceList.size() - 1));
        spuVo.setMarketId(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue().concat(params.getSelfMarketId()));
        mongoUtils.setGoodsInfoVo(spuVo);
        //redis
        redisUtils.setGoodsInfoVo(spuVo);
        relationVo.setSkuList(skuList);
        redisUtils.addMarketRelation(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue(), params.getSelfMarketId(), relationVo);
        redisUtils.addStoreMarketIsConfig(params.getSelfMarketId(), params.getStoreId(), params.getSpuId(), marketSpuId);
        // 执行sql
        String sqlData = SqlMapping.gets(sqls, sqlsData);
        queueUtils.sendMsgByRedis(MQConst.GoblinQueue.GOBLIN_SELF_MARKET.getKey(),
                sqlData);
        if (errorNameList.size() > 0) {
            return ResponseDto.failure(JsonUtils.toJson(errorNameList));
        }
        return ResponseDto.success();
    }

    @Override
    public ResponseDto<Boolean> zhengzaiSkuUpdate(GoblinStoreZhengzaiCommonParam params) {
        LocalDateTime now = LocalDateTime.now();
        String marketSpuId = params.getSpuId().concat(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue()).concat(IDGenerator.marketGoodId(params.getSelfMarketId()));
        List<String> marketSkuList = CollectionUtil.arrayListString();
        List<BigDecimal> priceList = CollectionUtil.arrayListBigDecimal();//价格集合
        List<String> errorNameList = CollectionUtil.arrayListString();//修改失败的款式名称数组
        LinkedList<String> sqls = CollectionUtil.linkedListString();
        sqls.add(SqlMapping.get("goblin.self.market.updateRelation"));
        LinkedList<Object[]> sqlsData = CollectionUtil.linkedListObjectArr();
        for (GoblinStoreZhengzaiItemParam item : params.getGoblinStoreZhengzaiItemParams()) {
            GoblinMarketingZhengzai bean = GoblinMarketingZhengzai.getNew();
            bean.setPriceMarketing(item.getPriceMarketing());
            bean.setStockMarketing(item.getStockMarketing());
            bean.setBuyLimit(item.getBuyLimit());
            bean.setBuyFactor(item.getBuyFactor());
            bean.setBuyRoster(item.getBuyRoster());
            bean.setDelFlag(0);
            bean.setUpdatedAt(now);
            //mongo
            GoblinGoodsSkuInfoVo skuVo = redisUtils.getGoodsSkuInfoVo(item.getSkuId().concat(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue()).concat(IDGenerator.marketGoodId(params.getSelfMarketId())));
            int changeStock = item.getStockMarketing() - skuVo.getSkuStock();
            //判断库存相关
            int restStock;
            if (changeStock > 0) {
                restStock = redisUtils.incrSkuStock(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue(), item.getSkuId(), changeStock);
                redisUtils.decrSkuStock(null, item.getSkuId(), changeStock);
            } else {
                restStock = redisUtils.decrSkuStock(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue(), item.getSkuId(), -changeStock);
                redisUtils.incrSkuStock(null, item.getSkuId(), -changeStock);
            }
            if (restStock < 0) {
                errorNameList.add(skuVo.getName());
                redisUtils.incrSkuStock(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue(), item.getSkuId(), -changeStock);
                redisUtils.decrSkuStock(null, item.getSkuId(), -changeStock);
                continue;
            }
            skuVo.setPrice(bean.getPriceMarketing());
            skuVo.setPriceMember(bean.getPriceMarketing());
            skuVo.setSkuStock(bean.getStockMarketing());
            skuVo.setBuyLimit(bean.getBuyLimit());
            skuVo.setBuyRoster(bean.getBuyRoster());
            skuVo.setBuyFactor(bean.getBuyFactor().toString());
            skuVo.setMarketId(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue().concat(params.getSelfMarketId()));
            mongoUtils.updateGoodsSkuInfoVo(skuVo);
            //redis
            redisUtils.setGoodsSkuInfoVo(skuVo);
            //mysql
            sqlsData.add(new Object[]{bean.getPriceMarketing(),
                    bean.getStockMarketing(), bean.getBuyFactor(), bean.getBuyRoster(), bean.getBuyLimit(), bean.getUpdatedAt(), params.getSelfMarketId(), params.getStoreId()});
            marketSkuList.add(skuVo.getSkuId());
            priceList.add(bean.getPriceMarketing());
        }
        if (errorNameList.size() == params.getGoblinStoreZhengzaiItemParams().size()) {
            return ResponseDto.failure(JsonUtils.toJson(errorNameList));
        }
        //mongo
        GoblinGoodsInfoVo spuVo = redisUtils.getGoodsInfoVo(params.getSpuId());
        spuVo.setSpuId(marketSpuId);
        //排序
        priceList = priceList.stream().sorted().collect(Collectors.toList());
        spuVo.setPriceGe(priceList.get(0));
        spuVo.setPriceLe(priceList.get(priceList.size() - 1));
        spuVo.setSkuIdList(marketSkuList);
        spuVo.setMarketId(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue().concat(params.getSelfMarketId()));
        mongoUtils.updateGoodsInfoVo(spuVo);
        //redis
        redisUtils.setGoodsInfoVo(spuVo);
        // 执行sql
        String sqlData = SqlMapping.gets(sqls, sqlsData);
        queueUtils.sendMsgByRedis(MQConst.GoblinQueue.GOBLIN_SELF_MARKET.getKey(),
                sqlData);
        if (errorNameList.size() > 0) {
            return ResponseDto.failure(JsonUtils.toJson(errorNameList));
        }
        return ResponseDto.success();
    }

    @Override
    public ResponseDto<Boolean> zhengzaiSpuDel(String marketId, String storeId, String spuId) {
        //todo 判断 如果有订单待支付 则不能关闭
        LocalDateTime now = LocalDateTime.now();
        String marketSpuId = spuId.concat(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue()).concat(IDGenerator.marketGoodId(marketId));
        GoblinMarketingZhengzai bean = GoblinMarketingZhengzai.getNew();
        bean.setUpdatedAt(now);
        bean.setDelFlag(1);
        //mongo
        mongoUtils.delGoodsInfoVo(marketSpuId);
        //redis
        redisUtils.delGoodsInfoVo(marketSpuId);
        redisUtils.removeMarketRelation(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue(), marketId, spuId);
        redisUtils.delStoreMarketIsConfig(marketId, storeId, spuId, marketSpuId);
        //库存处理
        GoblinGoodsInfoVo marketVo = redisUtils.getGoodsInfoVo(marketSpuId);
        for (String marketSkuId : marketVo.getSkuIdList()) {
            String skuId = marketSkuId.split(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue())[0];
            //库存回滚
            int restStock = redisUtils.getSkuStock(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue(), marketSkuId);
            int restStockDe = redisUtils.decrSkuStock(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue(), marketSkuId, restStock);
            redisUtils.incrSkuStock(null, skuId, restStock + restStockDe);
        }
        //mysql
        queueUtils.sendMsgByRedis(MQConst.GoblinQueue.GOBLIN_SELF_MARKET.getKey(),
                SqlMapping.get("goblin.self.market.delSpuRelation", bean.getDelFlag(), bean.getUpdatedAt(), marketId, storeId, spuId));
        return ResponseDto.success();
    }
}
