package com.liquidnet.service.goblin.service.impl.inner;

import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.base.SqlMapping;
import com.liquidnet.service.base.constant.MQConst;
import com.liquidnet.service.galaxy.dto.param.GalaxyNftTransferQueryReqDto;
import com.liquidnet.service.galaxy.dto.param.GalaxyNftTransferQueryRespDto;
import com.liquidnet.service.galaxy.service.IGalaxyTradeService;
import com.liquidnet.service.goblin.constant.GoblinStatusConst;
import com.liquidnet.service.goblin.dto.vo.GoblinGoodsSkuInfoVo;
import com.liquidnet.service.goblin.dto.vo.GoblinUserDigitalArtworkVo;
import com.liquidnet.service.goblin.util.GoblinMongoUtils;
import com.liquidnet.service.goblin.util.GoblinRedisUtils;
import com.liquidnet.service.goblin.util.QueueUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.LinkedList;

@Slf4j
@Service
public class GoblinQueBizArtworkTransQueryService {
    @Autowired
    QueueUtils queueUtils;
    @Autowired
    GoblinRedisUtils goblinRedisUtils;
    @Autowired
    GoblinMongoUtils goblinMongoUtils;

    @Resource(name = "galaxyTradeServiceImpl")
    private IGalaxyTradeService galaxyTradeService;

    public ResponseDto<String> bizArtworkTransQueryProcessing(String artworkId) {
        try {
            GoblinUserDigitalArtworkVo userDigitalArtworkVo = goblinRedisUtils.getUserDigitalArtworkVo(artworkId);
            if (null == userDigitalArtworkVo) {
                log.warn("#藏品转赠结果查询:藏品不存在[artworkId={}]", artworkId);
                return ResponseDto.success(String.format("藏品不存在[artworkId:%s]", artworkId));
            }
            String transferOrderId = userDigitalArtworkVo.getTransferOrderId(), receiverUid = userDigitalArtworkVo.getReceiverUid();
            if (!GoblinStatusConst.TransferState.PENDING.name().equals(userDigitalArtworkVo.getTransferState())) {
                log.warn("#藏品转赠结果查询:藏品非转赠中不处理[artworkId={},transferState={},transferOrderId={}]", artworkId, userDigitalArtworkVo.getTransferState(), transferOrderId);
                return ResponseDto.success(String.format("藏品非转赠中不处理[artworkId:%s]", artworkId));
            }

            GoblinGoodsSkuInfoVo goodsSkuInfoVo = goblinRedisUtils.getGoodsSkuInfoVo(userDigitalArtworkVo.getSkuId());
            GalaxyNftTransferQueryRespDto queryRespDto = this.queryNftTransferQueryRespDto(transferOrderId, goodsSkuInfoVo.getRouteType());
            if (null == queryRespDto || !"1".equals(queryRespDto.getTransferStatus())) {// 查询失败，重新入队处理
                queueUtils.sendMsgByRedis(MQConst.GoblinQueue.BIZ_ARTWORK_TRANS_QUERY.getKey(), userDigitalArtworkVo.getArtworkId());
                return ResponseDto.failure(String.format("藏品转赠结果查询失败[artworkId:%s]", artworkId));
            }
            if (!receiverUid.equals(queryRespDto.getOwnerUserId())) {// 拥有者与受赠人不一致（特殊情况，重新入队处理）
                log.warn("#藏品转赠结果查询:拥有者与受赠人不一致[artworkId={},receiverUid={},ownerUserId={}]", userDigitalArtworkVo.getArtworkId(), receiverUid, queryRespDto.getOwnerUserId());
                queueUtils.sendMsgByRedis(MQConst.GoblinQueue.BIZ_ARTWORK_TRANS_QUERY.getKey(), artworkId);
                return ResponseDto.failure(String.format("藏品转赠结果查询数据不一致[artworkId:%s]", artworkId));
            }

            LocalDateTime nowDateTime = LocalDateTime.now();
            {// 转赠人藏品处理
                userDigitalArtworkVo.setTransferState(GoblinStatusConst.TransferState.SUCCESS.name());
                userDigitalArtworkVo.setDelFlg("1");
                userDigitalArtworkVo.setDeletedAt(nowDateTime);

                if (goblinMongoUtils.updateUserDigitalArtworkVoByTransQuery(userDigitalArtworkVo)) {// 转赠人藏品状态更新Mongo
                    if (6 == userDigitalArtworkVo.getSource()) {// 来源为转赠的藏品，设置过期时间到期删除
                        goblinRedisUtils.setexUserDigitalArtworkVo(userDigitalArtworkVo, 30 * 60);
                    } else {
                        goblinRedisUtils.setUserDigitalArtworkVo(userDigitalArtworkVo);// 转赠人藏品状态更新Redis
                    }
                    goblinRedisUtils.addSubUserDigitalArtworkCount(userDigitalArtworkVo.getUid(), -1);// 转赠人藏品数量处理Redis
                    goblinRedisUtils.resetUserDigitalArtworkIdsByMongo(userDigitalArtworkVo.getUid());// 转赠人藏品ID集合缓存重置Redis
                } else {
                    log.warn("#藏品转赠结果查询:更新转赠人藏品Mongo数据失败[artworkId={}]", userDigitalArtworkVo.getArtworkId());
                    queueUtils.sendMsgByRedis(MQConst.GoblinQueue.BIZ_ARTWORK_TRANS_QUERY.getKey(), artworkId);
                    return ResponseDto.failure(String.format("藏品转赠结果查询数据不一致[artworkId:%s]", artworkId));
                }
            }
            GoblinUserDigitalArtworkVo receiverDigitalArtworkVo = GoblinUserDigitalArtworkVo.getNew();
            {// 受赠人藏品处理
                String transferTime = queryRespDto.getTransferTime(), transferHash = queryRespDto.getTransferHash();
                receiverDigitalArtworkVo.setArtworkId(IDGenerator.nextSnowId());
                receiverDigitalArtworkVo.setUid(receiverUid);
                receiverDigitalArtworkVo.setSkuId(userDigitalArtworkVo.getSkuId());
                receiverDigitalArtworkVo.setOrderId(transferOrderId);
                receiverDigitalArtworkVo.setEditionSn(userDigitalArtworkVo.getEditionSn());
                receiverDigitalArtworkVo.setNftId(userDigitalArtworkVo.getNftId());
                //receiverDigitalArtworkVo.setReleaseTxhash();
                //receiverDigitalArtworkVo.setReleaseAt();
                receiverDigitalArtworkVo.setTradingTxhash(transferHash);
                receiverDigitalArtworkVo.setTradingAt(transferTime);
                //receiverDigitalArtworkVo.setReceiverUid();
                //receiverDigitalArtworkVo.setTransferOrderId();
                //receiverDigitalArtworkVo.setTransferState();
                receiverDigitalArtworkVo.setSource(6);
                receiverDigitalArtworkVo.setState(1);
                receiverDigitalArtworkVo.setDelFlg("0");
                //receiverDigitalArtworkVo.setOpeningAt();
                receiverDigitalArtworkVo.setCreatedAt(nowDateTime);
                //receiverDigitalArtworkVo.setUpdatedAt();
                receiverDigitalArtworkVo.setAuthor(userDigitalArtworkVo.getAuthor());
                receiverDigitalArtworkVo.setPublisher(userDigitalArtworkVo.getPublisher());

                goblinRedisUtils.setUserDigitalArtworkVo(receiverDigitalArtworkVo);// 受赠人藏品记录Redis
                goblinRedisUtils.addSubUserDigitalArtworkCount(receiverDigitalArtworkVo.getUid(), 1);// 受赠人藏品数量记录Redis
                goblinRedisUtils.addUserDigitalArtworkIds(receiverDigitalArtworkVo.getUid(), receiverDigitalArtworkVo.getArtworkId());// 受赠人藏品ID列表记录Redis
                goblinMongoUtils.insertUserDigitalArtworkVo(receiverDigitalArtworkVo);// 受赠人藏品记录Mongo

                // 受赠人受赠藏品列表缓存更新
                goblinRedisUtils.rmvUserDigitalArtworkIdsTransfer(userDigitalArtworkVo.getReceiverUid(), userDigitalArtworkVo.getArtworkId());
            }

            {// Mysql持久化
                LinkedList<String> toMqSqls = CollectionUtil.linkedListString();
                toMqSqls.add(SqlMapping.get("goblin_user_digital_artwork.up_transfer_chain"));
                LinkedList<Object[]> updateUserDigitalArtworkObjs = CollectionUtil.linkedListObjectArr();
                updateUserDigitalArtworkObjs.add(new Object[]{userDigitalArtworkVo.getTransferState(), userDigitalArtworkVo.getDeletedAt(), userDigitalArtworkVo.getArtworkId()});
                toMqSqls.add(SqlMapping.get("goblin_user_digital_artwork.in_transfer"));
                LinkedList<Object[]> initUserDigitalArtworkObjs = CollectionUtil.linkedListObjectArr();
                initUserDigitalArtworkObjs.add(new Object[]{receiverDigitalArtworkVo.getArtworkId(),
                        receiverDigitalArtworkVo.getUid(), receiverDigitalArtworkVo.getSkuId(), receiverDigitalArtworkVo.getOrderId(),
                        receiverDigitalArtworkVo.getEditionSn(), receiverDigitalArtworkVo.getNftId(), receiverDigitalArtworkVo.getTradingTxhash(),
                        receiverDigitalArtworkVo.getTradingAt(), receiverDigitalArtworkVo.getSource(), receiverDigitalArtworkVo.getState(),
                        receiverDigitalArtworkVo.getCreatedAt()});
                queueUtils.sendMsgByRedis(MQConst.GoblinQueue.SQL_ARTWORK_GEN.getKey(), SqlMapping.gets(toMqSqls, updateUserDigitalArtworkObjs, initUserDigitalArtworkObjs));
            }
        } catch (Exception e) {
            log.error("Ex.藏品转赠结果查询:处理异常[artworkId={}]", artworkId, e);
            queueUtils.sendMsgByRedis(MQConst.GoblinQueue.BIZ_ARTWORK_UPL.getKey(), artworkId);
            return ResponseDto.failure(String.format("藏品转赠结果查询异常[artworkId:%s]", artworkId));
        }
        return ResponseDto.success();
    }

    /* ------------------------------------------------------------------------------------ */
    /* ------------------------------------------------------------------------------------ */
    /* ------------------------------------------------------------------------------------ */
    /* ------------------------------------------------------------------------------------ */
    /* ------------------------------------------------------------------------------------ */

    private GalaxyNftTransferQueryRespDto queryNftTransferQueryRespDto(String transferOrderId, String routerType) {
        GalaxyNftTransferQueryReqDto requestDto = GalaxyNftTransferQueryReqDto.getNew();
        ResponseDto<GalaxyNftTransferQueryRespDto> responseDto = null;
        try {
            requestDto.setTransOrderId(transferOrderId);
            requestDto.setRouterType(routerType);
            responseDto = galaxyTradeService.nftTransferQuery(requestDto);
            if (!responseDto.isSuccess()) {
                log.warn("#藏品转赠结果查询:处理失败[paramsStr={},postRespStr={}]", JsonUtils.toJson(requestDto), JsonUtils.toJson(responseDto));
                return null;
            }
            return responseDto.getData();
        } catch (Exception e) {
            log.error("Ex.藏品转赠结果查询:处理异常[paramsStr={},postRespStr={}],ex:{}", JsonUtils.toJson(requestDto), JsonUtils.toJson(responseDto), e.getMessage());
            return null;
        }
    }
    /* ------------------------------------------------------------------------------------ */
    /* ------------------------------------------------------------------------------------ */
    /* ------------------------------------------------------------------------------------ */
}