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.*;
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.common.domain.TenantSecretKey;
import com.ff.common.dto.BalanceChangesDTO;
import com.ff.common.service.ITenantGameQuotaService;
import com.ff.config.KeyConfig;
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.Assert;
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;


    @Resource
    private KeyConfig keyConfig;

    @Resource
    private IGameBettingDetailsService gameBettingDetailsService;


    /**
     * 获得就是成功
     *
     * @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()) {
                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.setGameSourceType(gamesDataDTO.getGameCategoryId());
                    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 {
            throw new BaseException(jiliGames.getMessage());

        }

        return CacheConstants.JILI_GAMES;
    }

    /**
     * 按代理id进行交换转账
     *
     * @param exchangeTransferMoneyRequestDTO 外汇转账moeny dto
     * @return {@link Long }
     */
    @Override
    @Transactional
    public String exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO) {
        String systemByCode = gameSecretKeyService.findSystemByCode(exchangeTransferMoneyRequestDTO.getAgentId(), GamePlatforms.JILI.getInfo());
        Member member = memberService.selectMemberByGameAccount(exchangeTransferMoneyRequestDTO.getAccount());
        String transactionId = GamePlatforms.JILI.getCode() + IdUtils.simpleUUID();
        TenantSecretKey tenantSecretKey = keyConfig.get();
        List<GameExchangeMoney> gameExchangeMonies = gameExchangeMoneyService.selectGameExchangeMoneyList(
                GameExchangeMoney.builder()
                        .tenantKey(tenantSecretKey.getTenantKey())
                        .orderId(exchangeTransferMoneyRequestDTO.getOrderId())
                        .build()
        );
        Assert.isTrue(CollectionUtils.isEmpty(gameExchangeMonies), "订单号重复");


        //获取下一个自增id
        GameExchangeMoney exchangeMoney = GameExchangeMoney
                .builder()
                .tenantKey(tenantSecretKey.getTenantKey())
                .quota(exchangeTransferMoneyRequestDTO.getQuota())
                .balance(exchangeTransferMoneyRequestDTO.getAmount())
                .exchangeType(exchangeTransferMoneyRequestDTO.getTransferType())
                .currencyCode(systemByCode)
                .memberId(member.getId())
                .transactionId(transactionId)
                .orderId(exchangeTransferMoneyRequestDTO.getOrderId())
                .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);

        JILIExchangeMoneyResponseDTO exchangeMoneyResponse = jiliClient.exchangeTransferByAgentId(query + "&Key=" + key, exchangeTransferMoneyRequestDTO.getAgentId());

        //判断是否转移成功
        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 {
            throw new BaseException(exchangeMoneyResponse.getMessage());
        }


        return transactionId;
    }


    /**
     * 按时间获取投注记录
     *
     * @param betRecordByTimeDTO 按时间dto投注记录
     * @return {@link Boolean }
     */
    @Override
    public Boolean getBetRecordByTime(BetRecordByTimeDTO betRecordByTimeDTO) {
        String startTime = DateUtils.formatDateToGMT4(new Date(betRecordByTimeDTO.getStartTime()));
        String endTime = DateUtils.formatDateToGMT4(new Date(betRecordByTimeDTO.getEndTime()));

        //请求参数
        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);
        JILIBetRecordResponseDTO betRecordJILIResponse = jiliClient.getBetRecordByTime(query + "&Key=" + key, betRecordByTimeDTO.getAgentId());

        //判断是否获取成功
        if (this.getIsSuccess(betRecordJILIResponse.getErrorCode())) {
            //数据插入
            this.batchInsert(betRecordJILIResponse);
            JILIBetRecordResponseDTO.DataBean dataBean = betRecordJILIResponse.getData();
            //获取下一页数据
            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);
                betRecordJILIResponse = jiliClient.getBetRecordByTime(query + "&Key=" + key, betRecordByTimeDTO.getAgentId());
                if (this.getIsSuccess(betRecordJILIResponse.getErrorCode())) {
                    //数据插入
                    this.batchInsert(betRecordJILIResponse);
                } else {
                    log.error("GameBettingDataJILIServiceImpl [getBetRecordByTime] 获取投注记录失败,错误代码{},错误信息{}", betRecordJILIResponse.getErrorCode(), betRecordJILIResponse.getMessage());
                }
            }
        } else {
            log.error("GameBettingDataJILIServiceImpl [getBetRecordByTime] 获取投注记录失败,错误代码{},错误信息{}", betRecordJILIResponse.getErrorCode(), betRecordJILIResponse.getMessage());
            return Boolean.FALSE;
        }
        return Boolean.TRUE;
    }

    /**
     * 赠送免费局数
     *
     * @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;

        query += "&AgentId=" + createFreeSpinRequest.getAgentId();
        log.info("GamesJILIServiceImpl [createFreeSpin] 请求参数 {}", query);
        createFreeSpinRequest.setQuery(query);
        //获取key
        String key = this.getKey(createFreeSpinRequest);
        //判断是否有免费游戏局数可使用的开始时间
        if (!ObjectUtils.isEmpty(createFreeSpinRequest.getStartTime())) {
            String startTime = DateUtils.formatDateToGMT4(new Date(createFreeSpinRequest.getStartTime()));
            query += "&StartTime=" + startTime;
        }
        //判断是否有免费游戏局数可使用的开始时间
        if (!ObjectUtils.isEmpty(createFreeSpinRequest.getStartTime())) {
            String startTime = DateUtils.formatDateToGMT4(new Date(createFreeSpinRequest.getStartTime()));
            query += "&StartTime=" + startTime;
        }
        //指定投注额
        if (ObjectUtils.isEmpty(createFreeSpinRequest.getBetValue())) {
            query += "&BetValue=" + createFreeSpinRequest.getBetValue();
        }
        createFreeSpinRequest.setQuery(query);
        JILICreateFreeSpinResponseDTO createFreeSpinResponseDTO = jiliClient.createFreeSpin(query + "&Key=" + key, createFreeSpinRequest.getAgentId());

        //判断是否获取成功
        if (this.getIsSuccess(createFreeSpinResponseDTO.getErrorCode())) {
            Member member = memberService.selectMemberByGameAccount(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)
                        .platformCode(GamePlatforms.JILI.getInfo())
                        .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());
        }

    }

    /**
     * 获取游戏详细信息
     *
     * @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);
        JILIGetGameDetailResponseDTO jiliGetGameDetailResponseDTO = jiliClient.getGameDetail(query + "&AgentId=" + getGameDetailRequestDTO.getAgentId() + "&Key=" + key);
        //判断是否获取成功
        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(jiliGetGameDetailResponseDTO.getMessage());
        }
    }

    /**
     * 强制会员从游戏注销
     *
     * @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);

        JILIKickMemberDTO jiliKickMemberDTO = jiliClient.kickMember(query + "&AgentId=" + kickMemberRequestDTO.getAgentId() + "&Key=" + key);
        //判断是否获取成功
        if (this.getIsSuccess(jiliKickMemberDTO.getErrorCode())) {
            return Boolean.TRUE;
        } else {
            throw new BaseException(jiliKickMemberDTO.getMessage());

        }
    }

    /**
     * 踢成员全部
     *
     * @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);
        JILIKickMemberAllDTO jiliKickMemberAllDTO = jiliClient.kickMemberAll(query + "&AgentId=" + kickMemberAllDTO.getAgentId() + "&Key=" + key);
        //判断是否获取成功
        if (this.getIsSuccess(jiliKickMemberAllDTO.getErrorCode())) {
            return Boolean.TRUE;
        } else {
            throw new BaseException(jiliKickMemberAllDTO.getMessage());
        }
    }

    /**
     * 免费游戏玩家使用的纪录
     *
     * @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);
        JILIGetFreeSpinDashflowResponseDTO getFreeSpinDashflowResponseDTO = jiliClient.getFreeSpinDashflow(query + "&Key=" + key);
        //判断是否获取成功
        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 {
            throw new BaseException(getFreeSpinDashflowResponseDTO.getMessage());
        }

    }

    /**
     * 取消赠送免费局数
     *
     * @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);
        JILICancelFreeSpinResponseDTO cancelFreeSpinResponseDTO = jiliClient.cancelFreeSpin(query  + "&Key=" + key);
        //判断是否获取成功
        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 {
            throw new BaseException(cancelFreeSpinResponseDTO.getMessage());
        }
    }


    /**
     * 批量插入
     *
     * @param betRecordJILIResponse 投注记录jiliresponse
     * @return {@link Integer }
     */
    private void batchInsert(JILIBetRecordResponseDTO betRecordJILIResponse) {
        List<GameBettingDetails> gameBettingDetails = new ArrayList<>();
        List<Long> wagersIds = new ArrayList<>();
        //数据组装
        JILIBetRecordResponseDTO.DataBean dataBean = betRecordJILIResponse.getData();
        //数据转化
        for (JILIBetRecordDataResponseDTO jiliBetRecordDataResponseDTO : dataBean.getResult()) {
            GameBettingDetails bettingDetails = this.dataBuild(GamesDataBuildDTO.builder().data(jiliBetRecordDataResponseDTO).build());
            if (!ObjectUtils.isEmpty(bettingDetails)) {
                gameBettingDetails.add(bettingDetails);
            }
            wagersIds.add(jiliBetRecordDataResponseDTO.getWagersId());
        }
        if (!CollectionUtils.isEmpty(gameBettingDetails)) {
            //查询重复数据id
            List<Long> removeWagersIds = gameBettingDetailsService.selectGameBettingDetailsByWagersId(wagersIds);
            //用steam流清除list中与wagersIds集合相同的数据
            gameBettingDetails = gameBettingDetails.stream()
                    .filter(detail -> !removeWagersIds.contains(detail.getWagersId()))
                    .collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(gameBettingDetails)) {
                gameBettingDetailsService.batchInsert(gameBettingDetails);
            }
        }

    }

    /**
     * 数据构建
     *
     * @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.selectMemberByGameAccount(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;
    }
}
