package com.game.business.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.game.business.domain.*;
import com.game.business.task.AppAgentGameBettingTask;
import com.game.business.util.Common;
import com.game.business.vo.*;
import com.game.business.service.*;
import com.game.common.annotation.Anonymous;
import com.game.common.annotation.Log;
import com.game.common.constant.CacheConstants;
import com.game.common.constant.finance.FinTranType1;
import com.game.common.constant.finance.FinTranType2;
import com.game.common.constant.finance.FinTranType3;
import com.game.common.core.controller.BaseController;
import com.game.common.core.domain.HttpRet;
import com.game.common.core.domain.HttpRetPageArr;
import com.game.common.core.domain.R;
import com.game.common.core.page.TableDataInfo;
import com.game.common.core.redis.RedisCache;
import com.game.common.enums.BusinessType;
import com.game.common.utils.SecurityUtils;
import com.game.common.utils.poi.ExcelUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/business/betting")
@Api(value = "AppGameBettingController", description = "游戏投注接口", tags = {"游戏投注、查询记录等"})
public class AppGameBettingController extends BaseController{

    @Autowired
    private IAppGameBettingService appGameBettingService;

    @Autowired
    private IAppGameService appGameService;

    @Autowired
    private IAppGameClassifyService appGameClassifyService;

    @Autowired
    private IAppUserService appUserService;

    @Autowired
    private IFinTranRecordService finTranRecordService;

    @Autowired
    private IAppGameLotteryService appGameLotteryService;

    @Autowired
    private IAppGameItemService appGameItemService;

    @Autowired
    private AppAgentGameBettingTask appAgentGameBettingTask;

    @Autowired
    private IAppGameMoneyService appGameMoneyService;

    @Autowired
    private RedisCache redisCache;

    /**
     * 下注
     */
    @PostMapping(value = "/create")
    @ApiOperation(value = "游戏下注", notes = "游戏下注")
    @DSTransactional
    public HttpRet<Double> betting(@RequestBody AppGameBetting gameBetting) throws Exception {

        String redisKey = CacheConstants.GAME_USER_BETTING_CREATE.concat(gameBetting.getUserId() + ":" + gameBetting.getGameId() + ":" + gameBetting.getGameDate());
        if(!redisCache.redisTemplate.opsForValue().setIfAbsent(redisKey, 1)){
            return HttpRet.fail("下注速度过快，请等待1秒后再试。");
        }

        Double diamondCoin = 0.00;

        try {

            if(gameBetting.getClassId() == null){
                return HttpRet.fail("游戏平台ID为空。");
            }

            if(gameBetting.getGameId() == null){
                return HttpRet.fail("游戏ID为空。");
            }

            if(gameBetting.getUserId()== null){
                return HttpRet.fail("用户ID为空。");
            }

            if(gameBetting.getBettingGameType() == null){
                gameBetting.setBettingGameType(0);
            }

//            if(gameBetting.getMoneyId() == null){
//                return HttpRet.fail("金额ID为空。");
//            }

            if(gameBetting.getMoneyId() != null && gameBetting.getMoneyId() > 0){
                if(gameBetting.getBettingGameType() == 0){

                    AppGameMoney appGameMoney = appGameMoneyService.selectAppGameMoneyById(gameBetting.getMoneyId());

                    if(appGameMoney == null){
                        return HttpRet.fail("金额对象不存在。");
                    }

                    if(appGameMoney.getBettingMoney().doubleValue() != gameBetting.getBettingAmount().doubleValue()){
                        return HttpRet.fail("投注金额不匹配，无法下单。");
                    }
                }
            }

            AppGameClassify appGameClassify = appGameClassifyService.selectAppGameClassifyById(gameBetting.getClassId());
            if(appGameClassify == null){
                return HttpRet.fail("游戏平台不存在。");
            }

            AppGame appGame = appGameService.selectAppGameById(gameBetting.getGameId());
            if(appGame == null){
                return HttpRet.fail("游戏不存在。");
            }

            if(appGame.getStatus() == 0){
                return HttpRet.fail("游戏已下线，无法下单。");
            }

            if(appGame.getEnable() == 1){
                return HttpRet.fail("游戏已禁用，无法下单。");
            }

            if(StringUtils.isBlank(appGame.getGameDate())){
                return HttpRet.fail("游戏期号不存在，无法下单。");
            }

            if(!appGame.getGameDate().equals(gameBetting.getGameDate())){
                return HttpRet.fail("游戏期号不匹配，无法下单。");
            }

            if(StringUtils.isBlank(appGame.getGameTime())){
                return HttpRet.fail("游戏已封盘，无法下单。");
            }

            if(!appGame.getGameTime().contains(":")){
                return HttpRet.fail("游戏已封盘，无法下单。");
            }

            String[] timeArry = appGame.getGameTime().substring(0, 5).split(":");
            int f = Integer.parseInt(timeArry[0]);
            int m = Integer.parseInt(timeArry[1]);
            if(f == 0 && m <= 2){
                return HttpRet.fail("游戏已封盘，无法下单。");
            }

            if(appGame.getBettingCount() == null || appGame.getBettingCount() == 0){
                return HttpRet.fail("投注次数已超过限额，无法下单。");
            }

            // 每期可投注多少个选项：比如设置为3 则只能投3个不同的选项，不能超过3个
            Integer bettingCount = appGameBettingService.getBettingCount(gameBetting.getUserId(), gameBetting.getGameId(), appGame.getGameDate(), gameBetting.getBettingItem());
            if(bettingCount != null && bettingCount > 0 ){
                if(appGame.getBettingCount().intValue() >= 0 && bettingCount.intValue() >= appGame.getBettingCount().intValue()){
                    return HttpRet.fail("当前期投注选项已超过限额，无法下单。");
                }
            }

            // 游戏特殊固定下注判断
            if(appGame.getCode().equals(Common.GAME_FOUR_CODE) ||
                appGame.getCode().equals(Common.GAME_SIX_CODE) ||
                appGame.getCode().equals(Common.GAME_SEVEN_CODE)){

                List<String> itemList = Arrays.asList(Common.GAME_BETTING_ITEM_SMALL_LIMIT);

                //  当前投注是否属于小倍
                if(itemList.contains(gameBetting.getBettingItem())) {

                    List<String> bettingItemList = appGameBettingService.getBettingItem(gameBetting.getUserId(), gameBetting.getGameId(), appGame.getGameDate());
                    if (bettingItemList != null && !bettingItemList.isEmpty()) {

                        List<String> checkItemList = new ArrayList<>();

                        for (int i = 0; i < itemList.size(); i++) {
                            String itemStr = itemList.get(i);
                            if (bettingItemList.contains(itemStr)) {
                                checkItemList.add(itemStr);
                            }
                        }

                        if(checkItemList.size() == 4){
                        }

                        // 当前投注是否已经满足3个投注选项了
                        if (checkItemList.size() == 3) {
                            // 当前投注的是否属于特殊选项重复投注
                            if (!checkItemList.contains(gameBetting.getBettingItem())) {
                                return HttpRet.fail("当前期投注选项已超过限额，无法下单！");
                            }
                        }
                    }
                }
            }else if(appGame.getCode().equals(Common.GAME_EIGHT_CODE)){

                List<String> itemSmallList = Arrays.asList(Common.GAME_BETTING_ITEM_SMALL_LIMIT);

                List<String> itemBigList = Arrays.asList(Common.GAME_BETTING_ITEM_BIG_LIMIT);

                List<String> bettingItemList = appGameBettingService.getBettingItem(gameBetting.getUserId(), gameBetting.getGameId(), appGame.getGameDate());

                if (bettingItemList != null && !bettingItemList.isEmpty()) {

                    // 当前投注是否属于小倍
                    if(itemSmallList.contains(gameBetting.getBettingItem())) {

                        List<String> checkItemList = new ArrayList<>();

                        for (int i = 0; i < itemSmallList.size(); i++) {
                            String itemStr = itemSmallList.get(i);
                            if (bettingItemList.contains(itemStr)) {
                                checkItemList.add(itemStr);
                            }
                        }

                        if(checkItemList.size() >= 3){
                            return HttpRet.fail("当前期投注选项已超过限额，无法下单！");
                        }

                        // 当前投注是否已经满足3个投注选项了
                        if (checkItemList.size() == 2) {
                            // 当前投注的是否属于特殊选项重复投注
                            if (!checkItemList.contains(gameBetting.getBettingItem())) {
                                return HttpRet.fail("当前期投注选项已超过限额，无法下单！");
                            }
                        }
                    // 当前投注是否属于大倍
                    }else if(itemBigList.contains(gameBetting.getBettingItem())) {

                        List<String> checkItemList = new ArrayList<>();

                        for (int i = 0; i < itemBigList.size(); i++) {
                            String itemStr = itemBigList.get(i);
                            if (bettingItemList.contains(itemStr)) {
                                checkItemList.add(itemStr);
                            }
                        }

                        if(checkItemList.size() >= 4){
                            return HttpRet.fail("当前期投注选项已超过限额，无法下单！");
                        }

                        // 当前投注是否已经满足3个投注选项了
                        if (checkItemList.size() == 3) {
                            // 当前投注的是否属于特殊选项重复投注
                            if (!checkItemList.contains(gameBetting.getBettingItem())) {
                                return HttpRet.fail("当前期投注选项已超过限额，无法下单！");
                            }
                        }
                    }
                }
            }

            BigDecimal gameBettingAmountCheck = new BigDecimal(appGame.getBettingMaxMoney() + "");
            BigDecimal gameBettingAmountSum = appGameBettingService.getBettingAmount(gameBetting.getUserId(), gameBetting.getGameId(), appGame.getGameDate(), null);
            BigDecimal gameBettingAmountAdd = gameBettingAmountSum.add(new BigDecimal(gameBetting.getBettingAmount() + ""));
            if(appGame.getBettingMaxMoney() >= 0 && gameBettingAmountAdd.compareTo(gameBettingAmountCheck) == 1){
                return HttpRet.fail("当前期投注金额已超过限额，无法下单。");
            }

            // 单选
            if(gameBetting.getBettingGameType() == 0){

                AppGameItem appGameItem = appGameItemService.selectAppGameItemByGameIdAndItemLocation(appGame.getId(), gameBetting.getBettingItem());
                if(appGameItem == null){
                    return HttpRet.fail("游戏选项不存在，无法下单。");
                }

                if(appGame.getCode().equals(Common.GAME_ONE_CODE)){
                    if(gameBetting.getBettingMultiple() != null && gameBetting.getBettingMultiple() > 0){
                        if(gameBetting.getBettingMultiple().doubleValue() != appGameItem.getItemMultiple().doubleValue()){
                            return HttpRet.fail("游戏选项倍数不统一，无法下单。");
                        }
                    }
                }

                Integer bettingItemCount = appGameBettingService.getBettingItemCount(gameBetting.getUserId(), gameBetting.getGameId(), appGame.getGameDate(), gameBetting.getBettingItem());
                if(bettingItemCount != null && bettingItemCount > 0 ){
                    if(appGameItem.getBettingCount().intValue() >= 0 && bettingItemCount.intValue() >= appGameItem.getBettingCount().intValue()){
                        return HttpRet.fail("当前期投注选项数量已超过限额，无法下单。");
                    }
                }

                BigDecimal bettingAmountCheck = new BigDecimal(appGameItem.getBettingMoney() + "");
                BigDecimal bettingAmountSum = appGameBettingService.getBettingAmount(gameBetting.getUserId(), gameBetting.getGameId(), appGame.getGameDate(), gameBetting.getBettingItem());
                BigDecimal bettingAmountAdd = bettingAmountSum.add(new BigDecimal(gameBetting.getBettingAmount() + ""));
                if(appGameItem.getBettingMoney() >= 0 && bettingAmountAdd.compareTo(bettingAmountCheck) == 1){
                    return HttpRet.fail("当前期选项投注金额已超过限额，无法下单。");
                }

                gameBetting.setBettingMultiple(appGameItem.getItemMultiple());
            // 多选
            }else if(gameBetting.getBettingGameType() == 1 || gameBetting.getBettingGameType() == 2){
                List<AppGameItemBettingVO> itemList = JSON.parseArray(gameBetting.getBettingItem(), AppGameItemBettingVO.class);
                if(itemList == null || itemList.isEmpty()){
                    return HttpRet.fail("游戏选项不存在，无法下单。");
                }
                for(AppGameItemBettingVO item : itemList){
                    AppGameItem appGameItem = appGameItemService.selectAppGameItemByGameIdAndItemLocation(appGame.getId(), item.getBettingItem());
                    if(appGameItem == null){
                        return HttpRet.fail("游戏选项不存在，无法下单。");
                    }
                }
                // 写死的倍数
                if(gameBetting.getBettingGameType() == 1){
                    gameBetting.setBettingMultiple(getMultiple(itemList.size()));
                }
            }

            AppGameLottery appGameLottery = appGameLotteryService.selectLottery(appGame.getClassifyId(), appGame.getId(), appGame.getGameDate());

            if(appGameLottery == null){
                return HttpRet.fail("游戏未开盘，无法下单。");
            }

            if(appGameLottery.getIsLottery() == 1){
                return HttpRet.fail("游戏已开奖，无法下单。");
            }

            AppUser appUser = appUserService.selectAppUserByUserid(gameBetting.getUserId());

            if(appUser == null){
                return HttpRet.fail("用户不存在。");
            }

            if(gameBetting.getBettingType() == 0){

                // 获取用户金额，判断投注金额是否大于余额
                if(gameBetting.getBettingAmount() > appUser.getDiamondCoin()){
                    return HttpRet.fail("余额不足，投注失败。");
                }

                // 更新用户余额
                //appUser.setDiamondCoin(appUser.getDiamondCoin() - gameBetting.getBettingAmount());
                //appUser.setDiamondCoinTotal(appUser.getDiamondCoinTotal() - gameBetting.getBettingAmount());
                //appUser.setDiamondCoinCash(appUser.getDiamondCoinCash() - gameBetting.getBettingAmount());
            }else{

                // 获取用户金额，判断投注金额是否大于余额
                if(gameBetting.getBettingAmount() > appUser.getCoin()){
                    return HttpRet.fail("金币不足，投注失败。");
                }

                //appUser.setCoin(appUser.getCoin() - gameBetting.getBettingAmount());

                // 判断不可提现金币是否满足扣款
                //if(gameBetting.getBettingAmount() > (appUser.getCoin() - appUser.getCoinCash())){
                //    appUser.setCoinCash(gameBetting.getBettingAmount() - (appUser.getCoin() - appUser.getCoinCash()));
                //}
            }

            //appUserService.updateAppUser(appUser);

            //redisCache.deleteObject("U:UserInfo:" + appUser.getUserid());

            gameBetting.setGameDate(appGame.getGameDate());
            gameBetting.setIsLive(0);
            if(gameBetting.getLiveRoomId() != null && gameBetting.getLiveRoomId() > 0 && gameBetting.getLiveUserId() != null && gameBetting.getLiveUserId() > 0){
                gameBetting.setIsLive(1);
            }

            gameBetting.setCreateTime(new Date());
            // 插入投注记录
            appGameBettingService.save(gameBetting);

            FinTranRecord finTranRecord = new FinTranRecord();

            //finTranRecord.setAfterCoin(appUser.getCoin());
            //finTranRecord.setAfterDiamondCoin(appUser.getDiamondCoin());

            if(gameBetting.getBettingType() == 0){
                finTranRecord.setCurrencyType(4);
                finTranRecord.setDiamondCoinChange(gameBetting.getBettingAmount() * -1);
                finTranRecord.setCoinChange(0.00);
            }else{
                finTranRecord.setCurrencyType(2);
                finTranRecord.setCoinChange(gameBetting.getBettingAmount() * -1);
                finTranRecord.setDiamondCoinChange(0.00);
            }

            finTranRecord.setAfterMoney(0.00);
            finTranRecord.setMoneyChange(0.00);

            finTranRecord.setAfterTicket(0.00);
            finTranRecord.setTicketChange(0.00);

            finTranRecord.setToUid(appUser.getUserid());
            finTranRecord.setUid(appUser.getUserid());

            finTranRecord.setSceneId1(0L);
            finTranRecord.setSceneId2(null);
            finTranRecord.setSceneType(0L);

            finTranRecord.setTranGroupId(gameBetting.getId());

            if(gameBetting.getBettingType() == 0){
                finTranRecord.setTranType1(FinTranType1.U_Outcome_Balance.getType());
            }else{
                finTranRecord.setTranType1(FinTranType1.U_Outcome_Coin.getType());
            }

            finTranRecord.setTranType2(FinTranType2.CONSUM_GAME.getType());
            finTranRecord.setTranType3(FinTranType3.CONSUM_GAME_ANCHOR_ZHUANPAN.getType());


            finTranRecord.setRemarks(appGame.getGameDate() + "期，游戏下注");

            finTranRecord.setConsumptionCoin(gameBetting.getBettingAmount());
            finTranRecord.setConsumptionMoney(0.00);
            finTranRecord.setCommissionRelatedUid(0L);
            finTranRecord.setAgentId(appUser.getAgentId());

            finTranRecord.setCreateTime(new Date());

            finTranRecord.setFromUid(appUser.getUserid());
            finTranRecord.setGoodsId(0L);
            finTranRecord.setGuildId(0L);
            finTranRecord.setManagerCoId(0L);
            finTranRecord.setManagerId(0L);

            finTranRecord.setPerc(0.00);
            finTranRecord.setProId(0L);
            finTranRecord.setProCount(0L);

            finTranRecord.setOrderId(gameBetting.getId());
            //finTranRecordService.insertFinTranRecord(finTranRecord);
            appUserService.updateUserAmount(finTranRecord,false);

            // 分佣
            if(gameBetting.getBettingType() == 0){
                appAgentGameBettingTask.agentGameBettingTask(gameBetting);
            }

            diamondCoin = appUser.getDiamondCoin();
        }catch (Exception e){
            throw new Exception("下注异常");
        }finally {
            redisCache.redisTemplate.delete(redisKey);
        }

        return HttpRet.success("下注成功", diamondCoin);
    }

    /**
     * 游戏输赢统计
     */
    @PostMapping(value = "/count")
    @ApiOperation(value = "游戏输赢统计（首页）", notes = "游戏输赢统计（首页）")
    public HttpRet<AppGameBettingCountVO> getCount(@RequestParam(name = "strDate") String strDate, @RequestParam(name = "userId") Long userId, @RequestParam(name = "bettingType") Integer bettingType)
    {

        if(bettingType == null){
            bettingType = 0;
        }
        AppGameBettingCountVO appGameBettingCountDTO = new AppGameBettingCountVO();
        List<AppGame> gameList = appGameService.selectAppGameList(new AppGame());

        if(gameList == null || gameList.isEmpty()){
            return HttpRet.success("查询成功",appGameBettingCountDTO);
        }

        List<AppGameBettingDetailsCountVO> countList = appGameBettingService.getCount(strDate, userId, bettingType);
        if(countList == null){
            countList = new ArrayList<>();
        }
        Map<Long, List<AppGameBettingDetailsCountVO>> idGameMap = countList.stream().collect(Collectors.groupingBy(AppGameBettingDetailsCountVO::getGameId));

        List<AppGameBettingDetailsCountVO> newList = new ArrayList<>();
        double orderAmount = 0.00;
        double winAmount = 0.00;
        double loseAmount = 0.00;
        for (int i = 0; i < gameList.size(); i++) {
            AppGame appGame = gameList.get(i);
            AppGameBettingDetailsCountVO appGameBettingDetailsCountDTO = new AppGameBettingDetailsCountVO();
            appGameBettingDetailsCountDTO.setBettingType(bettingType);
            appGameBettingDetailsCountDTO.setGameId(appGame.getId());
            appGameBettingDetailsCountDTO.setGameName(appGame.getName());
            appGameBettingDetailsCountDTO.setLogoUrl(appGame.getLogoUrl());
            appGameBettingDetailsCountDTO.setGamePath(appGame.getGamePath());
            if(idGameMap.containsKey(appGame.getId())){
                AppGameBettingDetailsCountVO dbAppGameBettingDetailsCount = idGameMap.get(appGame.getId()).get(0);
                appGameBettingDetailsCountDTO.setBettingCount(dbAppGameBettingDetailsCount.getBettingCount());
                appGameBettingDetailsCountDTO.setOrderAmount(dbAppGameBettingDetailsCount.getOrderAmount());
                appGameBettingDetailsCountDTO.setWinAmount(dbAppGameBettingDetailsCount.getWinAmount());
                appGameBettingDetailsCountDTO.setLoseAmount(dbAppGameBettingDetailsCount.getLoseAmount());
                orderAmount += dbAppGameBettingDetailsCount.getOrderAmount();
                winAmount += dbAppGameBettingDetailsCount.getWinAmount();
                loseAmount += dbAppGameBettingDetailsCount.getLoseAmount();
            }else{
                appGameBettingDetailsCountDTO.setBettingCount(0);
                appGameBettingDetailsCountDTO.setOrderAmount(0.00);
                appGameBettingDetailsCountDTO.setWinAmount(0.00);
                appGameBettingDetailsCountDTO.setLoseAmount(0.00);
            }
            newList.add(appGameBettingDetailsCountDTO);
        }
        appGameBettingCountDTO.setOrderAmount(orderAmount);
        appGameBettingCountDTO.setWinAmount(winAmount);
        appGameBettingCountDTO.setLoseAmount(loseAmount);
        appGameBettingCountDTO.setList(newList);
        return HttpRet.success("查询成功", appGameBettingCountDTO);
    }

    /**
     * 游戏输赢详情列表
     */
    @PostMapping(value = "/listByGameId")
    @ApiOperation(value = "游戏输赢统计（详情）", notes = "游戏输赢统计（详情）")
    public HttpRetPageArr<AppGameBettingVO> getListByGameId(@RequestParam(name = "gameId") Long gameId, @RequestParam(name = "userId") Long userId,
                                                            @RequestParam(name = "isWinning") Integer isWinning, @RequestParam(name = "strDate", required = false) String strDate
                                                            ,@RequestParam(name = "bettingType", required = false) Integer bettingType)
    {
        startPage();
        List<AppGameBetting> list = appGameBettingService.selectListByGameId(gameId, userId, isWinning, strDate, bettingType);
        List<AppGameBettingVO> resultList = new ArrayList<>();
        if(list != null && !list.isEmpty()){
            AppGameItem appGameItem = new AppGameItem();
            appGameItem.setGameId(gameId);
            List<AppGameItem> itemList = appGameItemService.selectAppGameItemList(appGameItem);
            Map<String, List<AppGameItem>> codeItmeMap = itemList.stream().collect(Collectors.groupingBy(AppGameItem::getItemLocation));
            for (int i = 0; i <list.size(); i++) {
                AppGameBetting appGameBetting  = list.get(i);
                AppGameBettingVO appGameBettingVO = new AppGameBettingVO();
                BeanUtils.copyProperties(appGameBetting, appGameBettingVO);

                if(StringUtils.isNotBlank(appGameBettingVO.getBettingItem())){
                    if(codeItmeMap.containsKey(appGameBettingVO.getBettingItem())){
                        appGameBettingVO.setItemName(codeItmeMap.get(appGameBettingVO.getBettingItem()).get(0).getItemName());
                    }
                }
                resultList.add(appGameBettingVO);
            }
        }
        return HttpRetPageArr.success("查询成功",getDataTable(resultList));
    }


    /**
     * 游戏投注记录
     */
    @PostMapping(value = "/listHistory")
    @ApiOperation(value = "游戏投注记录", notes = "游戏投注记录")
    public HttpRetPageArr<AppUserGameBettingCountVO> listHistory(@RequestParam(name = "gameId") Long gameId , @RequestParam(name = "bettingType", required = false) Integer bettingType
            , @RequestParam(name = "bettingGameType", required = false) Integer bettingGameType)
    {

        if(bettingGameType == null){
            bettingGameType = 0;
        }
        if(bettingType == null){
            bettingType = 0;
        }

        startPage();
        Long userId = SecurityUtils.getUserId();
        List<AppUserGameBettingCountVO> list = appGameBettingService.getUserCount(gameId, userId, bettingType);

        if(list != null && !list.isEmpty()){

            if(bettingGameType == 0){
                for (int i = 0; i < list.size(); i++) {
                    AppUserGameBettingCountVO appUserGameBettingCountVO = list.get(i);
                    List<AppUserGameBettingDetailsCountVO> detailsCountVOList = appGameBettingService.getUserBettingItemCount(gameId, appUserGameBettingCountVO.getGameDate(), userId, bettingType);
                    if(detailsCountVOList == null){
                        detailsCountVOList  = new ArrayList<>();
                    }
                    appUserGameBettingCountVO.setDetailsCountVOList(detailsCountVOList);
                }
            }else if(bettingGameType == 1){
                for (int i = 0; i < list.size(); i++) {

                    AppUserGameBettingCountVO appUserGameBettingCountVO = list.get(i);
                    List<AppGameBetting> bettingList = appGameBettingService.getUserBettingItem(gameId, appUserGameBettingCountVO.getGameDate(), userId, bettingType);
                    if(bettingList == null){
                        bettingList  = new ArrayList<>();
                    }
                    Map<String, AppUserGameBettingDetailsCountVO> itemMap = new HashMap<>();
                    for (int j = 0; j < bettingList.size(); j++) {
                        AppGameBetting appGameBetting =  bettingList.get(j);

                        List<AppGameItemBettingVO> itemList = JSON.parseArray(appGameBetting.getBettingItem(), AppGameItemBettingVO.class);

                        for(AppGameItemBettingVO item : itemList){
                            if(itemMap.containsKey(item.getBettingItem())){
                                AppUserGameBettingDetailsCountVO appUserGameBettingDetailsCountVO = itemMap.get(item.getBettingItem());
                                appUserGameBettingDetailsCountVO.setOrderAmount(appUserGameBettingDetailsCountVO.getOrderAmount() + item.getBettingAmount());
                                if(appGameBetting.getIsWinning() == 1){
                                    if(item.getBettingItem().equals(appUserGameBettingCountVO.getGameLotterySucc())) {
                                        appUserGameBettingDetailsCountVO.setWinAmount(appUserGameBettingDetailsCountVO.getWinAmount() + (appGameBetting.getBettingAmount() * appGameBetting.getBettingMultiple()));
                                    }
                                }else if(appGameBetting.getIsWinning() == 2){
                                    appUserGameBettingDetailsCountVO.setLoseAmount(appUserGameBettingDetailsCountVO.getLoseAmount() + item.getBettingAmount());
                                }
                                itemMap.put(item.getBettingItem(), appUserGameBettingDetailsCountVO);
                            }else{
                                AppUserGameBettingDetailsCountVO appUserGameBettingDetailsCountVO = new AppUserGameBettingDetailsCountVO();
                                appUserGameBettingDetailsCountVO.setBettingTtem(item.getBettingItem());
                                appUserGameBettingDetailsCountVO.setOrderAmount(item.getBettingAmount());
                                if(appGameBetting.getIsWinning() == 1){
                                    if(item.getBettingItem().equals(appUserGameBettingCountVO.getGameLotterySucc())){
                                        appUserGameBettingDetailsCountVO.setWinAmount(appGameBetting.getBettingAmount() * appGameBetting.getBettingMultiple());
                                    }
                                }else if(appGameBetting.getIsWinning() == 2){
                                    appUserGameBettingDetailsCountVO.setLoseAmount(item.getBettingAmount());
                                }
                                itemMap.put(item.getBettingItem(), appUserGameBettingDetailsCountVO);
                            }
                        }
                    }
                    List<AppUserGameBettingDetailsCountVO> detailsCountVOList = new ArrayList<>();
                    Set<String> set = itemMap.keySet();
                    Iterator<String> iterator = set.iterator();
                    while (iterator.hasNext()){
                        AppUserGameBettingDetailsCountVO appUserGameBettingDetailsCountVO = itemMap.get(iterator.next());
                        detailsCountVOList.add(appUserGameBettingDetailsCountVO);
                    }
                    appUserGameBettingCountVO.setDetailsCountVOList(detailsCountVOList);
                }
            }
        }
        return HttpRetPageArr.success("查询成功",getDataTable(list));
    }

    /**
     * 游戏投注记录（后台）
     */
    @PostMapping(value = "/staticsWeb")
    @ApiOperation(value = "游戏投注记录统计", notes = "游戏投注记录统计")
    public R<AppUserGameBettingStaticsVo> staticsWeb(@RequestParam(name = "gameId" , required = false) Long gameId ,
                                                                      @RequestParam(name = "userId" , required = false) Long userId,
                                                                      @RequestParam(name = "beginTime" , required = false) String beginTime,
                                                                      @RequestParam(name = "endTime" , required = false) String endTime
    )
    {
        AppUserGameBettingStaticsVo appUserGameBettingStaticsVo = new AppUserGameBettingStaticsVo();
        String date = DateUtil.format(DateUtil.date(),"yyyy-MM-dd");
        appUserGameBettingStaticsVo.setTotalAmount(appGameBettingService.sumBettingAmount(userId,0,beginTime,endTime,gameId));
        appUserGameBettingStaticsVo.setTotalCoinAmount(appGameBettingService.sumBettingAmount(userId,1,beginTime,endTime,gameId));
        appUserGameBettingStaticsVo.setToDayAmount(appGameBettingService.sumBettingAmount(userId,0,date.concat(" 00:00:00"),date.concat(" 23:59:59"),gameId));
        appUserGameBettingStaticsVo.setToDayCoinAmount(appGameBettingService.sumBettingAmount(userId,1,date.concat(" 00:00:00"),date.concat(" 23:59:59"),gameId));
        return R.ok(appUserGameBettingStaticsVo);
    }

    /**
     * 游戏投注记录（后台）
     */
    @PostMapping(value = "/listHistoryWeb")
    @ApiOperation(value = "游戏投注记录", notes = "游戏投注记录")
    public TableDataInfo<AppUserGameBettingWebCountVO> listHistoryWeb(@RequestParam(name = "gameId" , required = false) Long gameId ,
                                                                       @RequestParam(name = "userId" , required = false) Long userId ,
                                                                       @RequestParam(name = "bettingType", required = false) Integer bettingType,
                                                                      @RequestParam(name = "beginTime" , required = false) String beginTime,
                                                                      @RequestParam(name = "endTime" , required = false) String endTime
    )
    {

        startPage();
        beginTime = StringUtils.isNotBlank(beginTime)?beginTime.concat(" 00:00:00"):beginTime;
        endTime = StringUtils.isNotBlank(endTime)?endTime.concat(" 23:59:59"):endTime;
        List<AppUserGameBettingWebCountVO> list = appGameBettingService.getUserWebCount(gameId, userId, bettingType,beginTime,endTime);

        if(list != null && !list.isEmpty()){

            for (int i = 0; i < list.size(); i++) {

                AppUserGameBettingWebCountVO appUserGameBettingWebCountVO = list.get(i);

                // 单选
                if(appUserGameBettingWebCountVO.getBettingGameType() == 0){
                    List<AppUserGameBettingDetailsCountVO> detailsCountVOList = appGameBettingService.getUserBettingItemCount(appUserGameBettingWebCountVO.getGameId(),
                            appUserGameBettingWebCountVO.getGameDate(), appUserGameBettingWebCountVO.getUserId(), appUserGameBettingWebCountVO.getBettingType());
                    if(detailsCountVOList == null){
                        detailsCountVOList  = new ArrayList<>();
                    }

                    appUserGameBettingWebCountVO.setDetailsCountVOList(detailsCountVOList);
                // 写死多选
                }else if(appUserGameBettingWebCountVO.getBettingGameType() == 1){

                    List<AppGameBetting> bettingList = appGameBettingService.getUserBettingItem(appUserGameBettingWebCountVO.getGameId(),
                            appUserGameBettingWebCountVO.getGameDate(), appUserGameBettingWebCountVO.getUserId(), appUserGameBettingWebCountVO.getBettingType());
                    if(bettingList == null){
                        bettingList  = new ArrayList<>();
                    }
                    Map<String, AppUserGameBettingDetailsCountVO> itemMap = new HashMap<>();
                    for (int j = 0; j < bettingList.size(); j++) {
                        AppGameBetting appGameBetting =  bettingList.get(j);

                        List<AppGameItemBettingVO> itemList = JSON.parseArray(appGameBetting.getBettingItem(), AppGameItemBettingVO.class);

                        for(AppGameItemBettingVO item : itemList){
                            if(itemMap.containsKey(item.getBettingItem())){
                                AppUserGameBettingDetailsCountVO appUserGameBettingDetailsCountVO = itemMap.get(item.getBettingItem());
                                appUserGameBettingDetailsCountVO.setOrderAmount(appUserGameBettingDetailsCountVO.getOrderAmount() + item.getBettingAmount());
                                if(appGameBetting.getIsWinning() == 1){
                                    if(item.getBettingItem().equals(appUserGameBettingWebCountVO.getGameLotterySucc())) {
                                        appUserGameBettingDetailsCountVO.setWinAmount(appUserGameBettingDetailsCountVO.getWinAmount() + (appGameBetting.getBettingAmount() * appGameBetting.getBettingMultiple()));
                                    }
                                }else if(appGameBetting.getIsWinning() == 2){
                                    appUserGameBettingDetailsCountVO.setLoseAmount(appUserGameBettingDetailsCountVO.getLoseAmount() + item.getBettingAmount());
                                }
                                itemMap.put(item.getBettingItem(), appUserGameBettingDetailsCountVO);
                            }else{
                                AppUserGameBettingDetailsCountVO appUserGameBettingDetailsCountVO = new AppUserGameBettingDetailsCountVO();
                                appUserGameBettingDetailsCountVO.setBettingTtem(item.getBettingItem());
                                appUserGameBettingDetailsCountVO.setOrderAmount(item.getBettingAmount());
                                if(appGameBetting.getIsWinning() == 1){
                                    if(item.getBettingItem().equals(appUserGameBettingWebCountVO.getGameLotterySucc())){
                                        appUserGameBettingDetailsCountVO.setWinAmount(appGameBetting.getBettingAmount() * appGameBetting.getBettingMultiple());
                                    }
                                }else if(appGameBetting.getIsWinning() == 2){
                                    appUserGameBettingDetailsCountVO.setLoseAmount(item.getBettingAmount());
                                }
                                itemMap.put(item.getBettingItem(), appUserGameBettingDetailsCountVO);
                            }
                        }
                    }
                    List<AppUserGameBettingDetailsCountVO> detailsCountVOList = new ArrayList<>();
                    Set<String> set = itemMap.keySet();
                    Iterator<String> iterator = set.iterator();
                    while (iterator.hasNext()){
                        AppUserGameBettingDetailsCountVO appUserGameBettingDetailsCountVO = itemMap.get(iterator.next());
                        detailsCountVOList.add(appUserGameBettingDetailsCountVO);
                    }
                    appUserGameBettingWebCountVO.setDetailsCountVOList(detailsCountVOList);
                }
            }
        }
        return getDataTable(list);
    }

    private double getMultiple(int size){
        double itemMultiple;
        switch (size){
            case 1:
                itemMultiple = 8.5;
                break;
            case 2:
                itemMultiple = 4.0;
                break;
            case 3:
                itemMultiple = 2.0;
                break;
            default:
                itemMultiple = 1.0;
        }
        return itemMultiple;
    }

    /**
     * 查询用户下注记录列表
     */
    @PreAuthorize("@ss.hasPermi('business:betting:list')")
    @GetMapping("/list")
    @ApiOperation(value = "查询用户下注记录列表", notes = "获取用户下注记录列表")
    public TableDataInfo<AppGameBetting> list(AppGameBetting appGameBetting)
    {
        startPage();
        List<AppGameBetting> list = appGameBettingService.selectAppGameBettingList(appGameBetting);
        return getDataTable(list);
    }

    /**
     * 导出用户下注记录列表
     */
    @PreAuthorize("@ss.hasPermi('business:betting:export')")
    @Log(title = "用户下注记录", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    @ApiOperation(value = "导出用户下注记录列表", notes = "导出用户下注记录列表")
    public void export(HttpServletResponse response, AppGameBetting appGameBetting)
    {
        List<AppGameBetting> list = appGameBettingService.selectAppGameBettingList(appGameBetting);
        ExcelUtil<AppGameBetting> util = new ExcelUtil<AppGameBetting>(AppGameBetting.class);
        util.exportExcel(response, list, "用户下注记录数据");
    }

    /**
     * 获取用户下注记录详细信息
     */
    @PreAuthorize("@ss.hasPermi('business:betting:query')")
    @GetMapping(value = "/{id}")
    @ApiOperation(value = "获取用户下注记录详细信息", notes = "获取用户下注记录详细信息")
    public R<AppGameBetting> getInfo(@PathVariable("id") Long id)
    {
        return R.ok(appGameBettingService.selectAppGameBettingById(id));
    }

    /**
     * 新增用户下注记录
     */
    @PreAuthorize("@ss.hasPermi('business:betting:add')")
    @Log(title = "用户下注记录", businessType = BusinessType.INSERT)
    @ApiOperation(value = "新增用户下注记录", notes = "新增用户下注记录")
    @PostMapping
    public R add(@RequestBody AppGameBetting appGameBetting)
    {
        return R.ok(appGameBettingService.insertAppGameBetting(appGameBetting));
    }

    /**
     * 修改用户下注记录
     */
    @PreAuthorize("@ss.hasPermi('business:betting:edit')")
    @Log(title = "用户下注记录", businessType = BusinessType.UPDATE)
    @ApiOperation(value = "修改用户下注记录", notes = "修改用户下注记录")
    @PutMapping
    public R edit(@RequestBody AppGameBetting appGameBetting)
    {
        return R.ok(appGameBettingService.updateAppGameBetting(appGameBetting));
    }

    /**
     * 删除用户下注记录
     */
    @PreAuthorize("@ss.hasPermi('business:betting:remove')")
    @Log(title = "用户下注记录", businessType = BusinessType.DELETE)
    @ApiOperation(value = "删除用户下注记录", notes = "删除用户下注记录")
    @DeleteMapping("/{ids}")
    public R remove(@PathVariable Long[] ids)
    {
        return R.ok(appGameBettingService.deleteAppGameBettingByIds(ids));
    }
}
