package com.liquidnet.service.consumer.kylin.service.processor;

import com.liquidnet.common.exception.LiquidnetServiceException;
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.*;
import com.liquidnet.common.third.zxlnft.util.ZxlnftSdkUtil;
import com.liquidnet.commons.lang.util.BASE64Util;
import com.liquidnet.commons.lang.util.BeanUtil;
import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.commons.lang.util.StringUtil;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.consumer.kylin.utils.DataUtils;
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 lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;

/**
 * @author AnJiabin <anjiabin@zhengzai.tv>
 * @version V1.0
 * @Description: TODO
 * @class: ConsumerJsonNftPublishAndBuyProcessor
 * @Package com.liquidnet.service.consumer.kylin.service.processor
 * @Copyright: LightNet @ Copyright (c) 2022
 * @date 2022/3/29 17:04
 */
@Slf4j
@Component
public class ConsumerJsonNftPublishAndBuyProcessor {
    @Autowired
    private ZxlnftSdkUtil zxlnftSdkUtil;

    @Autowired
    private ZxlnftBiz zxlnftBiz;

    @Autowired
    private ZxlnftConfig zxlnftConfig;

    @Autowired
    private DataUtils dataUtils;

    public ResponseDto<GalaxyNftPublishAndBuyRespDto> nftPublishAndBuy(GalaxyNftPublishAndBuyReqDto reqDto) {
        //获取订单信息
        GalaxyNftOrderBo nftOrderBo = dataUtils.getNftOrderBo(reqDto.getRouterType(),reqDto.getNftOrderPayId());
        if(StringUtil.isNotNull(nftOrderBo)){
            return ResponseDto.failure(GalaxyErrorEnum.PUBLISH_FAIL_ALREADY_EXIST.getCode(), GalaxyErrorEnum.PUBLISH_FAIL_ALREADY_EXIST.getMessage());
        }


        //获取用户信息
        GalaxyUserInfoBo userInfoBo = dataUtils.getGalaxyUserInfo(reqDto.getRouterType(),reqDto.getUserId());

        //获取sku信息
        GalaxySeriesNftInfoBo seriesNftInfoBo = dataUtils.getSeriesNftInfoBo(reqDto.getRouterType(),reqDto.getSkuId());

        String author = seriesNftInfoBo.getAuthor();
        String nftName = seriesNftInfoBo.getNftName();
        String nftUrl = seriesNftInfoBo.getNftUrl();
        String displayUrl = seriesNftInfoBo.getDisplayUrl();

        String nftDesc = seriesNftInfoBo.getNftDesc();
        String nftFlag = seriesNftInfoBo.getNftFlag();
        //发行个数
        Long publishCount = 1L;
        //开始索引
        Integer seriesBeginIndex = 0;
        //发行金额
        Long sellCount = Long.valueOf(seriesNftInfoBo.getSellCount().multiply(BigDecimal.valueOf(100l)).longValue()); //积分
        /**
         * 根据sku获取系列Id
         */
        String seriesId = seriesNftInfoBo.getSkuId();
        //返回参数nftId
        String nftId = null;


        //查询系列信息
        Nft032SeriesReqDto nft032ReqDto = Nft032SeriesReqDto.getNew();
        nft032ReqDto.setSeriesId(seriesId);
        ZxlnftResponseDto<Nft032SeriesRespDto> resp = zxlnftSdkUtil.nft032Series(nft032ReqDto);

        if(!resp.isSuccess()){
            //该系列已经发行多少个nft
            Long crtCount = resp.getData().getSeriesInfo().getCrtCount();
            log.info("系列：{} 已发行 ：{}", seriesId, crtCount);
            //设置开始索引
            seriesBeginIndex = Integer.parseInt(String.valueOf(crtCount.longValue() + 1));
        }

        //3.1.2调用NFT发行接口
        /**
         * 发行无限制系列
         */
        Nft034PublishReqDto nft034ReqDto = Nft034PublishReqDto.getNew();
        nft034ReqDto.setAuthor(author);
        nft034ReqDto.setName(nftName);
        nft034ReqDto.setUrl(nftUrl);
        nft034ReqDto.setDisplayUrl(displayUrl);
        nft034ReqDto.setDesc(nftDesc);
        nft034ReqDto.setFlag(nftFlag);
        nft034ReqDto.setPublishCount(publishCount);
        //无限制零系列
        nft034ReqDto.setSeriesId(seriesId);
        nft034ReqDto.setSeriesBeginIndex(seriesBeginIndex);
        nft034ReqDto.setSellStatus(Integer.parseInt(ZxlnftEnum.SellStatusEnum.CAN_SELL.getCode()));
        nft034ReqDto.setSellCount(sellCount);
        nft034ReqDto.setOperateId(IDGenerator.get32UUID());
        nft034ReqDto.setMetaData("");

        ZxlnftResponseDto<Nft034PublishRespDto> nft034RespDto = zxlnftSdkUtil.nft034Publish(nft034ReqDto);

        if (nft034RespDto.isSuccess()) {
            //3.1.4查询 NFT发行结果
            Nft035PublishResultReqDto nft035ReqDto = Nft035PublishResultReqDto.getNew();
            nft035ReqDto.setTaskId(nft034RespDto.getData().getTaskId());
            //休眠1秒钟，等待执行结果
            try {
                Thread.sleep(1000l);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            long timeStart = System.currentTimeMillis();
            log.info("=======执行第{}次查询,taskId:{}", 1, nft035ReqDto.getTaskId());
            ZxlnftResponseDto<Nft035PublishResultRespDto> nft035RespDto = zxlnftSdkUtil.nft035PublishResult(nft035ReqDto);

            if (nft035RespDto.isSuccess()) {
                if (nft035RespDto.getData().getTaskStatus().toString().equals(ZxlnftEnum.TaskStatusEnum.TASK_FAIL.getCode())) {
                    log.info("任务执行失败！taskId:{} taskMsg:{}", nft035ReqDto.getTaskId(), nft035RespDto.getData().getTaskMsg());
                    return null;
                }

                int count = 1;
                String nftIdBegin = nft035RespDto.getData().getNftIdBegin();

                if (nft035RespDto.getData().getTaskStatus().toString().equals(ZxlnftEnum.TaskStatusEnum.PROCESSING.getCode())) {
                    log.info(ZxlnftEnum.TaskStatusEnum.PROCESSING.getMessage());
                    while (StringUtil.isEmpty(nftIdBegin)) {
                        //休眠1秒钟，等待执行结果
                        try {
                            Thread.sleep(1000l);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                        count++;
                        ZxlnftResponseDto<Nft035PublishResultRespDto> nft035RespDtoTemp = zxlnftSdkUtil.nft035PublishResult(nft035ReqDto);
                        log.info("=======执行第{}次查询,taskId:{}", count, nft035ReqDto.getTaskId());
                        if (nft035RespDtoTemp.getData().getTaskStatus().toString().equals(ZxlnftEnum.TaskStatusEnum.TASK_SUCCESS.getCode())) {
                            nftIdBegin = nft035RespDtoTemp.getData().getNftIdBegin();
                        } else if (nft035RespDtoTemp.getData().getTaskStatus().toString().equals(ZxlnftEnum.TaskStatusEnum.TASK_FAIL.getCode())) {
                            log.info("任务执行失败！taskId:{}", nft035ReqDto.getTaskId());
                            return null;
                        }

                        if (count == 6) {
                            log.info("=======查询共6次，跳出循环！taskId:{}", nft035ReqDto.getTaskId());
                            break;
                        }
                    }
                } else if (nft035RespDto.getData().getTaskStatus().toString().equals(ZxlnftEnum.TaskStatusEnum.TASK_SUCCESS.getCode())) {
                    log.info(ZxlnftEnum.TaskStatusEnum.TASK_SUCCESS.getMessage());
                }

                log.info("发行NFT后返回给前端nftID:{}", nftIdBegin);
                log.info("总共执行了{}次查询 总耗时:{} MS", count, (System.currentTimeMillis() - timeStart));

                if (StringUtil.isNotEmpty(nftIdBegin)) {
                    nftId = nftIdBegin;
                    //3.1.3调用NFT查询接口
                    Nft036InfoReqDto nft036ReqDto = Nft036InfoReqDto.getNew();
                    nft036ReqDto.setNftId(nftIdBegin);
                    ZxlnftResponseDto<Nft036InfoRespDto> nft036RespDto = zxlnftSdkUtil.nft036Info(nft036ReqDto);
                    log.info("调用NFT查询接口 : {}", nft036RespDto.toJson());
                }
            }
        }
        if(StringUtil.isNotEmpty(nftId)){
            //执行购买逻辑
            GalaxyNftPublishAndBuyRespDto nftPublishAndBuyRespDto = GalaxyNftPublishAndBuyRespDto.getNew();
            GalaxyNftBuyRespDto nftBuyRespDto = this.nftBuyBusiness(reqDto.getRouterType(),nftId,userInfoBo,seriesNftInfoBo,nftOrderBo);
            BeanUtil.copy(nftBuyRespDto,nftPublishAndBuyRespDto);
            return ResponseDto.success(nftPublishAndBuyRespDto);
        }else{
            return ResponseDto.failure(GalaxyErrorEnum.PUBLISH_FAIL.getCode(), GalaxyErrorEnum.PUBLISH_FAIL.getMessage());
        }
    }

    private GalaxyNftBuyRespDto nftBuyBusiness(String routerType,String nftId,GalaxyUserInfoBo userInfoBo, GalaxySeriesNftInfoBo seriesNftInfoBo,GalaxyNftOrderBo nftOrderBo){
//        3.2.2调用购买NFT接口
        Nft043BuyReqDto nft043BuyReqDto = Nft043BuyReqDto.getNew();
        nft043BuyReqDto.setNftId(nftId);
        nft043BuyReqDto.setApplyScore(seriesNftInfoBo.getSellCount().intValue());
        try {
            nft043BuyReqDto.setReceiverPubKey(BASE64Util.decode(userInfoBo.getUserPubKey()));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        nft043BuyReqDto.setPointReceiverAddr(userInfoBo.getBlockChainAddress());
        nft043BuyReqDto.setOfferCount(seriesNftInfoBo.getSellCount().longValue());
        nft043BuyReqDto.setOperateId(IDGenerator.get32UUID());

        /**
         * 接收人的私钥签名，签名对象是(platformPubKey_receiverPubKey_pointReceiverAddr_applyScore_接口名_nftId_offerCount_operateId)
         * 接口名：buy_nft
         */
        String signMetaData = zxlnftConfig.getNftPlatformPubKey()
                .concat("_").concat(nft043BuyReqDto.getReceiverPubKey())
                .concat("_").concat(nft043BuyReqDto.getPointReceiverAddr())
                .concat("_").concat(nft043BuyReqDto.getApplyScore().toString())
                .concat("_").concat("buy_nft")
                .concat("_").concat(nft043BuyReqDto.getNftId())
                .concat("_").concat(nft043BuyReqDto.getOfferCount().toString())
                .concat("_").concat(nft043BuyReqDto.getOperateId());
        String signature = null;
        try {
            signature = zxlnftBiz.createSign(BASE64Util.decode(userInfoBo.getUserPriKey()),signMetaData);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        nft043BuyReqDto.setSignature(signature);

        String nftBuyTaskId = null;
        ZxlnftResponseDto<Nft043BuyRespDto> nft043RespDto = zxlnftSdkUtil.nft043Buy(nft043BuyReqDto);
        if(nft043RespDto.isSuccess()){
            nftBuyTaskId = nft043RespDto.getData().getTaskId();
        }else{
            throw new LiquidnetServiceException(nft043RespDto.getCode(),nft043RespDto.getMessage());
        }

        //更新缓存数据状态
        nftOrderBo.setNftBuyTaskId(nftBuyTaskId);
        dataUtils.updateNftOrderBuyTaskId(routerType,nftOrderBo.getNftOrderPayId(),nftOrderBo);

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