package com.liquidnet.service.order.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.goblin.constant.NftAccStatusEnum;
import com.liquidnet.service.goblin.dto.GoblinUserNftAccInfoVo;
import com.liquidnet.service.goblin.dto.manage.MixOrderParam;
import com.liquidnet.service.goblin.dto.vo.*;
import com.liquidnet.service.goblin.param.SyncOrderParam;
import com.liquidnet.service.goblin.service.IMixOrderService;
import com.liquidnet.service.order.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.tomcat.jni.Local;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

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

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


@Service
@Slf4j
public class MixOrderServiceImpl implements IMixOrderService {

    @Autowired
    GoblinRedisUtils redisUtils;
    @Autowired
    GoblinMongoUtils mongoUtils;
    @Autowired
    GoblinOrderUtils orderUtils;
    @Autowired
    GoblinNftOrderUtils nftOrderUtils;
    @Autowired
    QueueUtils queueUtils;

    @Value("${liquidnet.service.order.url}")
    private String orderUrl;

    @Override
    public ResponseDto<GoblinPayInnerResultVo> checkOrder(MixOrderParam param, String uid) {
        GoblinMixDetailsVo mixVo = redisUtils.getMixDetails(param.getMixId());
        String mixId = mixVo.getMixId();
        String mobile = StringUtils.defaultString(((String) CurrentUtil.getTokenClaims().get(CurrentUtil.TOKEN_MOBILE)), "");
        List<String> canBuyIds = CollectionUtil.linkedListString();//有库存的id
        String boxSkuId = "";//盲盒种的skuid
        String stockSkuId = "";  // 盲盒id
        //判断 活动状态
        LocalDateTime st = LocalDateTime.parse(mixVo.getTimeStart(), DTF_YMD_HMS);
        LocalDateTime et = LocalDateTime.parse(mixVo.getTimeEnd(), DTF_YMD_HMS);
        LocalDateTime nt = LocalDateTime.now();
        if (!nt.isAfter(st) && nt.isBefore(et)) {
            return ResponseDto.failure("不在活动有效期内");
        }
        //判断白名单
        int whiteType = mixVo.getWhiteType();
        Boolean canBuy = redisUtils.getListCanBuy(mixId, mixId, mobile, uid, whiteType == 2 ? -1 : whiteType);
        if (!canBuy) {
            return ResponseDto.failure("该藏品仅对部分用户开放～");
        }
        //判断限购
        Integer limitCount = mixVo.getLimit();
        int buyCount = redisUtils.incrMixLimit(mixId, uid);
        if (buyCount > limitCount) {
            return ResponseDto.failure("超出限购数量");
        }
        //构建 各个商品信息
        List<GoblinGoodsSkuInfoVo> skuInfoList = ObjectUtil.cloneArrayGoblinGoodsSkuInfoListVo();
        List<GoblinGoodsSkuInfoVo> nftInfoList = ObjectUtil.cloneArrayGoblinGoodsSkuInfoListVo();
        for (GoblinMixDetailsItemVo itemVo : mixVo.getItem()) {
            String skuId = itemVo.getSkuId();
            GoblinGoodsSkuInfoVo skuInfoVo = redisUtils.getGoodsSkuInfoVo(skuId);
            //库存处理
            if (skuInfoVo.getUnbox().equals("1")) {//盲盒
                GoblinGoodsInfoVo spuInfoVo = redisUtils.getGoodsInfoVo(skuInfoVo.getSpuId());
                List<String> skuIdList = spuInfoVo.getSkuIdList();
                if (CollectionUtil.isEmpty(skuIdList)) {
                    return ResponseDto.failure("该商品SPU不存在～");
                } else {
                    GoblinGoodsSkuInfoVo boxSkuInfo = nftOrderUtils.lotteryDraw(skuIdList, itemVo.getCount(), nt, null);
                    if (null == boxSkuInfo) {
                        return ResponseDto.failure("盲盒库存不足啦～");
                    } else {
                        canBuyIds.add(boxSkuInfo.getSkuId() + "," + itemVo.getCount());
                    }
                    boxSkuId = skuInfoVo.getSkuId();
                    stockSkuId = boxSkuId;
                }
            } else {//正常
                if (skuInfoVo.getSkuType() == 1) {
                    stockSkuId = skuId;
                }
                int stock = redisUtils.decrSkuStock(mixId, skuId, itemVo.getCount());
                if (stock < 0) {
                    redisUtils.incrSkuStock(mixId, skuId, itemVo.getCount());
                    for (String canBuyId : canBuyIds) {
                        String[] data = canBuyId.split(",");
                        String skuIdSingle = data[0];
                        int count = Integer.parseInt(data[1]);
                        redisUtils.incrSkuStock(mixId, skuIdSingle, count);
                    }
                    return ResponseDto.failure("库存不足");
                } else {
                    canBuyIds.add(skuId + "," + itemVo.getCount());
                }
            }
            if (skuInfoVo.getSkuType() == 0) {
                skuInfoList.add(skuInfoVo);
            } else if (skuInfoVo.getSkuType() == 1) {
                nftInfoList.add(skuInfoVo);
            } else {
                return ResponseDto.failure("参数异常");
            }
        }
        // 认证验证
        if (nftInfoList.size() > 0) {
            GoblinUserNftAccInfoVo openAccountInfo = redisUtils.getOpenAccountInfo(uid);
            if (null == openAccountInfo || !NftAccStatusEnum.StatusAcc.SUCCESS.getCode().equals(openAccountInfo.getCode())) {
                return ResponseDto.failure("您还未开通数字账户");
            }
        }


        return null;
    }

    @Override
    public String syncOrder(SyncOrderParam syncOrderParam) {
        return null;
    }

    @Override
    public ResponseDto<Integer> checkOrderResult(String orderId) {
        return null;
    }

    @Override
    public ResponseDto<Integer> checkOrderResultMaterCode(String materCode) {
        return null;
    }
}
