package com.ff.game.api.jili.service.impl;

import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson2.JSON;
import com.ff.base.constant.CacheConstants;
import com.ff.base.constant.Constants;
import com.ff.base.core.redis.RedisCache;
import com.ff.base.enums.FreeStatus;
import com.ff.base.enums.GamePlatforms;
import com.ff.base.enums.GameStatus;
import com.ff.base.enums.JILIGameType;
import com.ff.base.exception.base.BaseException;
import com.ff.base.system.service.ISysConfigService;
import com.ff.base.utils.DateUtils;
import com.ff.base.utils.JsonUtil;
import com.ff.base.utils.MessageUtils;
import com.ff.base.utils.StringUtils;
import com.ff.base.utils.http.HttpClientSslUtils;
import com.ff.base.utils.http.HttpUtils;
import com.ff.base.utils.sign.Md5Utils;
import com.ff.base.utils.uuid.IdUtils;
import com.ff.game.api.IGamesService;
import com.ff.game.api.jili.client.JILIClient;
import com.ff.game.api.jili.dto.*;
import com.ff.game.api.request.*;
import com.ff.game.domain.*;
import com.ff.game.service.*;
import com.ff.member.domain.Member;
import com.ff.member.service.IMemberService;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.entity.ContentType;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


/**
 * 游戏数据解析服务
 *
 * @author shi
 * @date 2024/10/21
 */
@Service("JILIService")
@Slf4j
public class GamesJILIServiceImpl implements IGamesService {


    @Resource
    private ISysConfigService configService;

    @Resource
    private RedisCache redisCache;

    @Resource
    private IGameExchangeMoneyService gameExchangeMoneyService;


    @Resource
    private IGamePlatformService gamePlatformService;


    @Resource
    private IGameService gameService;


    @Resource
    private IMemberService memberService;

    @Resource
    private IGameFreeRecordService gameFreeRecordService;

    @Resource
    private IGameSecretKeyService gameSecretKeyService;

    @Resource
    private JILIClient jiliClient;

    /**
     * 获得就是成功
     *
     * @param errorCode 错误代码
     * @return {@link Boolean }
     */
    private Boolean getIsSuccess(Integer errorCode) {
        return 0 == errorCode;
    }


    /**
     * 获取密钥
     *
     * @param gamesBaseRequestDTO 游戏请求dto
     * @return {@link String }
     */
    @Override
    public String getKey(GamesBaseRequestDTO gamesBaseRequestDTO) {
        Random random = new Random();
        //取出对应的key跟密钥跟请求参数
        String agentKey = gamesBaseRequestDTO.getAgentKey();
        String agentId = gamesBaseRequestDTO.getAgentId();
        String query = gamesBaseRequestDTO.getQuery();

        String now = DateUtils.getFormattedDate();
        String keyG = Md5Utils.md5New(now + agentId + agentKey);

        String md5string = Md5Utils.md5New(query + keyG);
        Integer randomText1 = 100000 + random.nextInt(900000);
        Integer randomText2 = 100000 + random.nextInt(900000);
        String key = randomText1 + md5string + randomText2;
        return key;
    }

    /**
     * 创建成员
     *
     * @param createMemberRequestDTO 创建成员请求dto
     * @return {@link Boolean }
     */
    @Override
    public Boolean createMember(CreateMemberRequestDTO createMemberRequestDTO) {
        String query = "Account=" + createMemberRequestDTO.getAccount() + "&AgentId=" + createMemberRequestDTO.getAgentId();
        log.info("GamesJILIServiceImpl [createMember] 请求参数 {}", query);
        createMemberRequestDTO.setQuery(query);
        String key = this.getKey(createMemberRequestDTO);
        JILICreateMemberResponseDTO createMemberResponseDTO = jiliClient.createMember(query + "&Key=" + key);
        Boolean isSuccess = this.getIsSuccess(createMemberResponseDTO.getErrorCode());
        if (!isSuccess) {
            throw new BaseException(createMemberResponseDTO.getMessage());
        }
        //判断是否获取成功
        return isSuccess;
    }


    /**
     * 获取会员信息
     *
     * @param memberInfoRequestDTO 会员信息请求dto
     * @return {@link MemberInfoResponseDTO }
     */
    @Override
    public MemberInfoResponseDTO getMemberInfo(MemberInfoRequestDTO memberInfoRequestDTO) {
        String query = "Accounts=" + memberInfoRequestDTO.getAccounts() + "&AgentId=" + memberInfoRequestDTO.getAgentId();
        log.info("GamesJILIServiceImpl [getMemberInfo] 请求参数 {}", query);
        memberInfoRequestDTO.setQuery(query);
        String key = this.getKey(memberInfoRequestDTO);
        JILIMemberInfoDTO jiliMemberInfoDTO = jiliClient.getMemberInfo(query + "&Key=" + key);
        //判断是否获取成功
        if (this.getIsSuccess(jiliMemberInfoDTO.getErrorCode())) {
            List<MemberInfoResponseDTO> memberInfoResponseDTOS = new ArrayList<>();
            jiliMemberInfoDTO.getData().forEach(e -> {
                memberInfoResponseDTOS.add(MemberInfoResponseDTO.builder()
                        .status(e.getStatus())
                        .balance(e.getBalance())
                        .account(e.getAccount())
                        .build());
            });
            return memberInfoResponseDTOS.get(0);
        } else {
            throw new BaseException(jiliMemberInfoDTO.getMessage());
        }
    }

    /**
     * 无重定向登录
     *
     * @param gamesLogin 游戏登录
     * @return {@link String }
     */
    @Override
    public String loginWithoutRedirect(GamesLogin gamesLogin) {
        String query = "Account=" + gamesLogin.getAccount() + "&GameId=" + gamesLogin.getGameId() + "&Lang=" + gamesLogin.getLang() + "&AgentId=" + gamesLogin.getAgentId();
        log.info("GamesJILIServiceImpl [loginWithoutRedirect] 请求参数 {}", query);
        gamesLogin.setQuery(query);
        String key = this.getKey(gamesLogin);

//            if (!StringUtils.isEmpty(gamesLogin.getHomeUrl())) {
//                query += "&HomeUrl=" + gamesLogin.getHomeUrl();
//            }
        if (!StringUtils.isEmpty(gamesLogin.getPlatform())) {
            query += "&platform=" + gamesLogin.getPlatform();
        }
        if (!ObjectUtils.isEmpty(gamesLogin.getDisableFullScreen())) {
            query += "&disableFullScreen=" + gamesLogin.getDisableFullScreen();
        }

        JILILoginWithoutRedirectResponseDTO loginWithoutRedirectResponseDTO = jiliClient.loginWithoutRedirect(query + "&AgentId=" + gamesLogin.getAgentId() + "&Key=" + key);
        //判断是否获取成功
        if (this.getIsSuccess(loginWithoutRedirectResponseDTO.getErrorCode())) {
            return loginWithoutRedirectResponseDTO.getData();
        } else {
            throw new BaseException(loginWithoutRedirectResponseDTO.getMessage());
        }

    }


    /**
     * 获取游戏列表
     *
     * @param gamesBaseRequestDTO 游戏请求dto
     * @return {@link String }
     */
    @Transactional
    @Override
    public String getGameList(GamesBaseRequestDTO gamesBaseRequestDTO) {

        List<JILIGamesDataDTO> gamesDatas = redisCache.getCacheList(CacheConstants.JILI_GAMES);
        if (!CollectionUtils.isEmpty(gamesDatas)) {
            return CacheConstants.JILI_GAMES;
        }


        gamesBaseRequestDTO.setQuery("AgentId=" + gamesBaseRequestDTO.getAgentId());
        String key = this.getKey(gamesBaseRequestDTO);
        JILIGamesDTO jiliGames = jiliClient.getGameList("AgentId=" + gamesBaseRequestDTO.getAgentId() + "&Key=" + key);
        //判断是否获取成功
        if (this.getIsSuccess(jiliGames.getErrorCode())) {

            for (JILIGamesDataDTO gamesDataDTO : jiliGames.getData()) {
                if (JILIGameType.GAME_HALL.getCode().equals(gamesDataDTO.getGameCategoryId())) {
                    continue;
                }

                GamePlatform gamePlatform = GamePlatform.builder()
                        .platformType(JILIGameType.findSystemByCode(gamesDataDTO.getGameCategoryId()))
                        .platformCode(GamePlatforms.JILI.getCode())
                        .build();
                List<GamePlatform> gamePlatforms = gamePlatformService.selectGamePlatformList(gamePlatform);
                //没有此平台就新增一个平台
                if (CollectionUtils.isEmpty(gamePlatforms)) {
                    gamePlatform.setPlatformName(GamePlatforms.JILI.getInfo() + JILIGameType.findInfoByCode(gamesDataDTO.getGameCategoryId()));
                    gamePlatform.setSortNo(gamePlatformService.selectMaxSortNo() + 1);
                    gamePlatform.setCreateBy(Constants.SYSTEM);
                    gamePlatformService.insertGamePlatform(gamePlatform);
                } else {
                    gamePlatform = gamePlatforms.get(0);
                }
                Game game = Game.builder()
                        .platformId(gamePlatform.getId())
                        .gameCode(gamesDataDTO.getGameId())
                        .build();
                List<Game> games = gameService.selectGameList(game);
                //不存在这个游戏
                if (CollectionUtils.isEmpty(games)) {
                    game.setFreespin(gamesDataDTO.isFreespin());
                    game.setSortNo(gameService.selectMaxSortNoByPlatformId(gamePlatform.getId()) + 1);
                    game.setGameName(gamesDataDTO.getName().getZhCN());
                    game.setCreateBy(Constants.SYSTEM);
                    gameService.insertGame(game);
                } else {
                    game = games.get(0);
                }
                gamesDataDTO.setSystemGameId(game.getId());


            }

            redisCache.deleteObject(CacheConstants.JILI_GAMES);
            redisCache.setCacheList(CacheConstants.JILI_GAMES, jiliGames.getData());
            redisCache.expire(CacheConstants.JILI_GAMES, 5L, TimeUnit.HOURS);
        } else {
            log.error("GameBettingDataJILIServiceImpl [getGameList] 获取游戏列表失败,错误代码{},错误信息{}", jiliGames.getErrorCode(), jiliGames.getMessage());
            throw new BaseException(MessageUtils.message("game.list.retrieve.failed"));

        }

        return CacheConstants.JILI_GAMES;
    }

    /**
     * 按代理id进行交换转账
     *
     * @param exchangeTransferMoneyRequestDTO 外汇转账moeny dto
     * @return {@link Long }
     */
    @Override
    @Transactional
    public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO) {
        String systemByCode = gameSecretKeyService.findSystemByCode(exchangeTransferMoneyRequestDTO.getAgentId(), GamePlatforms.JILI.getInfo());
        Member member = memberService.selectMemberByMemberAccount(exchangeTransferMoneyRequestDTO.getAccount());
        String transactionId = exchangeTransferMoneyRequestDTO.getTransactionId();
        //如果没有自定义单号
        if (!StringUtils.hasText(exchangeTransferMoneyRequestDTO.getTransactionId())) {
            transactionId = GamePlatforms.JILI.getCode() + IdUtils.simpleUUID();
        }

        //获取下一个自增id
        GameExchangeMoney exchangeMoney = GameExchangeMoney
                .builder()
                .quota(exchangeTransferMoneyRequestDTO.getQuota())
                .platformId(exchangeTransferMoneyRequestDTO.getPlatformId())
                .balance(exchangeTransferMoneyRequestDTO.getAmount())
                .exchangeType(exchangeTransferMoneyRequestDTO.getTransferType())
                .currencyCode(systemByCode)
                .memberId(member.getId())
                .platformCode(GamePlatforms.JILI.getCode())
                .build();
        exchangeMoney.setCreateBy(Constants.SYSTEM);
        //接口限制限制50字符
        exchangeMoney.setTransactionId(transactionId);
        String query = "Account=" + exchangeTransferMoneyRequestDTO.getAccount()
                + "&TransactionId=" + exchangeMoney.getTransactionId()
                + "&Amount=" + exchangeTransferMoneyRequestDTO.getAmount()
                + "&TransferType=" + exchangeTransferMoneyRequestDTO.getTransferType()
                + "&AgentId=" + exchangeTransferMoneyRequestDTO.getAgentId();
        log.info("GamesJILIServiceImpl [exchangeTransferByAgentId] 请求参数 {}", query);
        exchangeTransferMoneyRequestDTO.setQuery(query);

        String key = this.getKey(exchangeTransferMoneyRequestDTO);
        String apiBaseUrl = configService.selectConfigByKey(Constants.JILI_API_BASE_URL);
        try {
            String result = HttpClientSslUtils.doPost(apiBaseUrl + "/ExchangeTransferByAgentId?" + query + "&Key=" + key, "AgentId=" + exchangeTransferMoneyRequestDTO.getAgentId(), ContentType.APPLICATION_FORM_URLENCODED);

            JILIExchangeMoneyResponseDTO exchangeMoneyResponse = JsonUtil.stringToObj(result, JILIExchangeMoneyResponseDTO.class);
            //判断是否转移成功
            if (this.getIsSuccess(exchangeMoneyResponse.getErrorCode())) {
                JILIExchangeMoneyResponseDTO.BeanData exchangeMoneyResponseData = exchangeMoneyResponse.getData();
                //更新数据
                exchangeMoney.setBalance(NumberUtil.sub(exchangeMoneyResponseData.getCurrencyAfter(), exchangeMoneyResponseData.getCurrencyBefore()).abs());
                exchangeMoney.setCoinBefore(exchangeMoneyResponseData.getCoinBefore());
                exchangeMoney.setCoinAfter(exchangeMoneyResponseData.getCoinAfter());
                exchangeMoney.setCurrencyBefore(exchangeMoneyResponseData.getCurrencyBefore());
                exchangeMoney.setCurrencyAfter(exchangeMoneyResponseData.getCurrencyAfter());
                exchangeMoney.setStatus(exchangeMoneyResponseData.getStatus());
                gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney);
            } else {
                log.error("GameBettingDataJILIServiceImpl [exchangeTransferByAgentId] 金额转移失败,错误代码{},错误信息{}", exchangeMoneyResponse.getErrorCode(), exchangeMoneyResponse.getMessage());
                throw new BaseException(MessageUtils.message("game.account.balance.transfer.failed"));

            }
        } catch (Exception e) {
            log.error("GameBettingDataJILIServiceImpl [exchangeTransferByAgentId] 金额转移失败,错误信息{}", e);
            throw new BaseException(MessageUtils.message("game.account.balance.transfer.failed"));

        }

        return exchangeMoney.getId();
    }


    /**
     * 按时间获取投注记录
     *
     * @param betRecordByTimeDTO 按时间dto投注记录
     * @return {@link List }<{@link GameBettingDetails }>
     */
    @Override
    public List<GameBettingDetails> getBetRecordByTime(BetRecordByTimeDTO betRecordByTimeDTO) {
        String startTime = DateUtils.formatDateToGMT4(new Date(betRecordByTimeDTO.getStartTime()));
        String endTime = DateUtils.formatDateToGMT4(new Date(betRecordByTimeDTO.getEndTime()));
        List<GameBettingDetails> gameBettingDetails = new ArrayList<>();
        //请求参数
        String query = "StartTime=" + startTime + "&EndTime=" + endTime + "&Page=" + betRecordByTimeDTO.getPage() + "&PageLimit=" + betRecordByTimeDTO.getPageLimit() + "&AgentId=" + betRecordByTimeDTO.getAgentId();
        log.info("GamesJILIServiceImpl [getBetRecordByTime] 请求参数 {}", query);
        betRecordByTimeDTO.setQuery(query);
        //获取key
        String key = this.getKey(betRecordByTimeDTO);
        String apiBaseUrl = configService.selectConfigByKey(Constants.JILI_API_BASE_URL);
        String result = null;
        try {
            result = HttpClientSslUtils.doPost(apiBaseUrl + "/GetBetRecordByTime?" + query + "&Key=" + key, "AgentId=" + betRecordByTimeDTO.getAgentId(), ContentType.APPLICATION_FORM_URLENCODED);

            JILIBetRecordResponseDTO betRecordJILIResponse = JSON.parseObject(result, JILIBetRecordResponseDTO.class);

            //判断是否获取成功
            if (this.getIsSuccess(betRecordJILIResponse.getErrorCode())) {
                //数据组装
                JILIBetRecordResponseDTO.DataBean dataBean = betRecordJILIResponse.getData();
                for (JILIBetRecordDataResponseDTO jiliBetRecordDataResponseDTO : dataBean.getResult()) {
                    GameBettingDetails bettingDetails = this.dataBuild(GamesDataBuildDTO.builder().data(jiliBetRecordDataResponseDTO).gamesKey(key).build());
                    if (!ObjectUtils.isEmpty(bettingDetails)) {
                        gameBettingDetails.add(bettingDetails);
                    }

                }

                //获取下一页数据
                while (dataBean.getPagination().getCurrentPage() != dataBean.getPagination().getTotalPages() && dataBean.getPagination().getTotalPages() > 0) {
                    betRecordByTimeDTO.setPage(dataBean.getPagination().getCurrentPage() + 1);
                    //请求参数
                    query = "StartTime=" + startTime + "&EndTime=" + endTime + "&Page=" + betRecordByTimeDTO.getPage() + "&PageLimit=" + betRecordByTimeDTO.getPageLimit() + "&AgentId=" + betRecordByTimeDTO.getAgentId();
                    log.info("GamesJILIServiceImpl [getBetRecordByTime] 请求参数 {}", query);
                    betRecordByTimeDTO.setQuery(query);
                    key = this.getKey(betRecordByTimeDTO);
                    result = HttpUtils.sendPost(apiBaseUrl + "/GetBetRecordByTime?" + query + "&Key=" + key, "");
                    betRecordJILIResponse = JsonUtil.stringToObj(result, JILIBetRecordResponseDTO.class);
                    dataBean = betRecordJILIResponse.getData();
                    for (JILIBetRecordDataResponseDTO jiliBetRecordDataResponseDTO : dataBean.getResult()) {
                        GameBettingDetails bettingDetails = this.dataBuild(GamesDataBuildDTO.builder().data(jiliBetRecordDataResponseDTO).gamesKey(key).build());
                        if (!ObjectUtils.isEmpty(bettingDetails)) {
                            gameBettingDetails.add(bettingDetails);
                        }
                    }
                }


                return gameBettingDetails;
            } else {
                log.error("GameBettingDataJILIServiceImpl [getBetRecordByTime] 获取投注记录失败,错误代码{},错误信息{}", betRecordJILIResponse.getErrorCode(), betRecordJILIResponse.getMessage());
                throw new BaseException(MessageUtils.message("game.bet.record.retrieve.failed"));

            }
        } catch (Exception e) {
            log.error("GameBettingDataJILIServiceImpl [getBetRecordByTime] 获取投注记录失败,错误信息{}", e);
            throw new BaseException(MessageUtils.message("game.bet.record.retrieve.failed"));

        }

    }

    /**
     * 赠送免费局数
     *
     * @param createFreeSpinRequest 创建自由旋转请求
     * @return {@link Boolean }
     */
    @Override
    public Boolean createFreeSpin(CreateFreeSpinRequestDTO createFreeSpinRequest) {

        String freeSpinValidity = DateUtils.formatDateToGMT4(new Date(createFreeSpinRequest.getFreeSpinValidity()));


        List<Long> gameIds = createFreeSpinRequest.getGameIds();
        GameUniqueDTO gameUniqueDTO = new GameUniqueDTO();
        gameUniqueDTO.setGameIds(gameIds);
        List<Game> gameList = gameService.selectGameUniqueList(gameUniqueDTO);
        String gameCodes = gameList.stream()
                .map(Game::getGameCode)
                .map(String::valueOf)
                .collect(Collectors.joining(","));
        String referenceId = GamePlatforms.JILI.getCode() + IdUtils.simpleUUID();
        //请求参数
        String query = "Account=" + createFreeSpinRequest.getAccount()
                + "&Currency=" + createFreeSpinRequest.getCurrency()
                + "&ReferenceId=" + referenceId
                + "&FreeSpinValidity=" + freeSpinValidity
                + "&NumberOfRounds=" + createFreeSpinRequest.getNumberOfRounds()
                + "&GameIds=" + gameCodes;
        //判断是否有免费游戏局数可使用的开始时间
        if (!ObjectUtils.isEmpty(createFreeSpinRequest.getStartTime())) {
            String startTime = DateUtils.formatDateToGMT4(new Date(createFreeSpinRequest.getStartTime()));
            query += "&StartTime=" + startTime;
        }
        query += "&AgentId=" + createFreeSpinRequest.getAgentId();
        ;
        log.info("GamesJILIServiceImpl [createFreeSpin] 请求参数 {}", query);
        createFreeSpinRequest.setQuery(query);
        //获取key
        String key = this.getKey(createFreeSpinRequest);
        String apiBaseUrl = configService.selectConfigByKey(Constants.JILI_API_BASE_URL);
        String result = null;
        try {
            result = HttpClientSslUtils.doPost(apiBaseUrl + "/CreateFreeSpin?" + query + "&Key=" + key, "AgentId=" + createFreeSpinRequest.getAgentId(), ContentType.APPLICATION_FORM_URLENCODED);

            JILICreateFreeSpinResponseDTO createFreeSpinResponseDTO = JSON.parseObject(result, JILICreateFreeSpinResponseDTO.class);
            //判断是否获取成功
            if (this.getIsSuccess(createFreeSpinResponseDTO.getErrorCode())) {
                Member member = memberService.selectMemberByMemberAccount(createFreeSpinRequest.getAccount());
                if (ObjectUtils.isEmpty(member)) {
                    member = new Member();
                }
                for (Game game : gameList) {
                    GameFreeRecord gameFreeRecord = GameFreeRecord.builder()
                            .currencyCode(gameSecretKeyService.findSystemByCode(createFreeSpinRequest.getAgentId(), GamePlatforms.JILI.getInfo()))
                            .referenceId(referenceId)
                            .memberId(member.getId())
                            .memberAccount(createFreeSpinRequest.getAccount())
                            .gameId(game.getId())
                            .sendTime(createFreeSpinRequest.getStartTime())
                            .expiredTime(createFreeSpinRequest.getFreeSpinValidity())
                            .freeUpdateTime(DateUtils.getNowDate())
                            .sendGame(game.getGameName())
                            .sendAmount(createFreeSpinRequest.getNumberOfRounds())
                            .unusedAmount(createFreeSpinRequest.getNumberOfRounds())
                            .build();
                    gameFreeRecord.setCreateBy(Constants.SYSTEM);
                    gameFreeRecordService.insertGameFreeRecord(gameFreeRecord);
                }

                return Boolean.TRUE;
            } else {
                log.error("GameBettingDataJILIServiceImpl [createFreeSpin] 赠送免费局数,错误代码{},错误信息{}", createFreeSpinResponseDTO.getErrorCode(), createFreeSpinResponseDTO.getMessage());
                throw new BaseException(createFreeSpinResponseDTO.getMessage());
            }
        } catch (Exception e) {
            log.error("GameBettingDataJILIServiceImpl [createFreeSpin] 赠送免费局数,错误信息{}", e);
            throw new BaseException(MessageUtils.message("game.free.round.gift.failed"));

        }

    }

    /**
     * 获取游戏详细信息
     *
     * @param getGameDetailRequestDTO 获取游戏详细信息请求dto
     * @return {@link GetGameDetailResponseDTO }
     */
    @Override
    public GetGameDetailResponseDTO getGameDetail(GetGameDetailRequestDTO getGameDetailRequestDTO) {
        String query = "WagersId=" + getGameDetailRequestDTO.getWagersId();

        getGameDetailRequestDTO.setQuery(query + "&AgentId=" + getGameDetailRequestDTO.getAgentId());
        String key = this.getKey(getGameDetailRequestDTO);
        if (StringUtils.hasText(getGameDetailRequestDTO.getLang())) {
            query += "&Lang=" + getGameDetailRequestDTO.getLang();
        }
        getGameDetailRequestDTO.setQuery(query);
        log.info("GamesJILIServiceImpl [getGameDetail] 请求参数 {}", query);

        String apiBaseUrl = configService.selectConfigByKey(Constants.JILI_API_BASE_URL);
        try {

            String result = HttpClientSslUtils.doGet(apiBaseUrl + "/GetGameDetailUrl?" + query + "&AgentId=" + getGameDetailRequestDTO.getAgentId() + "&Key=" + key);
            JILIGetGameDetailResponseDTO jiliGetGameDetailResponseDTO = JsonUtil.stringToObj(result, JILIGetGameDetailResponseDTO.class);
            //判断是否获取成功
            if (this.getIsSuccess(jiliGetGameDetailResponseDTO.getErrorCode())) {
                GetGameDetailResponseDTO getGameDetailResponseDTO = new GetGameDetailResponseDTO();
                getGameDetailResponseDTO.setUrl(jiliGetGameDetailResponseDTO.getData().getUrl());
                return getGameDetailResponseDTO;
            } else {
                log.error("GameBettingDataJILIServiceImpl [getGameDetail] 获取游戏游玩详情失败,错误代码{},错误信息{}", jiliGetGameDetailResponseDTO.getErrorCode(), jiliGetGameDetailResponseDTO.getMessage());
                throw new BaseException(MessageUtils.message("game.play.details.retrieve.failed"));

            }
        } catch (Exception e) {
            log.error("GameBettingDataJILIServiceImpl [getGameDetail] 获取游戏游玩详情失败,错误信息{}", e);
            throw new BaseException(MessageUtils.message("game.play.details.retrieve.failed"));

        }
    }

    /**
     * 强制会员从游戏注销
     *
     * @param kickMemberRequestDTO 踢会员请求dto
     * @return {@link Boolean }
     */
    @Override
    public Boolean kickMember(KickMemberRequestDTO kickMemberRequestDTO) {
        String query = "Account=" + kickMemberRequestDTO.getAccount();

        kickMemberRequestDTO.setQuery(query + "&AgentId=" + kickMemberRequestDTO.getAgentId());
        String key = this.getKey(kickMemberRequestDTO);
        log.info("GamesJILIServiceImpl [kickMember] 请求参数 {}", query);

        String apiBaseUrl = configService.selectConfigByKey(Constants.JILI_API_BASE_URL);
        try {

            String result = HttpClientSslUtils.doGet(apiBaseUrl + "/KickMember?" + query + "&AgentId=" + kickMemberRequestDTO.getAgentId() + "&Key=" + key);
            JILIKickMemberDTO jiliKickMemberDTO = JsonUtil.stringToObj(result, JILIKickMemberDTO.class);
            //判断是否获取成功
            if (this.getIsSuccess(jiliKickMemberDTO.getErrorCode())) {
                return Boolean.TRUE;
            } else {
                log.error("GameBettingDataJILIServiceImpl [kickMember] 强制会员从游戏注销失败,错误代码{},错误信息{}", jiliKickMemberDTO.getErrorCode(), jiliKickMemberDTO.getMessage());
                throw new BaseException(MessageUtils.message("game.member.force.logout.failed"));

            }
        } catch (Exception e) {
            log.error("GameBettingDataJILIServiceImpl [kickMember] 强制会员从游戏注销失败,错误信息{}", e);
            throw new BaseException(MessageUtils.message("game.member.force.logout.failed"));

        }
    }

    /**
     * 踢成员全部
     *
     * @param kickMemberAllDTO 踢成员全部dto
     * @return {@link Boolean }
     */
    @Override
    public Boolean kickMemberAll(KickMemberAllDTO kickMemberAllDTO) {
        String query = "AgentId=" + kickMemberAllDTO.getAgentId();
        if (!ObjectUtils.isEmpty(kickMemberAllDTO.getGameId())) {
            query = "GameId=" + kickMemberAllDTO.getGameId() + "&" + query;
        }


        kickMemberAllDTO.setQuery(query);
        String key = this.getKey(kickMemberAllDTO);
        log.info("GamesJILIServiceImpl [kickMemberAll] 请求参数 {}", query);

        String apiBaseUrl = configService.selectConfigByKey(Constants.JILI_API_BASE_URL);
        try {

            String result = HttpClientSslUtils.doGet(apiBaseUrl + "/KickMemberAll?" + query + "&Key=" + key);
            JILIKickMemberAllDTO jiliKickMemberAllDTO = JsonUtil.stringToObj(result, JILIKickMemberAllDTO.class);
            //判断是否获取成功
            if (this.getIsSuccess(jiliKickMemberAllDTO.getErrorCode())) {
                return Boolean.TRUE;
            } else {
                log.error("GameBettingDataJILIServiceImpl [kickMemberAll] 强制全部会员从游戏注销失败,错误代码{},错误信息{}", jiliKickMemberAllDTO.getErrorCode(), jiliKickMemberAllDTO.getMessage());
                throw new BaseException(MessageUtils.message("game.members.force.logout.failed"));

            }
        } catch (Exception e) {
            log.error("GameBettingDataJILIServiceImpl [kickMemberAll] 强制全部会员从游戏注销失败,错误信息{}", e);
            throw new BaseException(MessageUtils.message("game.members.force.logout.failed"));

        }
    }

    /**
     * 免费游戏玩家使用的纪录
     *
     * @param getFreeSpinDashflowRequestDTO 获取自由旋转dashflow请求dto
     * @return {@link List }<{@link GameFreeRecord }>
     */
    @Override
    public List<GameFreeRecord> getFreeSpinDashflow(GetFreeSpinDashflowRequestDTO getFreeSpinDashflowRequestDTO) {
        List<GameFreeRecord> gameFreeRecordsResult = new ArrayList<>();
        //请求参数
        String query = "UpdateTime=" + DateUtils.formatDateToGMT4(new Date(getFreeSpinDashflowRequestDTO.getStartTime()))
                + "&AgentId=" + getFreeSpinDashflowRequestDTO.getAgentId();

        log.info("GamesJILIServiceImpl [getFreeSpinDashflow] 请求参数 {}", query);
        getFreeSpinDashflowRequestDTO.setQuery(query);
        //获取key
        String key = this.getKey(getFreeSpinDashflowRequestDTO);
        String apiBaseUrl = configService.selectConfigByKey(Constants.JILI_API_BASE_URL);
        String result = null;
        try {
            result = HttpClientSslUtils.doPost(apiBaseUrl + "/GetFreeSpinDashflow?" + query + "&Key=" + key, "AgentId=" + getFreeSpinDashflowRequestDTO.getAgentId(), ContentType.APPLICATION_FORM_URLENCODED);

            JILIGetFreeSpinDashflowResponseDTO getFreeSpinDashflowResponseDTO = JSON.parseObject(result, JILIGetFreeSpinDashflowResponseDTO.class);
            //判断是否获取成功
            if (this.getIsSuccess(getFreeSpinDashflowResponseDTO.getErrorCode())) {
                for (JILIGetFreeSpinDashflowResponseDTO.DataBean data : getFreeSpinDashflowResponseDTO.getData()) {
                    List<GameFreeRecord> gameFreeRecords = gameFreeRecordService.selectGameFreeRecordList(GameFreeRecord.builder()
                            .referenceId(data.getReferenceID())
                            .build());
                    for (GameFreeRecord gameFreeRecord : gameFreeRecords) {
                        gameFreeRecord.setSendTime(data.getSendTime());
                        gameFreeRecord.setExpiredTime(data.getExpiredTime());
                        gameFreeRecord.setFreeUpdateTime(data.getUpdateTime());
                        gameFreeRecord.setSendAmount(data.getSendAmount());
                        gameFreeRecord.setUsedAmount(data.getUsedAmount());
                        gameFreeRecord.setUnusedAmount(data.getUnusedAmount());
                        gameFreeRecordService.updateGameFreeRecord(gameFreeRecord);
                        gameFreeRecordsResult.add(gameFreeRecord);
                    }
                }

                return gameFreeRecordsResult;
            } else {
                log.error("GameBettingDataJILIServiceImpl [getFreeSpinDashflow] 查询免费游戏玩家使用的纪录,错误代码{},错误信息{}", getFreeSpinDashflowResponseDTO.getErrorCode(), getFreeSpinDashflowResponseDTO.getMessage());
                throw new BaseException(getFreeSpinDashflowResponseDTO.getMessage());
            }
        } catch (Exception e) {
            log.error("GameBettingDataJILIServiceImpl [getFreeSpinDashflow] 查询免费游戏玩家使用的纪录,错误信息{}", e);
            throw new BaseException(MessageUtils.message("game.free.play.record.query.failed"));

        }
    }

    /**
     * 取消赠送免费局数
     *
     * @param cancelFreeSpinRequestDTO 取消免费旋转请求
     * @return {@link Boolean }
     */
    @Override
    public Boolean cancelFreeSpin(CancelFreeSpinRequestDTO cancelFreeSpinRequestDTO) {
        //请求参数
        String query = "ReferenceId=" + cancelFreeSpinRequestDTO.getReferenceId()
                + "&AgentId=" + cancelFreeSpinRequestDTO.getAgentId();
        ;
        log.info("GamesJILIServiceImpl [cancelFreeSpin] 请求参数 {}", query);
        cancelFreeSpinRequestDTO.setQuery(query);
        //获取key
        String key = this.getKey(cancelFreeSpinRequestDTO);
        String apiBaseUrl = configService.selectConfigByKey(Constants.JILI_API_BASE_URL);
        String result = null;
        try {
            result = HttpClientSslUtils.doPost(apiBaseUrl + "/CancelFreeSpin?" + query + "&Key=" + key, "AgentId=" + cancelFreeSpinRequestDTO.getAgentId(), ContentType.APPLICATION_FORM_URLENCODED);

            JILICancelFreeSpinResponseDTO cancelFreeSpinResponseDTO = JSON.parseObject(result, JILICancelFreeSpinResponseDTO.class);
            //判断是否获取成功
            if (this.getIsSuccess(cancelFreeSpinResponseDTO.getErrorCode())) {
                List<GameFreeRecord> gameFreeRecords = gameFreeRecordService.selectGameFreeRecordList(GameFreeRecord.builder()
                        .referenceId(cancelFreeSpinRequestDTO.getReferenceId())
                        .build());
                for (GameFreeRecord gameFreeRecord : gameFreeRecords) {
                    gameFreeRecord.setFreeStatus(FreeStatus.CANCEL.getCode());
                    gameFreeRecordService.updateGameFreeRecord(gameFreeRecord);
                }
                return Boolean.TRUE;
            } else {
                log.error("GameBettingDataJILIServiceImpl [cancelFreeSpin] 取消赠送免费局数,错误代码{},错误信息{}", cancelFreeSpinResponseDTO.getErrorCode(), cancelFreeSpinResponseDTO.getMessage());
                throw new BaseException(cancelFreeSpinResponseDTO.getMessage());
            }
        } catch (Exception e) {
            log.error("GameBettingDataJILIServiceImpl [cancelFreeSpin] 取消赠送免费局数,错误信息{}", e);
            throw new BaseException(MessageUtils.message("game.free.round.cancel.failed"));

        }
    }


    /**
     * 数据构建
     *
     * @param gamesDataBuildDTO 数据
     * @return {@link GameBettingDetails }
     */
    @Override
    public GameBettingDetails dataBuild(GamesDataBuildDTO gamesDataBuildDTO) {

        //转化类
        JILIBetRecordDataResponseDTO jiliBetRecordDataResponseDTO = (JILIBetRecordDataResponseDTO) gamesDataBuildDTO.getData();
        String systemByCode = gameSecretKeyService.findSystemByCode(jiliBetRecordDataResponseDTO.getAgentId(), GamePlatforms.JILI.getInfo());
        Member member = memberService.selectMemberByMemberAccount(jiliBetRecordDataResponseDTO.getAccount());
        if (ObjectUtils.isEmpty(member)) {
            return null;
        }
        List<JILIGamesDataDTO> gamesDatas = redisCache.getCacheList(CacheConstants.JILI_GAMES);
        Map<Integer, JILIGamesDataDTO> dataDTOMap = gamesDatas.stream().collect(Collectors.toMap(JILIGamesDataDTO::getGameId, e -> e));
        JILIGamesDataDTO gamesDataDTO = dataDTOMap.get(jiliBetRecordDataResponseDTO.getGameId());
        BigDecimal payoffAmount = BigDecimal.ZERO;
        if (GameStatus.WIN.getCode().equals(jiliBetRecordDataResponseDTO.getStatus())) {
            payoffAmount = NumberUtil.sub(jiliBetRecordDataResponseDTO.getPayoffAmount(), jiliBetRecordDataResponseDTO.getTurnover());
        } else if (GameStatus.FAIL.getCode().equals(jiliBetRecordDataResponseDTO.getStatus())) {
            payoffAmount = NumberUtil.sub(jiliBetRecordDataResponseDTO.getPayoffAmount(), jiliBetRecordDataResponseDTO.getTurnover()).negate();
        }

        //数据构造
        GameBettingDetails gameBettingDetails = GameBettingDetails.builder()
                //保存我们的币种id
                .currencyCode(systemByCode)
                .memberId(member.getId())
                .gameCode(jiliBetRecordDataResponseDTO.getGameId())
                .gameType(JILIGameType.findSystemByCode(jiliBetRecordDataResponseDTO.getGameCategoryId()))
                .platformCode(GamePlatforms.JILI.getCode())
                .gameId(gamesDataDTO.getSystemGameId())
                .gameName(gamesDataDTO.getName().getZhCN())
                .gameStatus(jiliBetRecordDataResponseDTO.getStatus())
                .gameStatusType(jiliBetRecordDataResponseDTO.getType())
                .gameCurrencyCode(jiliBetRecordDataResponseDTO.getAgentId())
                .account(String.valueOf(jiliBetRecordDataResponseDTO.getAccount()))
                .wagersId(jiliBetRecordDataResponseDTO.getWagersId())
                .wagersTime(jiliBetRecordDataResponseDTO.getWagersTime())
                .betAmount(jiliBetRecordDataResponseDTO.getBetAmount().abs())
                .payoffTime(jiliBetRecordDataResponseDTO.getPayoffTime())
                .payoffAmount(payoffAmount)
                .settlementTime(jiliBetRecordDataResponseDTO.getSettlementTime())
                .turnover(jiliBetRecordDataResponseDTO.getTurnover())
                .orderNo(String.valueOf(jiliBetRecordDataResponseDTO.getRoundIndex()))
                .build();
        gameBettingDetails.setCreateBy(Constants.SYSTEM);
        gameBettingDetails.setCreateTime(DateUtils.getNowDate());
        return gameBettingDetails;
    }
}
