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

import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.CurrentUtil;
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.vo.*;
import com.liquidnet.service.goblin.service.IGoblinAppZhengzaiService;
import com.liquidnet.service.goblin.util.*;
import org.springframework.beans.BeanUtils;
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;

import static com.liquidnet.commons.lang.util.DateUtil.DTF_YMD_HMS;

@Service
public class GoblinAppZhengzaiServiceImpl implements IGoblinAppZhengzaiService {

    @Autowired
    GoblinRedisUtils redisUtils;
    @Autowired
    GoblinOrderUtils goblinOrderUtils;
    @Autowired
    GoblinMongoUtils mongoUtils;
    @Autowired
    QueueUtils queueUtils;
    @Autowired
    GoblinOrderUtils orderUtils;


    @Override
    public List<GoblinSelfMarketingVo> getZhengzaiMarketList() {
        List<GoblinSelfMarketingVo> list = redisUtils.getGoblinSelfMarketingVoList();
        List<GoblinSelfMarketingVo> voList = ObjectUtil.getGoblinSelfMarketingVoList();
        LocalDateTime now = LocalDateTime.now();
        for (GoblinSelfMarketingVo item : list) {
            if (LocalDateTime.parse(item.getStartTime(), DTF_YMD_HMS).isBefore(now) && LocalDateTime.parse(item.getEndTime(), DTF_YMD_HMS).isAfter(now) && (item.getStatus() == null || item.getStatus() != 7)) {
                voList.add(item);
            }
        }
        return voList;
    }

    @Override
    public List<GoblinShowStoreInfoVo> getStoreList(String marketId) {
        List<GoblinMarketRelationVo> relationVo = redisUtils.getMarketRelation(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue(), marketId);
        List<String> storeIdList = relationVo.stream().map(GoblinMarketRelationVo::getStoreId).distinct().collect(Collectors.toList());
        List<GoblinShowStoreInfoVo> voList = ObjectUtil.getGoblinShowStoreInfoVoArrayList();
        for (String storeId : storeIdList) {
            if (storeId == null) {
                continue;
            }
            GoblinStoreInfoVo vo = redisUtils.getStoreInfoVo(storeId);
            if (vo.getStatus().equals("5") || vo.getStatus().equals("3")) {
                GoblinShowStoreInfoVo returnVo = GoblinShowStoreInfoVo.getNew();
                BeanUtils.copyProperties(vo, returnVo);
                voList.add(returnVo);
            }
        }
        return voList;
    }

    @Override
    public List<GoblinZhengzaiGoodVo> getSpuList(String marketId, String storeId) {
        List<GoblinMarketRelationVo> relationVo = redisUtils.getMarketRelation(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue(), marketId);
        List<String> spuIdList = relationVo.stream().map(GoblinMarketRelationVo::getSpuId).collect(Collectors.toList());
        List<GoblinZhengzaiGoodVo> voList = ObjectUtil.getGoblinZhengzaiGoodVoArrayList();
        for (String spuId : spuIdList) {
            GoblinGoodsInfoVo vo = redisUtils.getGoodsInfoVo(spuId);
            if (vo.getShelvesStatus().equals("3") && storeId.equals(vo.getStoreId())) {
                GoblinZhengzaiGoodVo returnVo = GoblinZhengzaiGoodVo.getNew();
                BeanUtils.copyProperties(vo, returnVo);
                voList.add(returnVo);
            }
        }
        return voList;
    }

    @Override
    public ResponseDto<Boolean> orderPush(String offCode, String marketId) {
        String[] orderIds = redisUtils.getOffCode(offCode);
        LocalDateTime now = LocalDateTime.now();
        LinkedList<String> sqls = CollectionUtil.linkedListString();
        LinkedList<Object[]> sqlDataOrder = CollectionUtil.linkedListObjectArr();
        LinkedList<Object[]> sqlDataSku = CollectionUtil.linkedListObjectArr();
        sqls.add(SqlMapping.get("goblin_order.store.orderStatus"));
        sqls.add(SqlMapping.get("goblin_order.store.orderSkuStatus"));
        String uid = CurrentUtil.getCurrentUid();
        GoblinStoreInfoVo storeInfoVo = redisUtils.getStoreInfoVoByUid(uid);
        if (storeInfoVo == null) {
            return ResponseDto.failure("参数错误");
        }
        if (orderIds == null) {
            return ResponseDto.failure("订单不存在");
        } else {
            for (String orderId : orderIds) {
                GoblinStoreOrderVo storeOrderVo = redisUtils.getGoblinOrder(orderId);
                if (!storeInfoVo.getStoreId().equals(storeOrderVo.getStoreId())|| !(storeOrderVo.getWriteOffCode().equals(offCode))) {
                    continue;
                }
                if (storeOrderVo.getStatus().equals(GoblinStatusConst.Status.ORDER_STATUS_0.getValue())) {
                    return ResponseDto.failure("出货失败，订单未支付");
                }
                if (storeOrderVo.getStatus().equals(GoblinStatusConst.Status.ORDER_STATUS_4.getValue())) {
                    return ResponseDto.failure("出货失败，订单已核销");
                }
                if (!storeOrderVo.getMarketId().equals(marketId)) {
                    return ResponseDto.failure("出货失败，活动不符");
                }
                storeOrderVo.setStatus(GoblinStatusConst.Status.ORDER_STATUS_4.getValue());
                storeOrderVo.setZhengzaiStatus(1);
                sqlDataOrder.add(new Object[]{
                        storeOrderVo.getStatus(),storeOrderVo.getZhengzaiStatus(), now,
                        storeOrderVo.getOrderId(), now, now
                });
                List<String> skuIds = storeOrderVo.getOrderSkuVoIds();
                for (String skuId : skuIds) {
                    GoblinOrderSkuVo skuInfoVo = redisUtils.getGoblinOrderSkuVo(skuId);
                    skuInfoVo.setStatus(GoblinStatusConst.Status.ORDER_STATUS_4.getValue());
                    sqlDataSku.add(new Object[]{
                            skuInfoVo.getStatus(), now,
                            skuInfoVo.getOrderSkuId(), now, now
                    });
                    redisUtils.setGoblinOrderSku(skuInfoVo.getOrderSkuId(), skuInfoVo);
                    mongoUtils.updateGoblinOrderSkuVo(skuInfoVo.getOrderSkuId(), skuInfoVo);
                }
                redisUtils.setGoblinOrder(storeOrderVo.getOrderId(), storeOrderVo);
                mongoUtils.updateGoblinStoreOrderVo(storeOrderVo.getOrderId(), storeOrderVo);
            }
            queueUtils.sendMsgByRedis(MQConst.GoblinQueue.GOBLIN_STORE_ORDER_OPERA.getKey(),
                    SqlMapping.gets(sqls, sqlDataOrder, sqlDataSku));
        }
        return ResponseDto.success(true);
    }

    @Override
    public ResponseDto<List<GoblinZhengzaiPushVo>> orderPushDetails(String offCode, String marketId) {
        String[] orderIds = redisUtils.getOffCode(offCode);
        List<GoblinZhengzaiPushVo> listVo = ObjectUtil.getGoblinZhengzaiPushVoArrayList();
        String uid = CurrentUtil.getCurrentUid();
        GoblinStoreInfoVo storeInfoVo = redisUtils.getStoreInfoVoByUid(uid);
        if (storeInfoVo == null) {
            return ResponseDto.failure("参数错误");
        }
        if (orderIds == null) {
            return ResponseDto.failure("订单不存在");
        } else {
            for (String orderId : orderIds) {
                GoblinStoreOrderVo storeOrderVo = redisUtils.getGoblinOrder(orderId);
                if (!storeInfoVo.getStoreId().equals(storeOrderVo.getStoreId()) || !(storeOrderVo.getWriteOffCode().equals(offCode))) {
                    continue;
                }
                if (storeOrderVo.getStatus().equals(GoblinStatusConst.Status.ORDER_STATUS_0.getValue())) {
                    return ResponseDto.failure("订单未支付");
                }
//                if (storeOrderVo.getStatus().equals(GoblinStatusConst.Status.ORDER_STATUS_4.getValue())) {
//                    return ResponseDto.failure("出货失败，订单已核销");
//                }
                if (!storeOrderVo.getMarketId().equals(marketId)) {
                    return ResponseDto.failure("活动不符");
                }
                List<String> skuIds = storeOrderVo.getOrderSkuVoIds();
                for (String skuId : skuIds) {
                    GoblinZhengzaiPushVo vo = GoblinZhengzaiPushVo.getNew();
                    GoblinOrderSkuVo skuInfoVo = redisUtils.getGoblinOrderSkuVo(skuId);
                    vo.setSkuName(skuInfoVo.getSkuName());
                    vo.setNum(skuInfoVo.getNum());
                    vo.setSkuSpecs(skuInfoVo.getSkuSpecs());
                    vo.setSpuName(skuInfoVo.getSpuName());
                    vo.setStatus(skuInfoVo.getStatus());
                    listVo.add(vo);
                }
            }
        }
        return ResponseDto.success(listVo);
    }

    @Override
    public ResponseDto<Boolean> orderBind(String uid, String masterCode) {
        String[] orderIds = redisUtils.getMasterCode(masterCode);
        LocalDateTime now = LocalDateTime.now();
        BigDecimal priceActual = BigDecimal.ZERO;
        if (orderIds == null) {
            return ResponseDto.failure("订单不存在");
        } else {
            for (String orderId : orderIds) {
                GoblinStoreOrderVo storeOrderVo = redisUtils.getGoblinOrder(orderId);
                if (storeOrderVo.getUserId().equals(uid)) {
                    continue;
                }
                storeOrderVo.setUserId(uid);
                priceActual = priceActual.add(storeOrderVo.getPriceActual());
                //mongo
                mongoUtils.updateGoblinStoreOrderVo(storeOrderVo.getOrderId(), storeOrderVo);
                //redis
                redisUtils.setGoblinOrder(storeOrderVo.getOrderId(), storeOrderVo);
                redisUtils.addZhengzaiOrderList(uid,orderId);
                //mysql
                queueUtils.sendMsgByRedis(MQConst.GoblinQueue.GOBLIN_STORE_ORDER_OPERA.getKey(),
                        SqlMapping.get("goblin_order.zhengzai.bind",
                                uid, now, storeOrderVo.getOrderId(), now, now));
            }
            if (priceActual.compareTo(BigDecimal.ZERO) != 0) {
                goblinOrderUtils.integral(uid, priceActual, "购买商品", 1);
            }
        }
        return ResponseDto.success();
    }
}
