package com.game.business.task;

import cn.hutool.core.util.IdUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.game.business.domain.*;
import com.game.business.service.*;
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.domain.HttpRet;
import com.game.common.core.redis.RedisCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

@Component
public class AppAgentGameBettingTask {

    @Autowired
    private IAppUserAgentService appUserAgentService;

    @Autowired
    private IAppGameCommissionService appGameCommissionService;

    @Autowired
    private IAppUserGameRecordCountService appUserGameRecordCountService;

    @Autowired
    private IAppGameBettingService appGameBettingService;

    @Autowired
    private IFinTranRecordService finTranRecordService;

    @Autowired
    private IAppUserService appUserService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private IAppUserCountService appUserCountService;

    @Autowired
    private AppUserCountTask appUserCountTask;

    @Async("asyncExecutor")
    public void agentGameBettingTask(AppGameBetting appGameBetting) throws Exception {

        List<AppUserGameRecordCount> recordCountList = new ArrayList<>();

        // 主播分佣
        liveCommissionHandler(appGameBetting, recordCountList);

        AppUserAgent userIdObject = new AppUserAgent();
        userIdObject.setUserId(appGameBetting.getUserId());
        List<AppUserAgent> userAgents = appUserAgentService.selectAppUserAgentList(userIdObject);
        if(userAgents == null || userAgents.isEmpty()){
            return;
        }

        AppUserAgent userAgent = userAgents.get(0);

        List<AppGameCommission> gameRateList = new ArrayList<>();

        getGameRate(appGameBetting.getGameId(), userAgent.getPid(), userAgent.getUserId(), gameRateList);
        if(gameRateList.isEmpty()){
            AppUserGameRecordCount recordCount = new AppUserGameRecordCount();
            recordCount.setGameId(appGameBetting.getGameId());
            recordCount.setUserId(appGameBetting.getUserId());
            recordCount.setPid(userAgent.getPid());
            recordCount.setCommission(0.00);
            recordCount.setGameRate(0.00);
            recordCount.setType(0);
            recordCount.setGameDate(appGameBetting.getGameDate());
            recordCount.setCreateTime(new Date());
            recordCountList.add(recordCount);
            appUserCountService.staticsUserBetting(appGameBetting, recordCountList);
            return;
        }

        commissionHandler(gameRateList, appGameBetting, recordCountList);

        //统计游戏下注、返佣情况
        appUserCountService.staticsUserBetting(appGameBetting,recordCountList);

        //更新用户充值是否满足流水
        appUserCountTask.calculationWithdraw(appGameBetting.getUserId());

    }

    private void getGameRate(Long gameId, Long pid, Long userId, List<AppGameCommission> gameRateList){

        AppGameCommission commissionWhere = new AppGameCommission();
        commissionWhere.setPid(pid);
        commissionWhere.setUserId(userId);
        commissionWhere.setGameId(gameId);

        List<AppGameCommission> gameCommissions = appGameCommissionService.selectAppGameCommissionList(commissionWhere);
        if(gameCommissions == null || gameCommissions.isEmpty()){
            return;
        }

        AppGameCommission gameCommission = gameCommissions.get(0);
        if(gameCommission.getGameRate() == null){
            gameCommission.setGameRate(0.00);
        }

        gameRateList.add(gameCommission);

        AppUserAgent userIdObject = new AppUserAgent();
        userIdObject.setUserId(pid);
        List<AppUserAgent> userAgents = appUserAgentService.selectAppUserAgentList(userIdObject);

        if(userAgents == null || userAgents.isEmpty()){
            return;
        }

        AppUserAgent userAgent = userAgents.get(0);

        getGameRate(gameId, userAgent.getPid(), userAgent.getUserId(), gameRateList);

    }

    @DSTransactional
    public void commissionHandler(List<AppGameCommission> gameRateList, AppGameBetting appGameBetting, List<AppUserGameRecordCount> recordCountList) throws Exception {

        // 升序排序
        gameRateList.stream().sorted(Comparator.comparing(AppGameCommission::getGameRate));

        AppGameCommission topCommission = gameRateList.get(gameRateList.size() - 1);
        BigDecimal bettingAmount = new BigDecimal(appGameBetting.getBettingAmount() + "");
        BigDecimal gameRate = new BigDecimal((topCommission.getGameRate() / 100.00) + "");

        // 总佣金
        BigDecimal bettingCommission = bettingAmount.multiply(gameRate).setScale(1, RoundingMode.DOWN);

        AppGameBetting updateBettingCommission = new AppGameBetting();
        updateBettingCommission.setId(appGameBetting.getId());
        updateBettingCommission.setBettingCommission(bettingCommission.doubleValue());
        updateBettingCommission.setUpdateTime(new Date());
        appGameBettingService.updateById(updateBettingCommission);

        double indexCommission = 0;

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

            // 分佣
            AppGameCommission appGameCommission = gameRateList.get(i);
            AppUser appUser = appUserService.selectAppUserByUserid(appGameCommission.getUserId());
            if(appUser == null){
                continue;
            }

            BigDecimal userGgameRate = new BigDecimal("0");
            BigDecimal userCommission = new BigDecimal("0");

            if(appGameCommission.getGameRate() > 0){
                // 计算佣金
                userGgameRate = new BigDecimal(((appGameCommission.getGameRate() - indexCommission) / 100.00) + "").setScale(4, RoundingMode.DOWN);
                userCommission = bettingAmount.multiply(userGgameRate).setScale(4, RoundingMode.DOWN);
            }

            // 上一次费率
            indexCommission = appGameCommission.getGameRate();

            // 更新用户余额
            //if(appGameBetting.getBettingType() == 0){
            //    appUser.setDiamondCoin(appUser.getDiamondCoin() + userCommission.doubleValue());
            //    appUser.setDiamondCoinTotal(appUser.getDiamondCoinTotal() + userCommission.doubleValue());
            //    appUser.setDiamondCoinCash(appUser.getDiamondCoinCash() + userCommission.doubleValue());

            // 更新用户金币
            //}else{
            //    appUser.setCoin(appUser.getCoin() + userCommission.doubleValue());
            //    appUser.setCoinCash(appUser.getCoinCash() + userCommission.doubleValue());
            //}

            //appUserService.updateAppUser(appUser);

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

            AppUserGameRecordCount appUserGameRecordCount = new AppUserGameRecordCount();
            appUserGameRecordCount.setGameId(appGameBetting.getGameId());
            appUserGameRecordCount.setGameDate(appGameBetting.getGameDate());
            appUserGameRecordCount.setUserId(appUser.getUserid());
            appUserGameRecordCount.setPid(appUser.getPid());
            appUserGameRecordCount.setCreateTime(new Date());
            appUserGameRecordCount.setType(0);
            appUserGameRecordCount.setGameRate(userGgameRate.doubleValue());
            appUserGameRecordCount.setCommission(userCommission.doubleValue());

            appUserGameRecordCountService.save(appUserGameRecordCount);
            recordCountList.add(appUserGameRecordCount);

            FinTranRecord finTranRecord = new FinTranRecord();
            //finTranRecord.setAfterDiamondCoin(appUser.getDiamondCoin());
            //finTranRecord.setAfterCoin(appUser.getCoin());

            if(appGameBetting.getBettingType() == 0){
                finTranRecord.setCurrencyType(4);
                finTranRecord.setDiamondCoinChange(userCommission.doubleValue());
                finTranRecord.setCoinChange(0.00);
            }else{
                finTranRecord.setCurrencyType(2);
                finTranRecord.setCoinChange(userCommission.doubleValue());
                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.setFromUid(appGameBetting.getUserId());

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

            finTranRecord.setTranGroupId(appGameBetting.getId());

            if(appGameBetting.getBettingType() == 0){
                finTranRecord.setTranType1(FinTranType1.U_Income_Coin_Balance.getType());
            }else{
                finTranRecord.setTranType1(FinTranType1.U_Income_Coin.getType());
            }
            finTranRecord.setTranType2(FinTranType2.REWARD_Income.getType());
            finTranRecord.setTranType3(FinTranType3.RECOMMEND_ADD_AMOUNT.getType());

            finTranRecord.setRemarks("游戏分佣");

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

            finTranRecord.setCreateTime(new Date());

            finTranRecord.setFromUid(appGameBetting.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(appGameBetting.getId());
            //finTranRecordService.insertFinTranRecord(finTranRecord);
            appUserService.updateUserAmount(finTranRecord,true,false);
        }
    }

    @DSTransactional
    public void liveCommissionHandler(AppGameBetting appGameBetting, List<AppUserGameRecordCount> recordCountList) throws Exception {

        if(appGameBetting.getIsLive() == 0){
            return;
        }

        AppUser appUser = appUserService.selectAppUserByUserid(appGameBetting.getLiveUserId());
        if(appUser == null){
            return;
        }

        // 主播分佣
        double gameRateAmount = appGameBetting.getBettingAmount() * 0.003;
        gameRateAmount = new BigDecimal(gameRateAmount + "").setScale(4, RoundingMode.DOWN).doubleValue();

        // 更新用户余额
        //if(appGameBetting.getBettingType() == 0){
        //    appUser.setDiamondCoin(appUser.getDiamondCoin() + gameRateAmount);
        //    appUser.setDiamondCoinTotal(appUser.getDiamondCoinTotal() + gameRateAmount);
        //    appUser.setDiamondCoinCash(appUser.getDiamondCoinCash() + gameRateAmount);
        // 更新用户金币
        //}else{
        //    appUser.setCoin(appUser.getCoin() + gameRateAmount);
        //    appUser.setCoinCash(appUser.getCoinCash() + gameRateAmount);
        //}
        //appUserService.updateAppUser(appUser);

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

        AppUserGameRecordCount appUserGameRecordCount = new AppUserGameRecordCount();
        appUserGameRecordCount.setGameId(appGameBetting.getGameId());
        appUserGameRecordCount.setGameDate(appGameBetting.getGameDate());
        appUserGameRecordCount.setUserId(appUser.getUserid());
        appUserGameRecordCount.setPid(appUser.getPid());
        appUserGameRecordCount.setCreateTime(new Date());
        appUserGameRecordCount.setType(1);
        appUserGameRecordCount.setGameRate(0.003);
        appUserGameRecordCount.setCommission(gameRateAmount);

        appUserGameRecordCountService.save(appUserGameRecordCount);
        recordCountList.add(appUserGameRecordCount);

        FinTranRecord finTranRecord = new FinTranRecord();

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

        if(appGameBetting.getBettingType() == 0){
            finTranRecord.setCurrencyType(4);
            finTranRecord.setDiamondCoinChange(gameRateAmount);
            finTranRecord.setCoinChange(0.00);
        }else{
            finTranRecord.setCurrencyType(2);
            finTranRecord.setCoinChange(gameRateAmount);
            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.setFromUid(appGameBetting.getUserId());

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

        finTranRecord.setTranGroupId(appGameBetting.getId());
        if(appGameBetting.getBettingType() == 0){
            finTranRecord.setTranType1(FinTranType1.U_Income_Coin_Balance.getType());
        }else{
            finTranRecord.setTranType1(FinTranType1.U_Income_Coin.getType());
        }

        finTranRecord.setTranType2(FinTranType2.REWARD_Income.getType());
        finTranRecord.setTranType3(FinTranType3.RECOMMEND_ADD_AMOUNT.getType());

        finTranRecord.setRemarks("游戏分佣");

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

        finTranRecord.setCreateTime(new Date());

        finTranRecord.setFromUid(appGameBetting.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(appGameBetting.getId());
        //finTranRecordService.insertFinTranRecord(finTranRecord);
        appUserService.updateUserAmount(finTranRecord,false);

    }

}
