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

import com.liquidnet.common.third.zxlnft.biz.ZxlnftBiz;
import com.liquidnet.common.third.zxlnft.config.ZxlnftConfig;
import com.liquidnet.common.third.zxlnft.constant.ZxlErrorEnum;
import com.liquidnet.common.third.zxlnft.constant.ZxlnftEnum;
import com.liquidnet.common.third.zxlnft.dto.*;
import com.liquidnet.common.third.zxlnft.dto.wallet.UploadToCosReq;
import com.liquidnet.common.third.zxlnft.dto.wallet.UploadToCosResp;
import com.liquidnet.common.third.zxlnft.exception.ZxlNftException;
import com.liquidnet.common.third.zxlnft.util.ZxlWalletSdkUtil;
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.IDGenerator;
import com.liquidnet.commons.lang.util.StringUtil;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.galaxy.constant.GalaxyConstant;
import com.liquidnet.service.galaxy.constant.GalaxyErrorCodeEnum;
import com.liquidnet.service.galaxy.dto.bo.GalaxySeriesInfoBo;
import com.liquidnet.service.galaxy.dto.param.*;
import com.liquidnet.service.galaxy.utils.DataUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * @author AnJiabin <anjiabin@zhengzai.tv>
 * @version V1.0
 * @Description: TODO
 * @class: ZxinArtworkBiz
 * @Package com.liquidnet.service.galaxy.router.zxin.biz
 * @Copyright: LightNet @ Copyright (c) 2021
 * @date 2022/3/15 13:04
 */
@Slf4j
@Component
public class ZxinArtworkBiz {
    @Autowired
    private ZxlnftSdkUtil zxlnftSdkUtil;

    @Autowired
    private ZxlWalletSdkUtil zxlWalletSdkUtil;

    @Autowired
    private ZxlnftBiz zxlnftBiz;

    @Autowired
    private ZxlnftConfig zxlnftConfig;

    @Autowired
    private DataUtils dataUtils;

    @Value("${liquidnet.galaxy.temp-file-path:/Users/anjiabin/mdsky_gitlab/galaxy/tempFilePath}")
    private String tempFilePath;

    public ResponseDto<GalaxyNftImageRespDto> nftImageCheck(GalaxyNftImageReqDto reqDto) {
        Nft008QueryImageModerationReqDto nft008ReqDto = Nft008QueryImageModerationReqDto.getNew();
        nft008ReqDto.setImageUrl(reqDto.getNftOriginalUrl());
        ZxlnftResponseDto<Nft008QueryImageModerationRespDto> nft008RespDto = zxlnftSdkUtil.nft008QueryImageModeration(nft008ReqDto);
        if(!nft008RespDto.isSuccess()){
            throw new ZxlNftException(ZxlErrorEnum.IMAGE_CHECK_ERROR.getCode(),ZxlErrorEnum.IMAGE_CHECK_ERROR.getMsg());
        }
        GalaxyNftImageRespDto nftImageRespDto = GalaxyNftImageRespDto.getNew();
        BeanUtil.copy(nft008RespDto.getData(),nftImageRespDto);
        return ResponseDto.success(nftImageRespDto);
    }



    public ResponseDto<GalaxyNftUploadRespDto> nftUpload(GalaxyNftUploadReqDto reqDto) {
        String imageUrl = reqDto.getNftOriginalUrl();
        //上传系列名只用来目录区分
        String seriesName = GalaxyConstant.SERIES_NAME_PREFIX + reqDto.getSkuId(); //素材存储目录
        String filePath = null;
        String imageType = imageUrl.substring(imageUrl.lastIndexOf("."),imageUrl.length());
        String fileName =  IDGenerator.getZxlNftImageCosCode() + imageType;

        //通过图片url地址上传
        File cosFile = this.inputStreamToFile(reqDto.getNftOriginalUrl(),fileName);
        filePath = cosFile.getAbsolutePath();
        log.info("cosFile.getPath() :{}",cosFile.getPath());
        log.info("cosFile.getAbsoluteFile() :{}",cosFile.getAbsoluteFile());

        //完整全路径 https://zhixinliantest-1302317679.cos.ap-guangzhou.myqcloud.com/nft/4e40d5f6f65aa8ec9bc33ab424e0167e68783bbe95d4d265086314d749808eef/NOW_ZXL_NFT_PIC001_test_skuId001/2022-03-04/ZXLNFTIMAGE202203041707466694345291.jpg
        String fullFilePath = null; //需要保存,返回给调用者
        String seriesId = null;

//        1.4.2调用生成素材上传临时密钥接口
        Nft022UploadSecretReqDto nft022ReqDto = Nft022UploadSecretReqDto.getNew();
        nft022ReqDto.setSeriesName(seriesName);
        nft022ReqDto.setTimestamp(DateUtil.getNowSeconds().toString());
        nft022ReqDto.setUserPubKey(zxlnftConfig.getNftPlatformPubKey());

        //系列为空
        String userData = nft022ReqDto.getTimestamp();
        //系列不为空
        if(StringUtil.isNotEmpty(nft022ReqDto.getSeriesName())){
            userData = nft022ReqDto.getTimestamp() + "_" + nft022ReqDto.getSeriesName();
        }

        nft022ReqDto.setUserSignedData(zxlnftBiz.createSign(zxlnftConfig.getNftPlatformPriKey(),userData));

        ZxlnftResponseDto<Nft022UploadSecretRespDto> nft022RespDto = zxlnftSdkUtil.nft022UploadSecret(nft022ReqDto);

        if(!nft022RespDto.isSuccess()){
            throw new ZxlNftException(ZxlErrorEnum.UPLOAD_TEMP_SECRET.getCode(),ZxlErrorEnum.UPLOAD_TEMP_SECRET.getMsg());
        }
//        1.4.3调用sdk接口-上传cos接口
        if(nft022RespDto.isSuccess()){
            fullFilePath = nft022RespDto.getData().getUploadAddress().concat(fileName);
            UploadToCosReq req = UploadToCosReq.getNew();
            req.setCosPath(fullFilePath);
            req.setTempSecretId(nft022RespDto.getData().getTempSecretId());
            req.setTempSecretKey(nft022RespDto.getData().getTempSecretKey());
            req.setSessionToken(nft022RespDto.getData().getSessionToken());
            req.setFilePath(filePath);
            UploadToCosResp uploadToCosResp = zxlWalletSdkUtil.uploadToCos(req);
        }

        log.info("完整的素材访问fullFilePath url：{}",fullFilePath);

        //进行系列声明

        GalaxyNftUploadRespDto galaxyNftUploadRespDto = GalaxyNftUploadRespDto.getNew();
        galaxyNftUploadRespDto.setMaterialAccessUrl(fullFilePath);
        galaxyNftUploadRespDto.setSkuId(reqDto.getSkuId());
        galaxyNftUploadRespDto.setNftOriginalUrl(reqDto.getNftOriginalUrl());

        return ResponseDto.success(galaxyNftUploadRespDto);
        //        1.4.4调用查询素材地址接口 -- 非必需
//        Nft021UploadUrlReqDto nft021ReqDto = Nft021UploadUrlReqDto.getNew();
//        nft021ReqDto.setSeriesName(seriesName);
//        nft021ReqDto.setPlatformIdentification(zxlnftConfig.getPlatformIdentification());
//        //如果上传人就是平台管理员，以下需要注释掉，因为会导致返回的地址多了一级目录
////        nft021ReqDto.setUserIdentification(zxlnftConfig.getPlatformIdentification());
//        ZxlnftResponseDto<Nft021UploadUrlRespDto> resp = zxlnftSdkUtil.nft021UploadUrl(nft021ReqDto);
    }

    public ResponseDto<GalaxyArtSeriesClaimRespDto> seriesClaim(GalaxyArtSeriesClaimReqDto reqDto) {
        String skuId = reqDto.getSkuId();
        String seriesName = GalaxyConstant.SERIES_NAME_PREFIX.concat(skuId);
        String nftUrl = reqDto.getCoverUrl();
        Long totalCound = reqDto.getTotalCount();
        String desc = reqDto.getDesc();
        //返回参数
        String seriesId = null;
        String taskId = null;
        GalaxySeriesInfoBo seriesInfoBo = dataUtils.getSeriesInfoBo(reqDto.getRouteType(),reqDto.getSkuId());
        if(StringUtil.isNotNull(seriesInfoBo)){
            /**
             * 如果系列声明成功，则不允许继续声明
             */
            if(seriesInfoBo.getPublishStatus().equalsIgnoreCase(GalaxyConstant.SeriesClaimStatusEnum.SUCCESS.getCode())){
                GalaxyArtSeriesClaimRespDto seriesClaimRespDto = GalaxyArtSeriesClaimRespDto.getNew();
                seriesClaimRespDto.setSkuId(seriesInfoBo.getSkuId());
                seriesClaimRespDto.setMaterialAccessUrl(seriesInfoBo.getNftUrl());
                seriesClaimRespDto.setSeriesId(seriesInfoBo.getSeriesId());
                seriesClaimRespDto.setSeriesName(seriesInfoBo.getSeriesName());
                return ResponseDto.success(seriesClaimRespDto);
            }
        }
        /**
         * 进行系列声明
         */
        Nft030SeriesClaimReqDto nft030ReqDto = Nft030SeriesClaimReqDto.getNew();
        nft030ReqDto.setPubKey(zxlnftConfig.getNftPlatformPubKey());
        nft030ReqDto.setSeriesName(seriesName);
        //无限制系列 设置为0
        nft030ReqDto.setTotalCount(totalCound);
        nft030ReqDto.setOperateId(IDGenerator.get32UUID());
        //系列封面
        nft030ReqDto.setCoverUrl(nftUrl);
        nft030ReqDto.setDesc(desc);
        nft030ReqDto.setMaxPublishCount(0);
        nft030ReqDto.setSeriesBeginFromZero(false);
        ZxlnftResponseDto<Nft030SeriesClaimRespDto> nft30RespDto = zxlnftSdkUtil.nft030SeriesClaim(nft030ReqDto);

        //{"taskId":"49d1cccc-e62c-40bc-923c-bfac31325351_nft-series-claim_1"}
        if(nft30RespDto.isSuccess()){
            //系列声明结果查询
            Nft031SeriesClaimResultReqDto nft031ReqDto = Nft031SeriesClaimResultReqDto.getNew();
            //第零个系列 无限制系列
            taskId = nft30RespDto.getData().getTaskId();
            nft031ReqDto.setTaskId(taskId);

            int count  = 0;
            while(StringUtil.isEmpty(seriesId)){
                //休眠1秒钟，等待执行结果
                try {
                    Thread.sleep(1000l);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                count++;
                log.info("=======执行第{}次查询,taskId:{}",count,nft031ReqDto.getTaskId());
                ZxlnftResponseDto<Nft031SeriesClaimResultRespDto> nft031RespDtoTemp = zxlnftSdkUtil.nft031SeriesClaimResult(nft031ReqDto);
                if(nft031RespDtoTemp.getData().getTaskStatus().toString().equals(ZxlnftEnum.TaskStatusEnum.TASK_SUCCESS.getCode())){
                    seriesId = nft031RespDtoTemp.getData().getSeriesId();
                    break;
                }else if(nft031RespDtoTemp.getData().getTaskStatus().toString().equals(ZxlnftEnum.TaskStatusEnum.TASK_FAIL.getCode())){
                    log.info("任务执行失败！taskId:{}",nft031ReqDto.getTaskId());
                    return ResponseDto.failure(GalaxyErrorCodeEnum.SERIES_CLAIM_ERROR.getCode(),GalaxyErrorCodeEnum.SERIES_CLAIM_ERROR.getMessage());
                }
                if(count==5){
                    log.info("=======查询共5次，跳出循环！taskId:{}",nft031ReqDto.getTaskId());
                    return ResponseDto.failure(GalaxyErrorCodeEnum.SERIES_CLAIM_ERROR_FIVE_TIMES.getCode(),GalaxyErrorCodeEnum.SERIES_CLAIM_ERROR_FIVE_TIMES.getMessage());
                }
            }

            log.info("系列声明结果查询 seriesId :{}",seriesId);
        }

        GalaxyArtSeriesClaimRespDto seriesClaimRespDto = GalaxyArtSeriesClaimRespDto.getNew();
        seriesClaimRespDto.setSkuId(skuId);
        seriesClaimRespDto.setMaterialAccessUrl(nftUrl);
        seriesClaimRespDto.setSeriesId(seriesId);
        seriesClaimRespDto.setSeriesName(seriesName);

        //构造缓存数据
        if(seriesInfoBo==null){
            this.buildSeriesInfoBo(skuId,seriesName,seriesId,totalCound,0l,nftUrl,nftUrl);
            dataUtils.setSeriesInfoBo(reqDto.getRouteType(),reqDto.getSkuId(),seriesInfoBo);
        }
        return ResponseDto.success(seriesClaimRespDto);
    }


    private GalaxySeriesInfoBo buildSeriesInfoBo(String skuId,String seriesName,String seriesId,Long totalCount,Long crtCount,String nftUrl,String imageUrl){

        GalaxySeriesInfoBo seriesInfoBo = GalaxySeriesInfoBo.getNew();
        seriesInfoBo.setSkuId(skuId);
        seriesInfoBo.setSeriesName(seriesName);
        seriesInfoBo.setSeriesId(seriesId);
        seriesInfoBo.setTotalCount(totalCount);
        seriesInfoBo.setCrtCount(crtCount);
        if(StringUtil.isEmpty(seriesId)){
            seriesInfoBo.setPublishStatus(GalaxyConstant.SeriesClaimStatusEnum.PROCESSING.getCode());
        }else{
            seriesInfoBo.setPublishStatus(GalaxyConstant.SeriesClaimStatusEnum.SUCCESS.getCode());
        }
        seriesInfoBo.setNftUrl(nftUrl);
        return seriesInfoBo;
    }


    /**
     * 通过URL上传
     * @param url
     * @param name
     * @return
     */
    public File inputStreamToFile(String url, String name) {
        try {
            HttpURLConnection httpUrl = (HttpURLConnection) new URL(url).openConnection();
            httpUrl.connect();
            InputStream ins = httpUrl.getInputStream();
//            File file = new File(System.getProperty("java.io.tmpdir") + File.separator + name);
            File file = new File(tempFilePath + File.separator + name);
            if (file.exists()) {
                return file;
            }
            OutputStream os = new FileOutputStream(file);
            int bytesRead;
            int len = 8192;
            byte[] buffer = new byte[len];
            while ((bytesRead = ins.read(buffer, 0, len)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            ins.close();
            return file;
        } catch (Exception e) {
            log.error("inputStreamToFileUrlError", e);
            return null;
        }
    }
}
