package com.liquidnet.service.galaxy.router.xuper.biz;

import com.liquidnet.common.exception.constant.ErrorCode;
import com.liquidnet.common.third.xuper.config.XuperConfig;
import com.liquidnet.common.third.xuper.dto.*;
import com.liquidnet.common.third.xuper.exception.XupterException;
import com.liquidnet.common.third.xuper.util.XuperSdkUtil;
import com.liquidnet.common.third.zxlnft.dto.Nft044BuyResultReqDto;
import com.liquidnet.commons.lang.util.BeanUtil;
import com.liquidnet.commons.lang.util.DateUtil;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.commons.lang.util.StringUtil;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.galaxy.biz.GalaxyBeanTransferBiz;
import com.liquidnet.service.galaxy.biz.GalaxyEnumBiz;
import com.liquidnet.service.galaxy.constant.GalaxyEnum;
import com.liquidnet.service.galaxy.constant.GalaxyErrorEnum;
import com.liquidnet.service.galaxy.dto.bo.GalaxyNftOrderBindBo;
import com.liquidnet.service.galaxy.dto.bo.GalaxyNftOrderBo;
import com.liquidnet.service.galaxy.dto.bo.GalaxySeriesNftInfoBo;
import com.liquidnet.service.galaxy.dto.bo.GalaxyUserInfoBo;
import com.liquidnet.service.galaxy.dto.param.*;
import com.liquidnet.service.galaxy.dto.vo.mongo.GalaxyNftOrderFailLogVo;
import com.liquidnet.service.galaxy.exception.GalaxyNftBuyException;
import com.liquidnet.service.galaxy.exception.GalaxyNftPublishException;
import com.liquidnet.service.galaxy.utils.GalaxyDataUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Date;

/**
 * @author AnJiabin <anjiabin@zhengzai.tv>
 * @version V1.0
 * @Description: TODO
 * @class: ZxinTradeBiz
 * @Package com.liquidnet.service.galaxy.router.zxin.biz
 * @Copyright: LightNet @ Copyright (c) 2021
 * @date 2022/6/27 13:08
 */
@Slf4j
@Component
public class XuperTradeCommonBiz {
    @Autowired
    private XuperSdkUtil xuperSdkUtil;

    @Autowired
    private XuperConfig xuperConfig;

    @Autowired
    private GalaxyDataUtils dataUtils;

    @Autowired
    private GalaxyBeanTransferBiz galaxyBeanTransferBiz;

    /**
     * 发行和购买
     * @param reqDto
     * @return
     */
    public ResponseDto<GalaxyNftPublishAndBuyRespDto> nftPublishAndBuy(GalaxyNftPublishAndBuyReqDto reqDto) {
        log.info("开始执行nftPublishAndBuy 请求参数:{}",reqDto.toString());
        //获取用户信息
        GalaxyUserInfoBo userInfoBo = dataUtils.getGalaxyUserInfo(reqDto.getRouterType(),reqDto.getUserId());
        if(StringUtil.isNull(userInfoBo)){
            log.error("开始执行nftPublishAndBuy error msg:{}",GalaxyErrorEnum.NFT_BUY_FAIL_USER_NOT_EXIST.getMessage());
            return ResponseDto.failure(GalaxyErrorEnum.NFT_BUY_FAIL_USER_NOT_EXIST.getCode(), GalaxyErrorEnum.NFT_BUY_FAIL_USER_NOT_EXIST.getMessage());
        }

        //获取sku信息
        GalaxySeriesNftInfoBo seriesNftInfoBo = dataUtils.getSeriesNftInfoBo(reqDto.getRouterType(),reqDto.getSkuId());
        if(StringUtil.isNull(seriesNftInfoBo)||StringUtil.isEmpty(seriesNftInfoBo.getSeriesId())){
            log.error("开始执行nftPublishAndBuy error msg:{}",GalaxyErrorEnum.SERIES_NFT_INFO_NOT_EXIST.getMessage());
            return ResponseDto.failure(GalaxyErrorEnum.SERIES_NFT_INFO_NOT_EXIST.getCode(), GalaxyErrorEnum.SERIES_NFT_INFO_NOT_EXIST.getMessage());
        }

        //获取订单信息
        GalaxyNftOrderBo nftOrderBo = dataUtils.getNftOrderBo(reqDto.getRouterType(),reqDto.getNftOrderPayId());
        //初始化订单数据
        if(nftOrderBo==null){
            nftOrderBo = galaxyBeanTransferBiz.buildNftOrderBo(reqDto.getNftOrderPayId(),userInfoBo,seriesNftInfoBo);
            nftOrderBo.setNftPublishTaskId(seriesNftInfoBo.getSeriesId());
            nftOrderBo.setNftPublishFromAddress(xuperConfig.getNftPlatformAddress());
            nftOrderBo.setNftBuyFromAddress(xuperConfig.getNftPlatformAddress());
            dataUtils.setNftOrderBo(reqDto.getRouterType(),reqDto.getNftOrderPayId(),nftOrderBo);
        }else if(StringUtil.isNotNull(nftOrderBo)){
            if(nftOrderBo.getNftPublishStatus().equalsIgnoreCase(GalaxyEnum.TaskStatusEnum.TASK_SUCCESS.getCode())
                    &&nftOrderBo.getNftBuyStatus().equalsIgnoreCase(GalaxyEnum.TaskStatusEnum.TASK_SUCCESS.getCode())){
                GalaxyNftPublishAndBuyRespDto nftPublishAndBuyRespDto = GalaxyNftPublishAndBuyRespDto.getNew();
                nftPublishAndBuyRespDto.setUserId(reqDto.getUserId());
                nftPublishAndBuyRespDto.setNftId(nftOrderBo.getNftId());
                log.error("开始执行nftPublishAndBuy error msg:{}", GalaxyErrorEnum.PUBLISH_FAIL_ALREADY_EXIST.toString());
                return ResponseDto.success(nftPublishAndBuyRespDto);
            }
            if(nftOrderBo.getNftPublishStatus().equalsIgnoreCase(GalaxyEnum.TaskStatusEnum.TASK_SUCCESS.getCode())
                    &&(nftOrderBo.getNftBuyStatus().equalsIgnoreCase(GalaxyEnum.TaskStatusEnum.INIT.getCode())
                    ||nftOrderBo.getNftBuyStatus().equalsIgnoreCase(GalaxyEnum.TaskStatusEnum.PROCESSING.getCode()))){
                //再次发起购买
                GalaxyNftPublishAndBuyRespDto nftPublishAndBuyRespDto = this.executeBuyBusiness(reqDto,userInfoBo,seriesNftInfoBo,nftOrderBo);
                if(StringUtil.isNotNull(nftPublishAndBuyRespDto)&&StringUtil.isNotEmpty(nftPublishAndBuyRespDto.getNftId())){
                    return ResponseDto.success(nftPublishAndBuyRespDto);
                }else{
                    log.error("开始执行nftPublishAndBuy-->executeBuyBusiness error msg:{}",GalaxyErrorEnum.NFT_BUY_FAIL.getMessage());
                    return ResponseDto.failure(GalaxyErrorEnum.NFT_BUY_FAIL.getCode(),GalaxyErrorEnum.NFT_BUY_FAIL.getMessage());
                }
            }
        }

        //开始索引
        Integer seriesBeginIndex = null;
        /**
         * 根据sku获取系列Id
         */
        String seriesId = seriesNftInfoBo.getSeriesId();
        //返回参数nftId
        String nftId = null;
        String publishTaskId = null;
        Long nftPublishChainTimestamp = null;
        Integer nftPublishStatus = null;
        String nftPublishTradeHash = null;

        //定义失败信息
        String failDesc = null;
        //是否发行成功
        boolean isPublishSuccess = false;

        try{
            /**
             * 获取订单和nft绑定信息
             */
            GalaxyNftOrderBindBo nftOrderBindBo = dataUtils.getGalaxyNftOrderBindBo(reqDto.getRouterType(),reqDto.getNftOrderPayId());
            if(StringUtil.isNull(nftOrderBindBo)){
                //获取发行索引
                long nftIdNo = dataUtils.incrNftIdNo(reqDto.getRouterType(),reqDto.getSkuId());
                //如果发行数大于最大发行数量
                if(nftIdNo > seriesNftInfoBo.getNftTotalCount()){
                    //发行失败
                    throw new GalaxyNftPublishException(GalaxyErrorEnum.NFT_PUBLISH_ERROR.getCode(),"该sku："+reqDto.getSkuId()+" 总共"+seriesNftInfoBo.getNftTotalCount()+"个NFT已经发行完毕，没有剩余库存！");
                }
                nftOrderBindBo = GalaxyNftOrderBindBo.getNew();
                nftOrderBindBo.setNftOrderPayId(reqDto.getNftOrderPayId());
                nftOrderBindBo.setSeriesId(seriesNftInfoBo.getSeriesId());
                nftOrderBindBo.setSeriesCode(seriesNftInfoBo.getSeriesCode());
                nftOrderBindBo.setNftIdIndex(Integer.valueOf(String.valueOf(nftIdNo)));
                nftOrderBindBo.setRouterType(reqDto.getRouterType());
                String nowTimeStr = DateUtil.Formatter.yyyyMMddHHmmss.format(LocalDateTime.now());
                nftOrderBindBo.setCreatedAt(nowTimeStr);
                dataUtils.setGalaxyNftOrderBindBo(reqDto.getRouterType(),reqDto.getNftOrderPayId(),nftOrderBindBo);
            }
            seriesBeginIndex = nftOrderBindBo.getNftIdIndex();

            //设置nftId
            nftId = seriesId.concat("_").concat(seriesBeginIndex.toString());
            //设置购买标志
            nftOrderBo.setNftId(nftId);

            /**
             * 如果已经发行成功
             */
            if(seriesNftInfoBo.getNftPublishStatus().equalsIgnoreCase(GalaxyEnum.AssetPublishStatusEnum.SUCCESS.getCode())){
                publishTaskId = seriesNftInfoBo.getSeriesId();//跳过发行查询
                nftPublishChainTimestamp = DateUtil.getNowSeconds();
                nftPublishStatus = Integer.parseInt(GalaxyEnum.AssetPublishStatusEnum.SUCCESS.getCode());
                nftPublishTradeHash = seriesNftInfoBo.getNftPublishTradeHash();
                //发行成功
                isPublishSuccess = true;
            }else if(seriesNftInfoBo.getNftPublishStatus().equalsIgnoreCase(GalaxyEnum.AssetPublishStatusEnum.PROCESSING.getCode())){
                if(StringUtil.isNotEmpty(nftOrderBo.getNftPublishTaskId())){
                    publishTaskId = nftOrderBo.getNftPublishTaskId();
                }
            }else if(seriesNftInfoBo.getNftPublishStatus().equalsIgnoreCase(GalaxyEnum.AssetPublishStatusEnum.INIT.getCode())){
                //发行
                Xuper004PublishAssetReqDto xuper004PublishAssetReqDto = Xuper004PublishAssetReqDto.getNew();
                // 定义返回结果对象
                Xuper004PublishAssetRespDto xuper004PublishAssetRespDto = null;
                long assetId = Long.parseLong(seriesNftInfoBo.getSeriesId());
                try {
                    xuper004PublishAssetReqDto.setMnemonic(xuperConfig.getNftPlatformMnemonic());
                    xuper004PublishAssetReqDto.setAssetId(assetId);
                    XuperResponseDto<Xuper004PublishAssetRespDto> xuperResponseDto = xuperSdkUtil.xuper004PublishAsset(xuper004PublishAssetReqDto);
                    if(xuperResponseDto.isSuccess()){
                        xuper004PublishAssetRespDto = xuperResponseDto.getParseData(Xuper004PublishAssetRespDto.class);
                    }
                }catch (XupterException e) {
                    log.error("biz error msg "+e.getMessage(),e);
                }catch (Exception e) {
                    log.error("sys error msg "+e.getMessage(),e);
                }
                log.info("xuper004PublishAsset resp : "+ JsonUtils.toJson(xuper004PublishAssetRespDto));

                if (Integer.parseInt(ErrorCode.SUCCESS.getCode()) == xuper004PublishAssetRespDto.errNo){
                    publishTaskId = String.valueOf(assetId);
                    nftOrderBo.setNftPublishTaskId(publishTaskId);
                }
            }

            //发行结果查询
            if (!isPublishSuccess){
                try{
                    int count = 0;
                    long timeStart = System.currentTimeMillis();
                    while (!isPublishSuccess) {
                        Thread.sleep(500l);
                        count++;
                        log.info("=======执行nft发行第{}次查询,taskId:{}", count, publishTaskId);
                        //执行nft发行结果查询
                        GalaxyNftPublishResultQueryReqDto nftPublishResultQueryReqDto = GalaxyNftPublishResultQueryReqDto.getNew();
                        nftPublishResultQueryReqDto.setNftOrderPayId(reqDto.getNftOrderPayId());
                        nftPublishResultQueryReqDto.setRouterType(reqDto.getRouterType());
                        ResponseDto<GalaxyNftPublishResultQueryRespDto> publishResultQueryRespDto = this.nftPublishResultQuery(nftPublishResultQueryReqDto);
                        if(publishResultQueryRespDto.isSuccess()){
                            GalaxyNftPublishResultQueryRespDto nftPublishResultQueryRespDto = publishResultQueryRespDto.getData();
                            if (nftPublishResultQueryRespDto.getTaskStatus().toString().equals(GalaxyEnum.AssetPublishStatusEnum.SUCCESS.getCode())) {
                                nftPublishChainTimestamp = DateUtil.getNowSeconds();
                                nftPublishStatus = Integer.parseInt(GalaxyEnum.AssetPublishStatusEnum.SUCCESS.getCode());
                                nftPublishTradeHash = nftPublishResultQueryRespDto.getTxHash();

                                //首次查询nft发行状态,如果成功更新nft系列发行状态
                                seriesNftInfoBo.setNftPublishStatus(GalaxyEnum.AssetPublishStatusEnum.SUCCESS.getCode());
                                seriesNftInfoBo.setNftPublishTradeHash(nftPublishTradeHash);
                                seriesNftInfoBo.setUpdatedAt(LocalDateTime.now());
                                dataUtils.updateSeriesNftPublishStatus(reqDto.getRouterType(),reqDto.getSkuId(),seriesNftInfoBo);

                                isPublishSuccess = true;
                            } else if (nftPublishResultQueryRespDto.getTaskStatus().toString().equals(GalaxyEnum.AssetPublishStatusEnum.FAIL.getCode())) {
                                log.info("任务执行失败！taskId:{}", publishTaskId);
                                nftPublishStatus = nftPublishResultQueryRespDto.getTaskStatus();
                                //发行失败
                                seriesNftInfoBo.setNftPublishStatus(GalaxyEnum.AssetPublishStatusEnum.FAIL.getCode());
                                seriesNftInfoBo.setUpdatedAt(LocalDateTime.now());
                                dataUtils.updateSeriesNftPublishStatus(reqDto.getRouterType(),reqDto.getSkuId(),seriesNftInfoBo);
                                //直接进行异常处理
                                throw new GalaxyNftPublishException(GalaxyErrorEnum.PUBLISH_FAIL.getCode(), "xuper004PublishAsset_resp:"+GalaxyErrorEnum.PUBLISH_FAIL.getMessage());
                            }else if(nftPublishResultQueryRespDto.getTaskStatus().toString().equals(GalaxyEnum.AssetPublishStatusEnum.PROCESSING.getCode())){
                                log.info("任务执行中！taskId:{}", publishTaskId);
                                nftPublishStatus = nftPublishResultQueryRespDto.getTaskStatus();

                                //发行中
                                seriesNftInfoBo.setNftPublishStatus(GalaxyEnum.AssetPublishStatusEnum.PROCESSING.getCode());
                                seriesNftInfoBo.setUpdatedAt(LocalDateTime.now());
                                dataUtils.updateSeriesNftPublishStatus(reqDto.getRouterType(),reqDto.getSkuId(),seriesNftInfoBo);
                            }
                        }

                        if (count == 20) {
                            log.info("=======查询共20次，跳出循环！taskId:{}",publishTaskId);
                            break;
                        }
                    }
                    log.info("发行NFT后返回给前端nftID:{}", nftId);
                    log.info("总共执行了{}次查询 总耗时:{} MS", count, (System.currentTimeMillis() - timeStart));
                }catch (GalaxyNftPublishException e){
                    throw new GalaxyNftPublishException(e.getCode(),e.getMessage());
                }catch(Exception e){
                    log.error(e.getMessage(),e);
                    //发行失败
                    throw new GalaxyNftPublishException(GalaxyErrorEnum.NFT_PUBLISH_ERROR.getCode(),"xuper004PublishAsset_exception:"+e.getMessage());
                }
            }else{
                if(!seriesNftInfoBo.getNftPublishStatus().equalsIgnoreCase(GalaxyEnum.AssetPublishStatusEnum.SUCCESS.getCode())){
                    //发行失败
                    throw new GalaxyNftPublishException(GalaxyErrorEnum.NFT_PUBLISH_ERROR.getCode(),"xuper004PublishAsset_resp:taskId : "+publishTaskId);
                }
            }
        }catch (GalaxyNftPublishException e) {
            failDesc = e.getMessage();
        }catch(Exception e){
            failDesc = e.getMessage();
            log.error(e.getMessage(),e);

        }

        if(StringUtil.isNotEmpty(failDesc)){
            //记录发行异常信息
            try{
                //发行异常或者失败记录任务id
                if(StringUtil.isNotNull(nftOrderBo)&&StringUtil.isNotEmpty(nftOrderBo.getNftPublishTaskId())){
                    nftOrderBo.setNftPublishStatus(GalaxyEnum.TaskStatusEnum.PROCESSING.getCode());
                    nftOrderBo.setUpdatedAt(LocalDateTime.now());
                    //更新nft发行状态为处理中
                    dataUtils.updateNftOrderPublishInfo(reqDto.getRouterType(),reqDto.getNftOrderPayId(),nftOrderBo);
                }else{
                    //记录错误信息
                    GalaxyNftOrderFailLogVo nftOrderFailLogVo = galaxyBeanTransferBiz.buildNftOrderFailLogVo(GalaxyEnum.TradeTypeEnum.TRADE_PUBLISH,reqDto,GalaxyEnum.OrderDealWithStatusEnum.DATA_INIT,failDesc,null
                            ,userInfoBo,seriesNftInfoBo,nftOrderBo);
                    dataUtils.setNftOrderFailLogVo(reqDto.getRouterType(),nftOrderFailLogVo);
                }
            }catch(Exception e){
                log.error(reqDto.getNftOrderPayId()+"发行setNftOrderFailLogVo记录异常："+e.getMessage(),e);
            }
            return ResponseDto.failure(GalaxyErrorEnum.PUBLISH_FAIL.getCode(), GalaxyErrorEnum.PUBLISH_FAIL.getMessage());
        }

        //更新订单缓存数据状态
        if(isPublishSuccess){
            if(StringUtil.isNotNull(nftPublishChainTimestamp)){
                //设置时间
                String nftPublishChainTimestampStr = DateUtil.format(new Date(nftPublishChainTimestamp*1000),DateUtil.Formatter.yyyyMMddHHmmss);
                nftOrderBo.setNftPublishChainTimestamp(nftPublishChainTimestampStr);
            }
            if(StringUtil.isNotNull(nftPublishStatus)){
                //转换任务状态
                nftOrderBo.setNftPublishStatus(nftPublishStatus.toString());
            }
            nftOrderBo.setNftPublishTradeHash(nftPublishTradeHash);
            nftOrderBo.setUpdatedAt(LocalDateTime.now());
            //先更新nft发行数据
            dataUtils.updateNftOrderPublishInfo(reqDto.getRouterType(),reqDto.getNftOrderPayId(),nftOrderBo);

            //第二步：执行购买逻辑
            GalaxyNftPublishAndBuyRespDto nftPublishAndBuyRespDto = this.executeBuyBusiness(reqDto,userInfoBo,seriesNftInfoBo,nftOrderBo);
            if(StringUtil.isNotNull(nftPublishAndBuyRespDto)&&StringUtil.isNotEmpty(nftPublishAndBuyRespDto.getNftId())){
                return ResponseDto.success(nftPublishAndBuyRespDto);
            }else{
                return ResponseDto.failure(GalaxyErrorEnum.NFT_BUY_FAIL.getCode(),GalaxyErrorEnum.NFT_BUY_FAIL.getMessage());
            }
        }
        return ResponseDto.failure(GalaxyErrorEnum.PUBLISH_FAIL.getCode(), GalaxyErrorEnum.PUBLISH_FAIL.getMessage());
    }


    public GalaxyNftPublishAndBuyRespDto executeBuyBusiness(GalaxyNftPublishAndBuyReqDto reqDto,GalaxyUserInfoBo userInfoBo, GalaxySeriesNftInfoBo seriesNftInfoBo,GalaxyNftOrderBo nftOrderBo){
        String buyFailDesc = null;
        //执行购买逻辑
        GalaxyNftPublishAndBuyRespDto nftPublishAndBuyRespDto = GalaxyNftPublishAndBuyRespDto.getNew();
        try{
            GalaxyNftBuyRespDto nftBuyRespDto = this.nftBuyBusinessSync(reqDto.getRouterType(),nftOrderBo.getNftId(),userInfoBo,seriesNftInfoBo,nftOrderBo);
            BeanUtil.copy(nftBuyRespDto,nftPublishAndBuyRespDto);
        }catch (GalaxyNftBuyException e){
            buyFailDesc = e.getMessage();
        }catch(Exception e){
            buyFailDesc = e.getMessage();
            log.error(e.getMessage(),e);
        }

        if(StringUtil.isNotEmpty(buyFailDesc)){
            //记录购买异常信息
            try{
                GalaxyNftOrderFailLogVo nftOrderFailLogVo = galaxyBeanTransferBiz.buildNftOrderFailLogVo(GalaxyEnum.TradeTypeEnum.TRADE_BUY,reqDto,GalaxyEnum.OrderDealWithStatusEnum.DATA_INIT,buyFailDesc,null
                        ,userInfoBo,seriesNftInfoBo,nftOrderBo);
                dataUtils.setNftOrderFailLogVo(reqDto.getRouterType(),nftOrderFailLogVo);
            }catch(Exception e){
                log.error(reqDto.getNftOrderPayId()+"购买setNftOrderFailLogVo记录异常："+e.getMessage(),e);
            }
        }
        return nftPublishAndBuyRespDto;
    }

    /**
     * 保持线程循环查询
     * @param nftId
     * @param userInfoBo
     * @param seriesNftInfoBo
     * @return
     */
    private GalaxyNftBuyRespDto nftBuyBusinessSync(String routerType,String nftId,GalaxyUserInfoBo userInfoBo, GalaxySeriesNftInfoBo seriesNftInfoBo,GalaxyNftOrderBo nftOrderBo){
        //定义返回参数
        String nftBuyTaskId = null;
        String nftBuyChainTimestamp = null;
        Integer nftBuyStatus = null;
        String nftBuyTradeHash = null;
        String nftBuyPayTaskId = null;

        /**
         * 获取订单和nft绑定信息
         */
        Long shardId = -1l;
        GalaxyNftOrderBindBo nftOrderBindBo = dataUtils.getGalaxyNftOrderBindBo(routerType,nftOrderBo.getNftOrderPayId());
        if(StringUtil.isNotNull(nftOrderBindBo)){
            shardId = nftOrderBindBo.getNftIdIndex().longValue();
        }


        //如果购买任务不为空，则直接进行购买任务查询
        if(StringUtil.isNotEmpty(nftOrderBo.getNftBuyTaskId())){
            nftBuyTaskId = nftOrderBo.getNftBuyTaskId();
        }

        if(StringUtil.isEmpty(nftBuyTaskId)){
            //购买
            Xuper007GrantShardReqDto xuper007GrantShardReqDto = Xuper007GrantShardReqDto.getNew();
            // 定义返回结果对象
            Xuper007GrantShardRespDto xuper007GrantShardRespDto = null;
            long assetId = Long.parseLong(seriesNftInfoBo.getSeriesId());
            try {
                xuper007GrantShardReqDto.setMnemonic(xuperConfig.getNftPlatformMnemonic());
                xuper007GrantShardReqDto.setAssetId(assetId);
                xuper007GrantShardReqDto.setShardId(shardId);
                xuper007GrantShardReqDto.setToAddr(xuperSdkUtil.getAccount(userInfoBo.getMnemonic()).getAddress());
                xuper007GrantShardReqDto.setToUserId(100000l);
                xuper007GrantShardReqDto.setPrice(seriesNftInfoBo.getSellCount().longValue());
                XuperResponseDto<Xuper007GrantShardRespDto> xuperResponseDto = xuperSdkUtil.xuper007GrantShard(xuper007GrantShardReqDto);
                if(xuperResponseDto.isSuccess()){
                    xuper007GrantShardRespDto = xuperResponseDto.getParseData(Xuper007GrantShardRespDto.class);
                }
            }catch (XupterException e) {
                log.error("biz error msg "+e.getMessage(),e);
            }catch (Exception e) {
                log.error("sys error msg "+e.getMessage(),e);
            }
            log.info("testXuper007GrantShard resp : "+ JsonUtils.toJson(xuper007GrantShardRespDto));
            if(StringUtil.isNotNull(xuper007GrantShardRespDto)&&xuper007GrantShardRespDto.getErrNo()==0){
                nftBuyTaskId = String.valueOf(assetId);
                nftOrderBo.setNftBuyTaskId(nftBuyTaskId);
            }
        }

        //如果购买任务id不为空
        if(StringUtil.isNotEmpty(nftBuyTaskId)){
            try{
                //3.2.4查询NFT购买结果
                Nft044BuyResultReqDto nft044ReqDto = Nft044BuyResultReqDto.getNew();
                nft044ReqDto.setTaskId(nftBuyTaskId);

                long timeStart = System.currentTimeMillis();

                int count  = 0;
                while(nftBuyPayTaskId == null){
                    Thread.sleep(500l);
                    count++;
                    log.info("=======执行nft购买第{}次查询,taskId:{}",count,nft044ReqDto.getTaskId());
                    //执行nft购买结果查询
                    GalaxyNftBuyResultQueryReqDto nftBuyResultQueryReqDto = GalaxyNftBuyResultQueryReqDto.getNew();
                    nftBuyResultQueryReqDto.setNftOrderPayId(nftOrderBo.getNftOrderPayId());
                    nftBuyResultQueryReqDto.setRouterType(routerType);
                    ResponseDto<GalaxyNftBuyResultQueryRespDto> buyResultQueryRespDto= this.nftBuyResultQuery(nftBuyResultQueryReqDto,nftOrderBo);
                    if(buyResultQueryRespDto.isSuccess()){
                        if(buyResultQueryRespDto.getData().getTaskStatus().toString().equals(GalaxyEnum.TaskStatusEnum.TASK_SUCCESS.getCode())){
                            nftBuyPayTaskId = buyResultQueryRespDto.getData().getPayTaskId();
                            nftBuyChainTimestamp = buyResultQueryRespDto.getData().getChainTimestamp();
                            nftBuyStatus = buyResultQueryRespDto.getData().getTaskStatus();
                            nftBuyTradeHash = buyResultQueryRespDto.getData().getTxHash();
                        }else if(buyResultQueryRespDto.getData().getTaskStatus().toString().equals(GalaxyEnum.TaskStatusEnum.TASK_FAIL.getCode())){
                            log.info("任务执行失败！taskId:{}",nft044ReqDto.getTaskId());
                            nftBuyStatus = buyResultQueryRespDto.getData().getTaskStatus();
                            //购买失败
                            throw new GalaxyNftBuyException(GalaxyErrorEnum.NFT_BUY_FAIL.getCode(), "nftBuyResultQuery:"+GalaxyErrorEnum.NFT_BUY_FAIL.getMessage());
                        }else if(buyResultQueryRespDto.getData().getTaskStatus().toString().equals(GalaxyEnum.TaskStatusEnum.PROCESSING.getCode())){
                            log.info("任务执行中！taskId:{}",nft044ReqDto.getTaskId());
                            nftBuyStatus = buyResultQueryRespDto.getData().getTaskStatus();
                        }
                    }

                    if(count==20){
                        //查询超过20次，则把nftId设置为空，为后续重新入队
                        nftId = null;
                        log.info("=======查询共20次，跳出循环！taskId:{}",nft044ReqDto.getTaskId());
                        break;
                    }
                }
                log.info("总共执行了多少次查询：{} 总耗时:{}",count,System.currentTimeMillis() - timeStart);
            }catch (GalaxyNftBuyException e){
                throw new GalaxyNftBuyException(e.getCode(),e.getMessage());
            }catch(Exception e){
                log.error(e.getMessage(),e);
                //发行失败
                throw new GalaxyNftBuyException(GalaxyErrorEnum.NFT_BUY_ERROR.getCode(),"nftBuyResultQuery_exception:"+e.getMessage());
            }

            //更新订单缓存数据状态
            if(StringUtil.isNotNull(nftBuyChainTimestamp)){
                //设置时间
                String nftBuyChainTimestampStr = DateUtil.format(new Date(),DateUtil.Formatter.yyyyMMddHHmmss);
                nftOrderBo.setNftBuyChainTimestamp(nftBuyChainTimestampStr);
            }
            if(StringUtil.isNotNull(nftBuyStatus)){
                nftOrderBo.setNftBuyStatus(nftBuyStatus.toString());
            }
            nftOrderBo.setNftBuyTradeHash(nftBuyTradeHash);
            nftOrderBo.setNftBuyPayTaskId(nftBuyPayTaskId);
            nftOrderBo.setUpdatedAt(LocalDateTime.now());
            //先更新nft购买数据
            dataUtils.updateNftOrderBuyInfo(routerType,nftOrderBo.getNftOrderPayId(),nftOrderBo);
        }else{
            //购买失败
            throw new GalaxyNftBuyException(GalaxyErrorEnum.NFT_BUY_ERROR.getCode(),"nftBuyResultQuery: nftBuyTaskId："+nftBuyTaskId);
        }

        GalaxyNftBuyRespDto nftBuyRespDto = GalaxyNftBuyRespDto.getNew();
        nftBuyRespDto.setUserId(userInfoBo.getUserId());
        nftBuyRespDto.setNftId(nftId);
        return nftBuyRespDto;
    }

    public ResponseDto<GalaxyNftBuyResultQueryRespDto> nftBuyResultQuery(GalaxyNftBuyResultQueryReqDto reqDto,GalaxyNftOrderBo nftOrderBo) {
        //获取订单信息
//        GalaxyNftOrderBo nftOrderBo = dataUtils.getNftOrderBo(reqDto.getRouterType(),reqDto.getNftOrderPayId());
//        if(StringUtil.isNull(nftOrderBo)){
//            return ResponseDto.failure(GalaxyErrorEnum.PUBLISH_ORDER_NOT_EXIST.getCode(), GalaxyErrorEnum.PUBLISH_ORDER_NOT_EXIST.getMessage());
//        }

        if(StringUtil.isEmpty(nftOrderBo.getNftBuyTaskId())){
            return ResponseDto.failure(GalaxyErrorEnum.NFT_BUY_TASK_NOT_EXIST.getCode(), GalaxyErrorEnum.NFT_BUY_TASK_NOT_EXIST.getMessage());
        }
        //执行资产碎片授予查询
        Xuper010QuerySdsReqDto xuper010QuerySdsReqDto = Xuper010QuerySdsReqDto.getNew();
        // 定义返回结果对象
        Xuper010QuerySdsRespDto xuper010QuerySdsRespDto = null;
        long shardId = -1l;
        GalaxyNftOrderBindBo nftOrderBindBo = dataUtils.getGalaxyNftOrderBindBo(reqDto.getRouterType(),nftOrderBo.getNftOrderPayId());
        if(StringUtil.isNotNull(nftOrderBindBo)){
            shardId = nftOrderBindBo.getNftIdIndex().longValue();
        }
        try {
            xuper010QuerySdsReqDto.setAssetId(Long.parseLong(nftOrderBo.getSeriesId()));
            xuper010QuerySdsReqDto.setShardId(shardId);
            XuperResponseDto<Xuper010QuerySdsRespDto>  xuperResponseDto = xuperSdkUtil.xuper010QuerySds(xuper010QuerySdsReqDto);
            if(xuperResponseDto.isSuccess()){
                xuper010QuerySdsRespDto = xuperResponseDto.getParseData(Xuper010QuerySdsRespDto.class);
            }
        }catch (XupterException e) {
            log.error("biz error msg "+e.getMessage(),e);
        }catch (Exception e) {
            log.error("sys error msg "+e.getMessage(),e);
        }
        log.info("xuper010QuerySds resp : "+ JsonUtils.toJson(xuper010QuerySdsRespDto));

        if(String.valueOf(xuper010QuerySdsRespDto.getErrNo()).equalsIgnoreCase(ErrorCode.SUCCESS.getCode())){
            GalaxyNftBuyResultQueryRespDto resultQueryRespDto = GalaxyNftBuyResultQueryRespDto.getNew();
            String nowTimeStr = DateUtil.getNowTime();
            //转换任务状态
            Integer taskStatus = Integer.valueOf(GalaxyEnumBiz.getGrantStatusEnum(reqDto.getRouterType(),String.valueOf(xuper010QuerySdsRespDto.getMeta().getStatus())).getCode());
            resultQueryRespDto.setTaskStatus(taskStatus);
            resultQueryRespDto.setChainTimestamp(nowTimeStr);
            resultQueryRespDto.setPayTaskId(xuper010QuerySdsRespDto.getMeta().getTxId());
            resultQueryRespDto.setTxHash(xuper010QuerySdsRespDto.getMeta().getTxId());
            return ResponseDto.success(resultQueryRespDto);
        }else{
            return ResponseDto.failure(GalaxyErrorEnum.NFT_PUBLISH_AND_BUY_QUERY_FAIL.getCode(),GalaxyErrorEnum.NFT_PUBLISH_AND_BUY_QUERY_FAIL.getMessage());
        }
    }

    /**
     * nft发行结果查询
     * @param reqDto
     * @return
     */
    private ResponseDto<GalaxyNftPublishResultQueryRespDto> nftPublishResultQuery(GalaxyNftPublishResultQueryReqDto reqDto){
        //获取订单信息
        GalaxyNftOrderBo nftOrderBo = dataUtils.getNftOrderBo(reqDto.getRouterType(),reqDto.getNftOrderPayId());
        if(StringUtil.isNull(nftOrderBo)){
            return ResponseDto.failure(GalaxyErrorEnum.PUBLISH_ORDER_NOT_EXIST.getCode(), GalaxyErrorEnum.PUBLISH_ORDER_NOT_EXIST.getMessage());
        }

        //NFT发行结果查询
        Xuper005QueryAssetReqDto xuper005QueryAssetReqDto = Xuper005QueryAssetReqDto.getNew();
        xuper005QueryAssetReqDto.setAssetId(Long.parseLong(nftOrderBo.getSeriesId()));
        // 定义返回结果对象
        Xuper005QueryAssetRespDto xuper005QueryAssetRespDto = null;
        try {
            XuperResponseDto<Xuper005QueryAssetRespDto>  xuperResponseDto = xuperSdkUtil.xuper005QueryAsset(xuper005QueryAssetReqDto);
            if(xuperResponseDto.isSuccess()){
                xuper005QueryAssetRespDto = xuperResponseDto.getParseData(Xuper005QueryAssetRespDto.class);
            }
        }catch (XupterException e) {
            log.error("biz error msg "+e.getMessage(),e);
        }catch (Exception e) {
            log.error("sys error msg "+e.getMessage(),e);
        }
        log.info("xuper005QueryAsset resp : "+ JsonUtils.toJson(xuper005QueryAssetRespDto));

        if (Integer.parseInt(ErrorCode.SUCCESS.getCode()) == xuper005QueryAssetRespDto.getErrNo()){
            //获取资产信息
            Xuper005QueryAssetRespDto.AssetMeta assetMeta = xuper005QueryAssetRespDto.getMeta();
            //设置时间
            String nftPublishChainTimestampStr = DateUtil.getNowTime();
            //转换任务状态
            String nftPublishStatusStr = GalaxyEnumBiz.getAssetPublishStatusEnum(reqDto.getRouterType(),String.valueOf(assetMeta.getStatus())).getCode();

            //构造返回结果
            GalaxyNftPublishResultQueryRespDto nftPublishResultQueryRespDto = GalaxyNftPublishResultQueryRespDto.getNew();
            nftPublishResultQueryRespDto.setNftIdBegin(nftOrderBo.getNftId());
            nftPublishResultQueryRespDto.setTaskMsg(nftOrderBo.getNftId());
            nftPublishResultQueryRespDto.setTxHash(assetMeta.getTxId());
            nftPublishResultQueryRespDto.setChainTimestamp(nftPublishChainTimestampStr);
            nftPublishResultQueryRespDto.setTaskStatus(Integer.valueOf(nftPublishStatusStr));

            return ResponseDto.success(nftPublishResultQueryRespDto);
        }else{
            return ResponseDto.failure(GalaxyErrorEnum.PUBLISH_FAIL.getCode(), GalaxyErrorEnum.PUBLISH_FAIL.getMessage());
        }
    }
}
