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

import com.liquidnet.common.third.zxlnft.biz.ZxlnftBiz;
import com.liquidnet.common.third.zxlnft.config.ZxlnftConfig;
import com.liquidnet.common.third.zxlnft.constant.ZxlnftEnum;
import com.liquidnet.common.third.zxlnft.dto.Nft044BuyResultReqDto;
import com.liquidnet.common.third.zxlnft.dto.Nft044BuyResultRespDto;
import com.liquidnet.common.third.zxlnft.dto.ZxlnftResponseDto;
import com.liquidnet.common.third.zxlnft.util.ZxlnftSdkUtil;
import com.liquidnet.commons.lang.util.BeanUtil;
import com.liquidnet.commons.lang.util.DateUtil;
import com.liquidnet.commons.lang.util.StringUtil;
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.GalaxyNftOrderBo;
import com.liquidnet.service.galaxy.dto.bo.GalaxySeriesNftInfoBo;
import com.liquidnet.service.galaxy.dto.bo.GalaxyUserInfoBo;
import com.liquidnet.service.galaxy.dto.param.GalaxyNftBuyRespDto;
import com.liquidnet.service.galaxy.dto.param.GalaxyNftPublishAndBuyReqDto;
import com.liquidnet.service.galaxy.dto.param.GalaxyNftPublishAndBuyRespDto;
import com.liquidnet.service.galaxy.dto.vo.mongo.GalaxyNftOrderFailLogVo;
import com.liquidnet.service.galaxy.exception.GalaxyNftBuyException;
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 ZxlnftSdkUtil zxlnftSdkUtil;

    @Autowired
    private ZxlnftBiz zxlnftBiz;

    @Autowired
    private ZxlnftConfig zxlnftConfig;

    @Autowired
    private GalaxyDataUtils dataUtils;

    @Autowired
    private GalaxyBeanTransferBiz galaxyBeanTransferBiz;

    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;
        Long nftBuyChainTimestamp = null;
        Integer nftBuyStatus = null;
        String nftBuyTradeHash = null;
        String nftBuyPayTaskId = null;

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

        if(StringUtil.isEmpty(nftBuyTaskId)){
//            //购买
//            Xuper007GrantShardReqDto xuper007GrantShardReqDto = Xuper007GrantShardReqDto.getNew();
//            // 定义返回结果对象
//            Xuper007GrantShardRespDto xuper007GrantShardRespDto = null;
//            long assetId = 171095615845019437l;
////        long assetId = 1532351545249738541l;
//
//            try {
//                xuper007GrantShardReqDto.setMnemonic(creatorMnemonic);
//                xuper007GrantShardReqDto.setAssetId(assetId);
//                xuper007GrantShardReqDto.setShardId(1l);
//                xuper007GrantShardReqDto.setToAddr(xuperSdkUtil.getAccount(customerMnemonic).getAddress());
//                xuper007GrantShardReqDto.setToUserId(100000l);
//                xuper007GrantShardReqDto.setPrice(1234l);
//                XuperResponseDto<Xuper007GrantShardRespDto> xuperResponseDto = xuperSdkUtil.xuper007GrantShard(reqDto);
//                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(respDto));
//            if(nft043RespDto.isSuccess()){
//                nftBuyTaskId = nft043RespDto.getData().getTaskId();
//                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("=======执行第{}次查询,taskId:{}",count,nft044ReqDto.getTaskId());
                    ZxlnftResponseDto<Nft044BuyResultRespDto> nft044RespDto = zxlnftSdkUtil.nft044BuyResult(nft044ReqDto);
                    if(nft044RespDto.getData().getTaskStatus().toString().equals(ZxlnftEnum.TaskStatusEnum.TASK_SUCCESS.getCode())){
                        nftBuyPayTaskId = nft044RespDto.getData().getPayTaskId();
                        nftBuyChainTimestamp = nft044RespDto.getData().getChainTimestamp();
                        nftBuyStatus = nft044RespDto.getData().getTaskStatus();
                        nftBuyTradeHash = nft044RespDto.getData().getTxHash();
                    }else if(nft044RespDto.getData().getTaskStatus().toString().equals(ZxlnftEnum.TaskStatusEnum.TASK_FAIL.getCode())){
                        log.info("任务执行失败！taskId:{}",nft044ReqDto.getTaskId());
                        nftBuyStatus = nft044RespDto.getData().getTaskStatus();

                        //购买失败
                        throw new GalaxyNftBuyException(GalaxyErrorEnum.NFT_BUY_FAIL.getCode(), "nft044BuyResult_resp:"+GalaxyErrorEnum.NFT_BUY_FAIL.getMessage());
                    }else if(nft044RespDto.getData().getTaskStatus().toString().equals(ZxlnftEnum.TaskStatusEnum.PROCESSING.getCode())){
                        log.info("任务执行中！taskId:{}",nft044ReqDto.getTaskId());
                        nftBuyStatus = nft044RespDto.getData().getTaskStatus();
                    }
                    if(count==20){
                        //查询超过20次，则把nftId设置为空，为后续重新入队
                        nftId = null;
                        log.info("=======查询共5次，跳出循环！taskId:{}",nft044ReqDto.getTaskId());
                        break;
                    }
                }
                log.info("总共执行了多少次查询：{} 总耗时:{}",count,System.currentTimeMillis() - timeStart);
//            if(StringUtil.isNotEmpty(payTaskId)){
//                //3.2.5查询NFT购买支付结果
//                Nft045BuyPayResultReqDto nft045ReqDto = Nft045BuyPayResultReqDto.getNew();
//                nft045ReqDto.setTaskId(payTaskId);
//                ZxlnftResponseDto<Nft045BuyPayResultRespDto> nft045RespDto = zxlnftSdkUtil.nft045BuyPayResult(nft045ReqDto);
//            }
            }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(),"nft044BuyResult_exception:"+e.getMessage());
            }

            //更新订单缓存数据状态
            if(StringUtil.isNotNull(nftBuyChainTimestamp)){
                //设置时间
                String nftBuyChainTimestampStr = DateUtil.format(new Date(nftBuyChainTimestamp*1000),DateUtil.Formatter.yyyyMMddHHmmss);
                nftOrderBo.setNftBuyChainTimestamp(nftBuyChainTimestampStr);
            }
            if(StringUtil.isNotNull(nftBuyStatus)){
                //转换任务状态
                String nftBuyStatusStr = GalaxyEnumBiz.getTaskStatusEnum(routerType,nftBuyStatus.toString()).getCode();

                nftOrderBo.setNftBuyStatus(nftBuyStatusStr);
            }
            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(),"nft043Buy_resp: nftBuyTaskId："+nftBuyTaskId);
        }

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