package com.zanxiang.game.module.sdk.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.zanxiang.game.module.base.pojo.enums.BanStatusEnum;
import com.zanxiang.game.module.base.pojo.enums.DeleteEnum;
import com.zanxiang.game.module.mybatis.entity.*;
import com.zanxiang.game.module.sdk.constant.RedisKeyConstant;
import com.zanxiang.game.module.sdk.enums.CpPushDataEnum;
import com.zanxiang.game.module.sdk.enums.DeviceTypeEnum;
import com.zanxiang.game.module.sdk.enums.KafkaEventTrackEnum;
import com.zanxiang.game.module.sdk.pojo.dto.PlatformOrderDTO;
import com.zanxiang.game.module.sdk.pojo.param.*;
import com.zanxiang.game.module.sdk.pojo.vo.CpPushResultVO;
import com.zanxiang.game.module.sdk.pojo.vo.CpPushUserVO;
import com.zanxiang.game.module.sdk.service.*;
import com.zanxiang.game.module.sdk.util.RegisterUtil;
import com.zanxiang.module.redis.service.IDistributedLockComponent;
import com.zanxiang.module.util.JsonUtil;
import com.zanxiang.module.util.bean.BeanUtil;
import com.zanxiang.module.util.exception.BaseException;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.json.JSONObject;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import reactor.util.function.Tuple2;
import reactor.util.function.Tuple3;
import reactor.util.function.Tuples;

import java.time.LocalDateTime;
import java.util.Base64;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author : lingfeng
 * @time : 2024-06-20
 * @description : CP推送数据
 */
@Slf4j
@Service
public class CpPushDataServiceImpl implements ICpPushDataService {

    @Autowired
    private IGameExtService gameExtService;

    @Autowired
    private IUserService userService;

    @Autowired
    private IAgentService agentService;

    @Autowired
    private IGameService gameService;

    @Autowired
    private ICallBackService callBackService;

    @Autowired
    private IUserAgentLogService userAgentLogService;

    @Autowired
    private IKafkaService kafkaService;

    @Autowired
    private IGameUserService gameUserService;

    @Autowired
    private IUserShareService userShareService;

    @Autowired
    private IGameUserRoleService gameUserRoleService;

    @Autowired
    private IGameServerService gameServerService;

    @Autowired
    private IOrderService orderService;

    @Autowired
    private TransactionDefinition transactionDefinition;

    @Autowired
    private ICpPushErrorLogService cpPushErrorLogService;

    @Autowired
    private DataSourceTransactionManager dataSourceTransactionManager;

    @Autowired
    private IDistributedLockComponent distributedLockComponent;

    @Override
    public CpPushResultVO pushOrder(String gameAppId, CpPushOrderParam param) {
        //查询游戏
        Game game = this.getGameByGameAppId(gameAppId);
        //查询订单信息
        Order order = orderService.getOne(new LambdaQueryWrapper<Order>()
                .eq(Order::getGameId, game.getId())
                .eq(Order::getCpOrderId, param.getOrderId()));
        // 手动开启事务
        TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
        try {
            if (order == null) {
                order = this.createOrder(game, param);
            } else {
                order.setStatus(param.getStatus());
                order.setPayTime(param.getPayTime());
                order.setUpdateTime(LocalDateTime.now());
            }
            //订单更新或者保存
            orderService.saveOrUpdate(order);
            // 提交事务
            dataSourceTransactionManager.commit(transactionStatus);
        } catch (Exception e) {
            // 回滚事务
            dataSourceTransactionManager.rollback(transactionStatus);
            //保存错误日志
            cpPushErrorLogService.createLog(game.getId(), CpPushDataEnum.CP_PUSH_DATA_ORDER, param, e.getMessage());
            //抛出异常
            throw new BaseException(e.getMessage());
        }
        //订单回传
        callBackService.orderCallBack(BeanUtil.copy(order, PlatformOrderDTO.class));
        //判断订单行为
        if (Objects.equals(param.getStatus(), 2)) {
            //支付
            kafkaService.eventTrack(KafkaEventTrackEnum.KAFKA_EVENT_TRACK_ORDER_PAY, JsonUtil.toString(BeanUtil.copy(order, PlatformOrderDTO.class)));
        } else {
            //下单
            kafkaService.eventTrack(KafkaEventTrackEnum.KAFKA_EVENT_TRACK_ORDER_PAY, JsonUtil.toString(order));
        }
        //日志更新
        cpPushErrorLogService.errorLogUpdate(game.getId(), CpPushDataEnum.CP_PUSH_DATA_ORDER, param);
        //构造返回
        return CpPushResultVO.builder().result(Boolean.TRUE).build();
    }

    private Order createOrder(Game game, CpPushOrderParam param) {
        String lockKey = RedisKeyConstant.ORDER_CREATE_LOCK + param.getOpenId() + "_" + param.getOrderId();
        if (!distributedLockComponent.doLock(lockKey, 0L, 1L, TimeUnit.MINUTES)) {
            log.error("[订单推送]正在创建中, param : {}", JsonUtil.toString(param));
            throw new BaseException("接口调用订单正在创建中");
        }
        try {
            //查询玩家信息
            User user = userService.getOne(new LambdaQueryWrapper<User>()
                    .eq(User::getOpenId, param.getOpenId())
                    .eq(User::getGameId, game.getId()));
            if (user == null) {
                throw new BaseException("[订单推送]玩家信息不存在");
            }
            //玩家信息
            GameUser gameUser = gameUserService.getOne(new LambdaQueryWrapper<GameUser>()
                    .eq(GameUser::getUserId, user.getId()));
            if (gameUser == null) {
                throw new BaseException("[订单推送]游戏玩家信息不存在");
            }
            //角色信息
            GameUserRole gameUserRole = gameUserRoleService.getOne(new LambdaQueryWrapper<GameUserRole>()
                    .eq(GameUserRole::getGameId, game.getId())
                    .eq(GameUserRole::getUserId, user.getId())
                    .eq(GameUserRole::getRoleId, param.getRoleId()));
            if (gameUserRole == null) {
                throw new BaseException("[订单推送]角色信息不存在");
            }
            //构造订单
            return this.transform(game, param, user, gameUser, gameUserRole);
        } catch (Exception e) {
            log.error("[订单推送]订单创建出现异常, game : {}, param : {}, e : {}", JsonUtil.toString(game), JsonUtil.toString(param), e.getMessage(), e);
            throw new BaseException("[订单推送]订单创建出现异常!");
        } finally {
            RLock rLock = distributedLockComponent.getLock(lockKey);
            if (rLock != null) {
                distributedLockComponent.unlock(lockKey);
            }
        }
    }

    private Order transform(Game game, CpPushOrderParam param, User user, GameUser gameUser, GameUserRole gameUserRole) {
        return Order.builder()
                .orderId(orderService.getOrderNum(user.getId()))
                .cpOrderId(param.getOrderId())
                .agentId(user.getAgentId())
                .cpId(game.getCpId())
                .userId(user.getId())
                .mgUserId(gameUser.getId())
                .regTime(user.getCreateTime())
                .gameId(game.getId())
                .roleId(gameUserRole.getRoleId())
                .roleName(gameUserRole.getRoleName())
                .roleLevel(gameUserRole.getRoleLevel())
                .roleVipLevel(gameUserRole.getRoleVipLevel())
                .serverId(gameUserRole.getServerId())
                .serverName(gameUserRole.getServerName())
                .amount(param.getAmount())
                .realAmount(param.getStatus() == 2 ? param.getAmount() : null)
                .productId(param.getProductId())
                .productName(param.getProductName())
                .deviceSystem(user.getDeviceSystem())
                .payWayId(0L)
                .payDeviceId(0L)
                .gamePayWayId(0L)
                .ext(param.getExtension())
                .status(param.getStatus())
                .payTime(param.getPayTime())
                .createTime(param.getCreateTime())
                .updateTime(LocalDateTime.now())
                .build();
    }

    @Override
    public CpPushResultVO pushActive(String gameAppId, CpPushActiveParam param) {
        //查询游戏
        Game game = this.getGameByGameAppId(gameAppId);
        try {
            //查询玩家信息
            User user = userService.getOne(new LambdaQueryWrapper<User>()
                    .eq(User::getOpenId, param.getOpenId())
                    .eq(User::getGameId, game.getId()));
            if (user == null) {
                throw new BaseException("[活跃推送]角色信息不存在");
            }
            //查询角色信息
            GameUserRole gameUserRole = gameUserRoleService.getOne(new LambdaQueryWrapper<GameUserRole>()
                    .eq(GameUserRole::getUserId, user.getId())
                    .eq(GameUserRole::getGameId, game.getId())
                    .eq(GameUserRole::getServerId, param.getServerId())
                    .eq(GameUserRole::getRoleId, param.getRoleId())
                    .orderByDesc(GameUserRole::getCreateTime)
                    .last("limit 1"));
            if (gameUserRole == null) {
                throw new BaseException("[活跃推送]角色信息不存在");
            }
            //角色活跃信息上报到卡夫卡
            kafkaService.roleActiveTrack(gameUserRole, param.getActiveType());
        } catch (Exception e) {
            //保存错误日志
            cpPushErrorLogService.createLog(game.getId(), CpPushDataEnum.CP_PUSH_DATA_ACTIVE, param, e.getMessage());
            //抛出异常
            throw new BaseException(e.getMessage());
        }
        //日志更新
        cpPushErrorLogService.errorLogUpdate(game.getId(), CpPushDataEnum.CP_PUSH_DATA_ACTIVE, param);
        //构造返回
        return CpPushResultVO.builder().result(Boolean.TRUE).build();
    }

    @Override
    public CpPushResultVO pushServer(String gameAppId, CpPushServerParam param) {
        //查询游戏
        Game game = this.getGameByGameAppId(gameAppId);
        boolean result;
        // 手动开启事务
        TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
        try {
            //查询区服id
            GameServer gameServer = gameServerService.getOne(new LambdaQueryWrapper<GameServer>()
                    .eq(GameServer::getGameId, game.getSuperGameId())
                    .eq(GameServer::getServerId, param.getServerId())
            );
            GameServer transform = this.transform(game.getSuperGameId(), param);
            if (gameServer == null) {
                gameServer = transform;
            } else {
                gameServer.setGameId(transform.getGameId());
                gameServer.setServerId(transform.getServerId());
                gameServer.setServerName(transform.getServerName());
                gameServer.setNickName(transform.getNickName());
                gameServer.setStartTime(transform.getStartTime());
                gameServer.setUpdateTime(LocalDateTime.now());
            }
            //区服添加或者更新
            result = gameServerService.saveOrUpdate(gameServer);
            //提交事务
            dataSourceTransactionManager.commit(transactionStatus);
        } catch (Exception e) {
            //回滚事务
            dataSourceTransactionManager.rollback(transactionStatus);
            //保存错误日志
            cpPushErrorLogService.createLog(game.getId(), CpPushDataEnum.CP_PUSH_DATA_SERVER, param, e.getMessage());
            //抛出异常
            throw new BaseException(e.getMessage());
        }
        //日志更新
        cpPushErrorLogService.errorLogUpdate(game.getId(), CpPushDataEnum.CP_PUSH_DATA_SERVER, param);
        //构造返回
        return CpPushResultVO.builder().result(result).build();
    }

    private GameServer transform(Long superGameId, CpPushServerParam param) {
        return GameServer.builder()
                .gameId(superGameId)
                .serverId(param.getServerId())
                .serverName(param.getServerName())
                .nickName(param.getNickName())
                .startTime(param.getStartTime())
                .isDelete(DeleteEnum.NO.getCode())
                .createBy(0L)
                .createTime(LocalDateTime.now())
                .isSourceServer(Boolean.TRUE)
                .isMerge(Boolean.FALSE)
                .updateBy(0L)
                .updateTime(LocalDateTime.now())
                .build();
    }

    @Override
    public CpPushResultVO pushRole(String gameAppId, CpPushRoleParam param) {
        //查询游戏
        Game game = this.getGameByGameAppId(gameAppId);
        boolean result;
        // 手动开启事务
        TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
        try {
            //查询玩家信息
            User user = userService.getOne(new LambdaQueryWrapper<User>()
                    .eq(User::getGameId, game.getId())
                    .eq(User::getOpenId, param.getOpenId()));
            if (user == null) {
                throw new BaseException("[角色推送]玩家信息不存在");
            }
            //查询玩家角色信息
            GameUserRole gameUserRole = gameUserRoleService.getOne(new LambdaQueryWrapper<GameUserRole>()
                    .eq(GameUserRole::getUserId, user.getId())
                    .eq(GameUserRole::getGameId, user.getGameId())
                    .eq(GameUserRole::getRoleId, param.getRoleId()));
            if (gameUserRole == null) {
                result = this.gameRoleCreate(param, user);
            } else {
                result = this.gameRoleUpdate(param, gameUserRole, user);
            }
            // 提交事务
            dataSourceTransactionManager.commit(transactionStatus);
        } catch (Exception e) {
            // 回滚事务
            dataSourceTransactionManager.rollback(transactionStatus);
            //保存错误日志
            cpPushErrorLogService.createLog(game.getId(), CpPushDataEnum.CP_PUSH_DATA_ROLE, param, e.getMessage());
            //抛出异常
            throw new BaseException(e.getMessage());
        }
        //日志更新
        cpPushErrorLogService.errorLogUpdate(game.getId(), CpPushDataEnum.CP_PUSH_DATA_ROLE, param);
        //构造返回
        return CpPushResultVO.builder().result(result).build();
    }

    private boolean gameRoleCreate(CpPushRoleParam param, User user) {
        GameUser gameUser = gameUserService.getOne(new LambdaQueryWrapper<GameUser>()
                .select(GameUser::getId)
                .eq(GameUser::getGameId, user.getGameId())
                .eq(GameUser::getUserId, user.getId()));
        if (gameUser == null) {
            throw new BaseException("[角色推送]游戏玩家信息不存在");
        }
        //上锁
        if (!distributedLockComponent.doLock(RedisKeyConstant.ROLE_CREATE_LOCK + user.getGameId() + "_" + param.getRoleId(),
                0L, 1L, TimeUnit.MINUTES)) {
            log.error("[角色推送]角色正在创建中, param : {}, user : {}", JsonUtil.toString(param), JsonUtil.toString(user));
            return Boolean.TRUE;
        }
        //创建角色
        GameUserRole userRole = this.transform(param, gameUser, user);
        boolean result = gameUserRoleService.save(userRole);
        //更新用户创角数
        userService.update(new LambdaUpdateWrapper<User>()
                .setSql("role_count=role_count+" + 1)
                .set(User::getUpdateTime, LocalDateTime.now())
                .eq(User::getId, user.getId()));
        //更新玩家创角数
        gameUserService.update(new LambdaUpdateWrapper<GameUser>()
                .setSql("role_count=role_count+" + 1)
                .set(GameUser::getUpdateTime, LocalDateTime.now())
                .eq(GameUser::getId, gameUser.getId()));
        //用户创角回传
        callBackService.roleCallBack(userRole);
        //用户创角埋点数据发送到卡夫卡
        kafkaService.eventTrack(KafkaEventTrackEnum.KAFKA_EVENT_TRACK_ROLE_CREATE, JsonUtil.toString(userRole));
        return result;
    }

    private boolean gameRoleUpdate(CpPushRoleParam param, GameUserRole gameUserRole, User user) {
        //更新频率限制, 20秒更新一次, 避免游戏实时战力高频上报
        if (!distributedLockComponent.doLock(RedisKeyConstant.ROLE_LEVEL_UP + user.getGameId() + "_" + param.getRoleId(),
                0L, 20L, TimeUnit.SECONDS)) {
            return Boolean.TRUE;
        }
        //判断是否等级变更
        boolean updateRoleLevel = gameUserRole.getRoleLevel() != null && param.getRoleLevel() > gameUserRole.getRoleLevel();
        //玩家角色信息更新
        if (param.getExtra() != null && Strings.isNotBlank(JsonUtil.toString(param.getExtra()))) {
            gameUserRole.setExtra(JsonUtil.toString(param.getExtra()));
        }
        if (gameUserRole.getServerId() == null) {
            gameUserRole.setServerId(param.getServerId());
        }
        if (param.getRolePower() != null) {
            gameUserRole.setRolePower(param.getRolePower());
        }
        if (param.getRoleVipLevel() != null) {
            gameUserRole.setRoleVipLevel(param.getRoleVipLevel());
        }
        gameUserRole.setRoleName(param.getRoleName());
        gameUserRole.setRoleLevel(param.getRoleLevel());
        gameUserRole.setServerName(param.getServerName());
        gameUserRole.setUpdateTime(LocalDateTime.now());
        boolean result = gameUserRoleService.updateById(gameUserRole);
        //等级更新, 创角回传
        if (updateRoleLevel) {
            callBackService.roleCallBack(gameUserRole);
        }
        //角色更新数据埋点发送到卡夫卡
        kafkaService.eventTrack(KafkaEventTrackEnum.KAFKA_EVENT_TRACK_ROLE_UPDATE, JsonUtil.toString(gameUserRole));
        return result;
    }

    private GameUserRole transform(CpPushRoleParam param, GameUser gameUser, User user) {
        String extraJson = JsonUtil.toString(param.getExtra());
        return GameUserRole.builder()
                .userId(user.getId())
                .gameUserId(gameUser.getId())
                .gameId(user.getGameId())
                .serverId(param.getServerId())
                .serverName(param.getServerName())
                .roleId(param.getRoleId())
                .roleName(param.getRoleName())
                .roleLevel(param.getRoleLevel())
                .roleVipLevel(param.getRoleVipLevel())
                .rolePower(param.getRolePower())
                .os(user.getDeviceSystem())
                .regTime(user.getCreateTime())
                .createTime(param.getCreateTime())
                .updateTime(LocalDateTime.now())
                .lastLoginTime(LocalDateTime.now())
                .extra(param.getExtra() == null || Strings.isBlank(extraJson) ? null : extraJson)
                .build();
    }

    @Override
    public CpPushUserVO pushUser(String gameAppId, CpPushUserParam param) {
        //查询游戏
        Game game = this.getGameByGameAppId(gameAppId);
        //结果信息
        CpPushUserVO cpPushUserVO;
        // 手动开启事务
        TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
        try {
            //中间数据
            UserData userData = UserData.builder().gameId(game.getId()).channel(param.getChannel()).ip(param.getIp()).ua(param.getUa()).build();
            //根据openId查询用户
            User user = userService.getOne(new LambdaQueryWrapper<User>()
                    .eq(User::getGameId, game.getId())
                    .eq(User::getOpenId, param.getOpenId()));
            //玩家信息不存在
            if (user == null) {
                cpPushUserVO = this.createUser(game, userData, param);
            } else {
                //玩家信息更新
                Map<String, String> channelMap = this.updateUser(user, param, game, userData);
                cpPushUserVO = CpPushUserVO.builder().userId(user.getId())
                        .sdkUser(!Objects.equals(user.getAgentId(), Agent.DEFAULT_AGENT))
                        .channel(JsonUtil.toString(channelMap))
                        .build();
            }
            // 提交事务
            dataSourceTransactionManager.commit(transactionStatus);
        } catch (Exception e) {
            // 回滚事务
            dataSourceTransactionManager.rollback(transactionStatus);
            //保存错误日志
            cpPushErrorLogService.createLog(game.getId(), CpPushDataEnum.CP_PUSH_DATA_USER, param, e.getMessage());
            //抛出异常
            throw new BaseException(e.getMessage());
        }
        //日志更新
        cpPushErrorLogService.errorLogUpdate(game.getId(), CpPushDataEnum.CP_PUSH_DATA_USER, param);
        //返回结果
        return cpPushUserVO;
    }

    private CpPushUserVO createUser(Game game, UserData userData, CpPushUserParam param) {
        //游戏id
        Long gameId = game.getId();
        //线程锁Key
        String lockKey = RedisKeyConstant.USER_CREATE + gameId + "_" + param.getOpenId();
        //上锁
        if (!distributedLockComponent.doLock(lockKey, 0L, 3L, TimeUnit.MINUTES)) {
            log.error("[用户推送]用户正在创建中, param : {}, game : {}", JsonUtil.toString(param), JsonUtil.toString(game));
            throw new BaseException("[用户推送]用户正在创建中");
        }
        //玩家信息
        User user;
        //渠道map
        Map<String, String> channelMap = null;
        try {
            //判断是否分享玩家
            if (Strings.isNotBlank(param.getShareOpenId())) {
                User shareUser = userService.getOne(new LambdaQueryWrapper<User>()
                        .eq(User::getGameId, gameId)
                        .eq(User::getOpenId, param.getShareOpenId())
                        .last("limit 1"));
                user = this.transform(gameId, shareUser, param);
            } else {
                Tuple3<Long, Map<String, String>, String> tuple3 = this.getUserAgentChannel(game, userData, param.getOpenId());
                user = this.transform(gameId, tuple3, param);
                channelMap = tuple3.getT2();
            }
            userService.save(user);
            gameUserService.createGameUser(user);
            userAgentLogService.regAgentLog(user);
            //非分享用户, 回传注册
            if (Strings.isBlank(param.getShareOpenId())) {
                callBackService.userCallBack(user, channelMap);
            } else {
                //记录分享信息, 用户不回传
                userShareService.createShareLog(user, userData);
            }
            //注册信息埋点数据发送到卡夫卡
            kafkaService.eventTrack(KafkaEventTrackEnum.KAFKA_EVENT_TRACK_REG, JsonUtil.toString(user));
            //返回构造数据
            return CpPushUserVO.builder().userId(user.getId())
                    .sdkUser(!Objects.equals(user.getAgentId(), Agent.DEFAULT_AGENT))
                    .channel(JsonUtil.toString(channelMap))
                    .build();
        } catch (Exception e) {
            log.error("[用户推送]用户创建出现异常, gameId : {}, param : {}, e : {}", gameId, JsonUtil.toString(param), e.getMessage(), e);
            throw new BaseException("[用户推送]用户创建出现异常");
        } finally {
            RLock rLock = distributedLockComponent.getLock(lockKey);
            if (rLock != null) {
                distributedLockComponent.unlock(lockKey);
            }
        }
    }

    private Map<String, String> updateUser(User user, CpPushUserParam param, Game game, UserData userData) {
        //活跃间隔时长
        long inactiveDay = 15L;
        //判定不活跃时长是否达到限制
        if (param.getActiveTime().plusDays(inactiveDay).isAfter(LocalDateTime.now())) {
            return Collections.emptyMap();
        }
        //渠道id, 链接参数
        Tuple3<Long, Map<String, String>, String> tuple3 = this.getUserAgentChannel(game, userData, param.getOpenId());
        //查询渠道
        Agent agent = agentService.getById(tuple3.getT1());
        if (agent == null) {
            return Collections.emptyMap();
        }
        //保存旧的渠道信息
        Tuple3<Long, Long, String> oldAgentChannel = Tuples.of(user.getId(), user.getAgentId(), user.getChannel());
        //更新用户信息
        user.setAgentId(agent.getId());
        user.setChannel(userData.getChannel());
        user.setUpdateTime(LocalDateTime.now());
        userService.updateById(user);
        //添加渠道变更记录
        userAgentLogService.agentUpdateLog(oldAgentChannel, agent.getId(), userData.getChannel());
        //回传用户信息
        callBackService.userCallBack(user, tuple3.getT2());
        //渠道变更信息埋点数据发送到卡夫卡
        kafkaService.eventTrack(KafkaEventTrackEnum.KAFKA_EVENT_TRACK_AGENT_UPDATE, JsonUtil.toString(user));
        //返回更新的渠道信息
        return tuple3.getT2();
    }

    private Tuple3<Long, Map<String, String>, String> getUserAgentChannel(Game game, UserData userData, String openId) {
        //解析渠道信息
        String channel = new String(Base64.getDecoder().decode(userData.getChannel()));
        userData.setChannel(channel);
        //没有携带渠道标识, 无法解析渠道信息, 判定为自然量
        if (!channel.contains("agentKey") && !channel.contains("state")) {
            return Tuples.of(0L, Collections.emptyMap(), channel);
        }
        Tuple2<Boolean, Boolean> jsonAndEmpty = this.isJsonAndEmpty(channel);
        //channel渠道信息非json格式, 或者是空json
        if (!jsonAndEmpty.getT1() || jsonAndEmpty.getT2()) {
            //返回自然量渠道
            return Tuples.of(0L, Collections.emptyMap(), channel);
        }
        //渠道id, 链接参数, 分享人id
        Tuple3<Long, Map<String, String>, String> tuple3 = agentService.getUserAgentId(game, userData, openId);
        //返回渠道id, 渠道参数
        return Tuples.of(tuple3.getT1(), tuple3.getT2(), channel);
    }

    private User transform(Long gameId, User shareUser, CpPushUserParam param) {
        return User.builder()
                .openId(param.getOpenId())
                .regAgentId(shareUser.getRegAgentId())
                .agentId(shareUser.getAgentId())
                .channel(shareUser.getChannel())
                .gameId(gameId)
                .username(param.getOpenId())
                .nickname(RegisterUtil.randomNickName(param.getOpenId()))
                .deviceType(DeviceTypeEnum.DEVICE_TYPE_MINI_APP.getDeviceType())
                .status(BanStatusEnum.NORMAL_STATUS.getStatus())
                .authentication(0)
                .createTime(param.getRegTime())
                .updateTime(LocalDateTime.now())
                .deviceSystem(param.getOs())
                .ip(param.getIp())
                .shareUserId(shareUser.getId())
                .build();
    }

    private User transform(Long gameId, Tuple3<Long, Map<String, String>, String> tuple3, CpPushUserParam param) {
        return User.builder()
                .openId(param.getOpenId())
                .regAgentId(tuple3.getT1())
                .agentId(tuple3.getT1())
                .channel(tuple3.getT2().isEmpty() ? tuple3.getT3() : JsonUtil.toString(tuple3.getT2()))
                .gameId(gameId)
                .username(param.getOpenId())
                .nickname(RegisterUtil.randomNickName(param.getOpenId()))
                .deviceType(DeviceTypeEnum.DEVICE_TYPE_MINI_APP.getDeviceType())
                .status(BanStatusEnum.NORMAL_STATUS.getStatus())
                .authentication(0)
                .createTime(param.getRegTime())
                .updateTime(LocalDateTime.now())
                .deviceSystem(param.getOs())
                .ip(param.getIp())
                .build();
    }

    private Tuple2<Boolean, Boolean> isJsonAndEmpty(String str) {
        try {
            JSONObject jsonObject = new JSONObject(str);
            return Tuples.of(Boolean.TRUE, jsonObject.keySet().isEmpty());
        } catch (Exception e) {
            return Tuples.of(Boolean.FALSE, Boolean.FALSE);
        }
    }

    private Game getGameByGameAppId(String gameAppId) {
        //游戏拓展信息
        GameExt gameExt = gameExtService.getByGameAppId(gameAppId);
        if (gameExt == null) {
            log.error("参数错误, 游戏拓展信息配置不存在, gameAppId : {}", gameAppId);
            throw new BaseException("参数错误, 游戏拓展信息配置不存在");
        }
        //查询游戏
        Game game = gameService.getById(gameExt.getGameId());
        if (game == null) {
            log.error("参数错误, 游戏配置不存在, gameAppId : {}", gameAppId);
            throw new BaseException("参数错误, 游戏配置不存在");
        }
        return game;
    }
}
