package com.game.business.task;

import com.alibaba.fastjson.JSONObject;
import com.game.business.domain.AppGame;
import com.game.business.domain.AppGameItem;
import com.game.business.domain.AppGameLottery;
import com.game.business.service.IAppGameBettingService;
import com.game.business.service.IAppGameItemService;
import com.game.business.service.IAppGameLotteryService;
import com.game.business.service.IAppGameService;
import com.game.business.vo.AppUserGameBettingDetailsCountVO;
import com.game.business.websocket.server.WebSocketServer;
import com.game.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Component
public class AppGameLotteryAutoTask {

    @Autowired
    private IAppGameBettingService appGameBettingService;

    @Autowired
    private IAppGameItemService appGameItemService;

    @Autowired
    private IAppGameLotteryService appGameLotteryService;

    @Autowired
    private AppGameLotteryTask appGameLotteryTask;

    @Autowired
    private IAppGameService appGameService;

    @Autowired
    private WebSocketServer webSocketServer;

    @Async("asyncExecutor")
    public void autoTask(Long gameId){

        try {

            AppGame appGame = appGameService.selectAppGameById(gameId);
            if (appGame == null) return;

            // 是否已开奖
            AppGameLottery dbAppGameLottery = appGameLotteryService.selectLottery(appGame.getClassifyId(), appGame.getId(), appGame.getGameDate());
            if(dbAppGameLottery != null && dbAppGameLottery.getIsLottery() == 1){
                return;
            }

            String gameDate = appGame.getGameDate();

            Map<String, Double> dateBetting = appGameBettingService.getBettingAmountByDate(gameId, DateUtils.dateTime(new Date()));

            // 余额投注总输赢
            BigDecimal diamondCoinSum = new BigDecimal(dateBetting.get("diamondCoinSum") + "");
            BigDecimal diamondCoinWin = new BigDecimal(dateBetting.get("diamondCoinWin") + "");
            BigDecimal diamondCoinLose = new BigDecimal(dateBetting.get("diamondCoinLose") + "");

            // 金币投注总输赢
            BigDecimal coinSum = new BigDecimal(dateBetting.get("coinSum") + "");
            BigDecimal coinWin = new BigDecimal(dateBetting.get("coinWin") + "");
            BigDecimal coinLose = new BigDecimal(dateBetting.get("coinLose") + "");

            if(coinSum.compareTo(BigDecimal.ZERO) > 0){
                diamondCoinSum = diamondCoinSum.add(coinSum.divide(new BigDecimal("100.00")).setScale(2, BigDecimal.ROUND_HALF_UP));
            }

            if(coinWin.compareTo(BigDecimal.ZERO) > 0){
                diamondCoinWin = diamondCoinWin.add(coinWin.divide(new BigDecimal("100.00")).setScale(2, BigDecimal.ROUND_HALF_UP));
            }

            if(coinLose.compareTo(BigDecimal.ZERO) > 0){
                diamondCoinLose = diamondCoinLose.add(coinLose.divide(new BigDecimal("100.00")).setScale(2, BigDecimal.ROUND_HALF_UP));
            }

            // 余额选项投注详情
            List<AppUserGameBettingDetailsCountVO> diamondCoinBettingDetailsList = appGameBettingService.getBettingAmountByGameDate(gameId, gameDate, 0);
            Map<String, List<AppUserGameBettingDetailsCountVO>> diamondCoinMap = null;
            double diamondCoinGameDateSum = 0.0;
            if(diamondCoinBettingDetailsList != null && !diamondCoinBettingDetailsList.isEmpty()){
                diamondCoinMap = diamondCoinBettingDetailsList.stream().collect(Collectors.groupingBy(AppUserGameBettingDetailsCountVO::getBettingTtem));
                diamondCoinGameDateSum = diamondCoinBettingDetailsList.stream().mapToDouble(AppUserGameBettingDetailsCountVO::getOrderAmount).sum();
            }

            // 金币选项投注详情
            List<AppUserGameBettingDetailsCountVO> coinBettingDetailsList = appGameBettingService.getBettingAmountByGameDate(gameId, gameDate, 1);
            Map<String, List<AppUserGameBettingDetailsCountVO>> coinMap = null;
            if(coinBettingDetailsList != null && !coinBettingDetailsList.isEmpty()){
                coinMap = coinBettingDetailsList.stream().collect(Collectors.groupingBy(AppUserGameBettingDetailsCountVO::getBettingTtem));
                double coinGameDateSum = diamondCoinBettingDetailsList.stream().mapToDouble(AppUserGameBettingDetailsCountVO::getOrderAmount).sum();
                if(coinGameDateSum > 0){
                    diamondCoinGameDateSum += coinGameDateSum / 100;
                }
            }

            AppGameItem appGameItem = new AppGameItem();
            appGameItem.setGameId(gameId);
            List<AppGameItem> itemList = appGameItemService.selectAppGameItemList(appGameItem);

            double itemMultiple = 0;
            for(AppGameItem item : itemList){
                itemMultiple += item.getItemMultiple();
            }

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

            for(AppGameItem item : itemList){
                Double rete = itemMultiple * 100 / item.getItemMultiple();
                int int_rate = rete.intValue();
                for (int i = 0; i < int_rate; i++) {
                    pools.add(item.getItemLocation());
                }
            }

            //随机开奖
            Collections.shuffle(pools);

            int index = new Random().nextInt(pools.size());
            String lottertSucc = pools.get(index);

            AppGameItem gameItem = appGameItemService.selectAppGameItemByGameIdAndItemLocation(gameId, lottertSucc);

            double lottertAmount = 0.0;
            if(diamondCoinMap != null && diamondCoinMap.containsKey(lottertSucc)){
                AppUserGameBettingDetailsCountVO detailsCountVO = diamondCoinMap.get(lottertSucc).get(0);
                lottertAmount = detailsCountVO.getOrderAmount() * gameItem.getItemMultiple();
            }

            if(coinMap != null && coinMap.containsKey(lottertSucc)){
                AppUserGameBettingDetailsCountVO detailsCountVO = coinMap.get(lottertSucc).get(0);
                lottertAmount += detailsCountVO.getOrderAmount() / 100.00 * gameItem.getItemMultiple();;
            }

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

            // 开奖次数
            long count = appGameLotteryService.selectCountAuto(appGame.getClassifyId(), appGame.getId(), DateUtils.dateTime(new Date()));

            // 开始走最低开盘
            if(count > 500 && diamondCoinWin.subtract(diamondCoinSum.multiply(new BigDecimal("0.8"))).compareTo(BigDecimal.ZERO) > 0){

                // 随机开奖
                if(lottertAmount - diamondCoinGameDateSum > 0){

                    for (AppGameItem item : itemList) {
                        double orderAmount = 0.0;

                        if(diamondCoinMap != null){
                            if(diamondCoinMap.containsKey(item.getItemLocation())){
                                AppUserGameBettingDetailsCountVO detailsCountVO = diamondCoinMap.get(item.getItemLocation()).get(0);
                                orderAmount += detailsCountVO.getOrderAmount();
                            }
                        }

                        if(coinMap != null){
                            if(coinMap.containsKey(item.getItemLocation())){
                                AppUserGameBettingDetailsCountVO detailsCountVO = coinMap.get(item.getItemLocation()).get(0);
                                orderAmount += detailsCountVO.getOrderAmount() / 100.00;
                            }
                        }

                        if(orderAmount == 0 || (orderAmount * itemMultiple) - diamondCoinGameDateSum <= 0){
                            itemPools.add(item.getItemLocation());
                        }
                    }
                }
            }

            if(!itemPools.isEmpty()){
                index = new Random().nextInt(itemPools.size());
                lottertSucc = pools.get(index);
            }

            JSONObject gameLottery = new JSONObject();
            gameLottery.put("type", "2");
            gameLottery.put("gameLottery", lottertSucc);
            webSocketServer.sendMessageAll(gameLottery.toJSONString());


            // 保存开奖记录
            AppGameLottery appGameLottery = appGameLotteryService.selectLottery(appGame.getClassifyId(), appGame.getId(), gameDate);

            if(appGameLottery == null){
                // 保存开奖记录
                appGameLottery = new AppGameLottery();
                appGameLottery.setGameId(appGame.getId());
                appGameLottery.setClassId(appGame.getClassifyId());
                appGameLottery.setGameDate(gameDate);
                appGameLottery.setIsLottery(1);
                appGameLottery.setGameRecordDate(new Date());
                appGameLottery.setGameLotterySucc(lottertSucc);
                appGameLotteryService.save(appGameLottery);
            }else{
                if(appGameLottery.getIsLottery() == 1){
                    return;
                }

                Date RecordDate = new Date();

                appGameLottery.setIsLottery(1);
                appGameLottery.setGameLotterySucc(lottertSucc);
                appGameLottery.setGameRecordDate(RecordDate);

                AppGameLottery updateAppGameLottery = new AppGameLottery();
                updateAppGameLottery.setId(appGameLottery.getId());
                updateAppGameLottery.setIsLottery(1);
                updateAppGameLottery.setGameRecordDate(RecordDate);
                updateAppGameLottery.setGameLotterySucc(lottertSucc);
                appGameLotteryService.updateById(updateAppGameLottery);
            }

            appGameLotteryTask.updateLottery(appGameLottery);

        }catch (Exception e){
            e.printStackTrace();
        }
    }

    @Async("asyncExecutor")
    public void updateAppGameTime(Long classId, Long gameId,int countdown) throws IOException {

        String time = "00:";
        if(countdown < 10){
            time = time + "0" + countdown;
        }else{
            time = time + countdown;
        }

        AppGame appGame = new AppGame();
        appGame.setId(gameId);
        appGame.setGameTime(time);

        if(countdown == 2){

            appGame.setGameDate(DateUtils.getTime());

            JSONObject dateJson = new JSONObject();
            dateJson.put("type", "3");
            dateJson.put("gameDate", appGame.getGameDate());
            webSocketServer.sendMessageAll(dateJson.toJSONString());

            AppGameLottery appGameLottery = new AppGameLottery();
            appGameLottery.setGameId(appGame.getId());
            appGameLottery.setClassId(classId);
            appGameLottery.setGameDate(appGame.getGameDate());
            appGameLottery.setIsLottery(0);
            appGameLottery.setGameRecordDate(new Date());
            appGameLotteryService.save(appGameLottery);
        }

        appGameService.updateAppGame(appGame);
    }
}
