package com.game.business.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.thread.ThreadUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Date;
import java.util.function.Function;
import java.util.stream.Collectors;

import com.game.business.domain.*;
import com.game.business.service.*;
import com.game.business.task.AppUserCountTask;
import com.game.common.constant.AppSceneType;
import com.game.common.constant.CacheConstants;
import com.game.common.constant.finance.FinTranAddedInfo;
import com.game.common.constant.finance.FinTranType1;
import com.game.common.constant.finance.FinTranType3;
import com.game.common.constant.finance.TranCurrencyType;
import com.game.common.core.domain.HttpRet;
import com.game.common.core.redis.RedisCache;
import com.game.common.exception.ServiceException;
import com.game.common.utils.DateUtils;
import com.game.common.utils.SecurityUtils;
import com.game.common.utils.StringUtils;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import com.game.business.mapper.AppUserCountDividendMapper;
import com.game.common.annotation.DataSource;
import com.game.common.enums.DataSourceType;
import org.springframework.transaction.annotation.Transactional;

/**
 * 用户代理分红Service业务层处理
 *
 * @author game
 * @date 2024-06-30
 */
@Service
@Log4j2
public class AppUserCountDividendServiceImpl extends ServiceImpl<AppUserCountDividendMapper, AppUserCountDividend> implements IAppUserCountDividendService {
    @Autowired
    private AppUserCountDividendMapper appUserCountDividendMapper;
    @Autowired
    private IAppUserService appUserService;
    @Autowired
    private IFinTranRecordService finTranRecordService;
    @Autowired
    private IAppUserCountService appUserCountService;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private IAppUserAgentService appUserAgentService;
    @Autowired
    private AppUserCountTask appUserCountTask;

    /**
     * 查询用户代理分红
     *
     * @param id 用户代理分红主键
     * @return 用户代理分红
     */
    @Override
    public AppUserCountDividend selectAppUserCountDividendById(Long id) {
        return appUserCountDividendMapper.selectAppUserCountDividendById(id);
    }

    /**
     * 查询用户代理分红列表
     *
     * @param appUserCountDividend 用户代理分红
     * @return 用户代理分红
     */
    @Override
    public List<AppUserCountDividend> selectAppUserCountDividendList(AppUserCountDividend appUserCountDividend) {
        return appUserCountDividendMapper.selectAppUserCountDividendList(appUserCountDividend);
    }

    /**
     * 新增用户代理分红
     *
     * @param appUserCountDividend 用户代理分红
     * @return 结果
     */
    @Override
    @Transactional
    public void insertAppUserCountDividend(AppUserCountDividend appUserCountDividend) {
                appUserCountDividend.setCreateTime(DateUtils.getNowDate());
          LambdaQueryWrapper<AppUserCountDividend> queryWrapper = new LambdaQueryWrapper<>();
          queryWrapper.eq(AppUserCountDividend::getUserId, appUserCountDividend.getUserId());
          queryWrapper.eq(AppUserCountDividend::getDateNo, appUserCountDividend.getDateNo());
          AppUserCountDividend userCountDividend = appUserCountDividendMapper.selectOne(queryWrapper);
          if (userCountDividend == null) {
              appUserCountDividend.setCreateTime(DateUtils.getNowDate());
              appUserCountDividendMapper.insert(appUserCountDividend);
          }else if(userCountDividend.getStatus().intValue() == 0){
              appUserCountDividend.setUpdateTime(DateUtils.getNowDate());
              appUserCountDividend.setId(userCountDividend.getId());
              appUserCountDividendMapper.updateById(appUserCountDividend);
          }else{
              log.warn("当前用户已发放分红，无法更新未发放");
          }
    }

    /**
     * 修改用户代理分红
     *
     * @param appUserCountDividend 用户代理分红
     * @return 结果
     */
    @Override
    public int updateAppUserCountDividend(AppUserCountDividend appUserCountDividend) {
                appUserCountDividend.setUpdateTime(DateUtils.getNowDate());
        return appUserCountDividendMapper.updateAppUserCountDividend(appUserCountDividend);
    }

    /**
     * 批量删除用户代理分红
     *
     * @param ids 需要删除的用户代理分红主键
     * @return 结果
     */
    @Override
    public int deleteAppUserCountDividendByIds(Long[] ids) {
        return appUserCountDividendMapper.deleteAppUserCountDividendByIds(ids);
    }

    /**
     * 删除用户代理分红信息
     *
     * @param id 用户代理分红主键
     * @return 结果
     */
    @Override
    public int deleteAppUserCountDividendById(Long id) {
        return appUserCountDividendMapper.deleteAppUserCountDividendById(id);
    }

    @Override
    public List<AppUserCountDividend> selectUserDividendList(Long pid,Long userId,String dateNum,Integer status) {
        //需求变动  只展示和发放上一周期数据
        String day = DateUtil.format(DateUtil.date(),"dd");
        if(Integer.parseInt(day) > 15){
            //下半月上一周期是15号
            dateNum = DateUtil.format(DateUtil.date(),"yyyy-MM").concat("-15");
        }else{
            //上半月上一周期为上个月月底
            dateNum = DateUtil.format(DateUtil.endOfMonth(DateUtil.offsetMonth(DateUtil.date(),-1)),"yyyy-MM-dd");
        }
        List<AppUserCountDividend> dividendList = appUserCountDividendMapper.selectUserDividendList(pid,userId,dateNum,status);
        if(null != dividendList && dividendList.size()>0){
            List<Long> ids = dividendList.stream().map(AppUserCountDividend::getUserId).collect(Collectors.toList());
            List<AppUser> userList = appUserService.selectListByIds(ids);
            if(null != userList && userList.size()>0){
                Map<String,AppUser> userMap = userList.stream().collect(Collectors.toMap(e->String.valueOf(e.getUserid()), Function.identity(),(k1,k2)->k2));
                dividendList.forEach(e->{
                    AppUser appUser = userMap.get(String.valueOf(e.getUserId()));
                    if(null != appUser){
                        e.setNickName(appUser.getNickname());
                    }
                });
            }
        }
        return dividendList;
    }

    @Override
    public HttpRet<Boolean> send(String userId, String dateNo,Long sendUserId) {
        List<AppUserCountDividend> dividendList = this.selectUserDividendList(sendUserId, StringUtils.isBlank(userId)?null:Long.parseLong(userId),dateNo,0);
        if(null == dividendList || dividendList.size() < 1){
            return HttpRet.fail("发放失败，不存在或已发放");
        }
        if(StringUtils.isNotBlank(userId) && dividendList.size() == 1 && dividendList.get(0).getDiamondCoin() < 1 && dividendList.get(0).getCoin() < 1){
            return HttpRet.fail("发放失败，金额为0");
        }
        /*dividendList = dividendList.stream().filter(e->e.getStatus().intValue() == 0).collect(Collectors.toList());
        if(dividendList.size() < 1){
            return HttpRet.fail("发放失败，不存在或已发放");
        }*/
        AppUser user = appUserService.selectAppUserByUserid(sendUserId);
        double totalAmount = dividendList.stream().mapToDouble(e->e.getDiamondCoin()).sum();
        if(user.getDiamondCoin() < totalAmount){
            return HttpRet.fail("发放失败，余额不足，还差" + (totalAmount - user.getDiamondCoin()));
        }
        double coinTotal = dividendList.stream().mapToDouble(e->e.getCoin()).sum();
        if(user.getCoin() < coinTotal){
            return HttpRet.fail("发放失败，金币不足, 还差" + (coinTotal - user.getCoin()));
        }
        List<Long> userIds = new ArrayList<>();
        userIds.add(sendUserId);
        //开始发放
        List<Long> ids = dividendList.stream().map(AppUserCountDividend::getUserId).collect(Collectors.toList());
        userIds.addAll(ids);
        List<AppUser> userList = appUserService.selectListByIds(ids);
        if(null != userList && userList.size()>0) {
            Map<String, AppUser> userMap = userList.stream().collect(Collectors.toMap(e -> String.valueOf(e.getUserid()), Function.identity(), (k1, k2) -> k2));
            String errMsg = "";
            for(AppUserCountDividend countDividend : dividendList){
                Long errUserId = countDividend.getUserId();
                if(countDividend.getStatus().intValue() != 0){
                    continue;
                }
                try {
                    AppUser appUser = userMap.get(String.valueOf(countDividend.getUserId()));
                    AppUser curUser = appUserService.selectAppUserByUserid(sendUserId);
                    if(!sendUserId.equals(appUser.getPid())){
                        throw new ServiceException("只能给直属团队成员发放");
                    }
                    /*AppUser updateAppUser = new AppUser();
                    AppUser curUpdateAppUser = new AppUser();//当前用户*/
                    //                updateAppUser.setUserid(appUser.getUserid());
                    if (null != countDividend.getDiamondCoin() && countDividend.getDiamondCoin() > 0) {
                        if(null != countDividend.getDiamondCoin() && curUser.getDiamondCoin() < countDividend.getDiamondCoin()){
                            throw new ServiceException("余额不足");
                        }
                        //扣减发放用户
                        /*curUser.setDiamondCoinCash(curUser.getDiamondCoinCash() - MoneyUtils.consumeCash(curUser.getDiamondCoin(),curUser.getDiamondCoinCash(),e.getDiamondCoin()));
                        curUser.setDiamondCoin(curUser.getDiamondCoin() - e.getDiamondCoin());
                        curUser.setDiamondCoinTotal(curUser.getDiamondCoinTotal() - e.getDiamondCoin());
                        curUpdateAppUser.setUserid(curUser.getUserid());
                        curUpdateAppUser.setDiamondCoinCash(curUser.getDiamondCoinCash());
                        curUpdateAppUser.setDiamondCoin(curUser.getDiamondCoin());
                        curUpdateAppUser.setDiamondCoinTotal(curUser.getDiamondCoinTotal());*/
                        //发放用户扣减流水
                        FinTranAddedInfo curAddedInfo = FinTranAddedInfo.createTranInfo(appUser.getUserid(), 0, 0, AppSceneType.Scene_None, "");
                        FinTranRecord curTran = FinTranRecord.initFinTranRecordSomeParams(curAddedInfo, FinTranType3.AGENT_DIVIDED, FinTranType1.U_Outcome_Balance, curUser);
                        curTran.setDiamondCoinChange(countDividend.getDiamondCoin() * -1);
                        //                    curTran.setAfterDiamondCoin(curUser.getDiamondCoin());
                        curTran.setCurrencyType(TranCurrencyType.Balance.getType());
                        curTran.setRemarks(countDividend.getDateNo() + " 发放团队分红奖励");
                        curTran.setFromUid(sendUserId);
//                        tranRecordList.add(curTran);
                        appUserService.updateUserAmount(curTran,true);

                        //受益用户
                        /*updateAppUser.setDiamondCoin(appUser.getDiamondCoin() + e.getDiamondCoin());
                        updateAppUser.setDiamondCoinTotal(appUser.getDiamondCoinTotal() + e.getDiamondCoin());
                        updateAppUser.setDiamondCoinCash(appUser.getDiamondCoinCash() + e.getDiamondCoin());*/
                        //流水 余额
                        FinTranAddedInfo addedInfo = FinTranAddedInfo.createTranInfo(appUser.getUserid(), 0, 0, AppSceneType.Scene_None, "");
                        FinTranRecord tran = FinTranRecord.initFinTranRecordSomeParams(addedInfo, FinTranType3.AGENT_DIVIDED, FinTranType1.Agent_Income_Diamond_Coin, appUser);
                        tran.setDiamondCoinChange(countDividend.getDiamondCoin());
                        tran.setAfterDiamondCoin(appUser.getDiamondCoin() + countDividend.getDiamondCoin());
                        tran.setCurrencyType(TranCurrencyType.Balance.getType());
                        tran.setRemarks(countDividend.getDateNo() + " 团队周分红奖励");
                        tran.setFromUid(sendUserId);
                        //                    tranRecordList.add(tran);
                        appUserService.updateUserAmount(tran,true,true);
                    }
                    if (null != countDividend.getCoin() && countDividend.getCoin() > 0) {
                        if(null != countDividend.getCoin() && curUser.getCoin() < countDividend.getCoin()){
                            throw new ServiceException("金币不足");
                        }
                        //扣减发放用户
                        /*curUser.setCoinCash(curUser.getCoinCash() - MoneyUtils.consumeCash(curUser.getCoin(),curUser.getCoinCash(),e.getCoin()));
                        curUser.setCoin(curUser.getCoin() - e.getCoin());
                        curUpdateAppUser.setUserid(curUser.getUserid());
                        curUpdateAppUser.setCoinCash(curUser.getCoinCash());
                        curUpdateAppUser.setCoin(curUser.getCoin());*/
                        //发放用户扣减流水
                        FinTranAddedInfo curAddedInfo = FinTranAddedInfo.createTranInfo(appUser.getUserid(), 0, 0, AppSceneType.Scene_None, "");
                        FinTranRecord curTran = FinTranRecord.initFinTranRecordSomeParams(curAddedInfo, FinTranType3.AGENT_DIVIDED, FinTranType1.U_Outcome_Coin, curUser);
                        curTran.setDiamondCoinChange(countDividend.getDiamondCoin() * -1);
                        //                    curTran.setAfterCoin(curUser.getCoin());
                        curTran.setCurrencyType(TranCurrencyType.Coin.getType());
                        curTran.setRemarks(countDividend.getDateNo() + " 发放团队分红奖励");
                        curTran.setFromUid(sendUserId);
//                        tranRecordList.add(curTran);
                        appUserService.updateUserAmount(curTran,true);

                        //                    updateAppUser.setCoin(appUser.getDiamondCoin() + e.getDiamondCoin());
                        //流水 余额
                        FinTranAddedInfo addedInfo = FinTranAddedInfo.createTranInfo(appUser.getUserid(), 0, 0, AppSceneType.Scene_None, "");
                        FinTranRecord tran = FinTranRecord.initFinTranRecordSomeParams(addedInfo, FinTranType3.AGENT_DIVIDED, FinTranType1.Agent_Income_Coin, appUser);
                        tran.setDiamondCoinChange(countDividend.getDiamondCoin());
                        //                    tran.setAfterDiamondCoin(appUser.getDiamondCoin() + e.getDiamondCoin());
                        tran.setCurrencyType(TranCurrencyType.Coin.getType());
                        tran.setRemarks(countDividend.getDateNo() + " 团队周分红奖励");
                        tran.setFromUid(sendUserId);
                        appUserService.updateUserAmount(tran,true);
                        //                    tranRecordList.add(tran);
                    }
                    /*appUserService.updateAppUser(updateAppUser);
                    appUserService.updateAppUser(curUpdateAppUser);*/
                    //清除用户缓存
                    //                redisCache.deleteObject("U:UserInfo:".concat(String.valueOf(appUser.getUserid())));
                    /*if(tranRecordList.size() > 0){
                     *//*tranRecordList.forEach(t->{
    //                        finTranRecordService.insertFinTranRecord(t);
                            appUserService.updateUserAmount(t);
                        });*//*
                        for(FinTranRecord finTranRecord :tranRecordList){
                            try {
                                appUserService.updateUserAmount(finTranRecord);
                            } catch (Exception ex) {
                                throw new RuntimeException(ex);
                            }
                        }
                    }*/
                    AppUserCountDividend userCountDividend = new AppUserCountDividend();
                    userCountDividend.setId(countDividend.getId());
                    userCountDividend.setStatus(1);
                    this.updateAppUserCountDividend(userCountDividend);

                }catch (Exception ex){
                    errMsg = "发放失败：" + ex.getMessage();
                    log.info("{}发放失败:{}",errUserId,ex.getMessage());
                    break;
                }
            }
            if(StringUtils.isNotBlank(errMsg)){
                return HttpRet.fail(errMsg);
            }
            userIds = userIds.stream().distinct().collect(Collectors.toList());
            for(Long uid : userIds) {
                //更新用户可提现余额
                ThreadUtil.execute(()->{
                    appUserCountTask.updateWithdrawAble(uid);
                });
            }
        }
        return HttpRet.success("发放成功",true);
    }

    @Override
    public void reloadCache(String dateTime, List<Long> userIds) {
        //废弃
        /*Date uDate = new Date();
        if (StringUtils.isNotBlank(dateTime)) {
            uDate = DateUtil.parse(dateTime, "yyyy-MM-dd");
        }
        String beginTime = DateUtil.format(DateUtil.beginOfWeek(uDate), "yyyy-MM-dd");
        String endTime = DateUtil.format(DateUtil.endOfWeek(uDate), "yyyy-MM-dd");
        if (null == userIds) {
            List<AppUser> list = appUserService.selectTeamUserList();
            if (null != list && list.size() > 0) {
                list.forEach(appUser -> {
                    double money = calculation(appUser.getUserid(), beginTime, endTime);
                    redisCache.setCacheMapValue(CacheConstants.USER_AGENT_TEAM_PHASE, String.valueOf(appUser.getUserid()), money);
                });
            }
        } else {
            userIds.forEach(e->{
                AppUserAgent appUserAgent = appUserAgentService.selectInfo(e);
                if (null != appUserAgent) {
                    Long topUserId = appUserAgent.getTopId()<1?appUserAgent.getUserId():appUserAgent.getTopId();
                    double money = calculation(topUserId, beginTime, endTime);
                    redisCache.setCacheMapValue(CacheConstants.USER_AGENT_TEAM_PHASE, String.valueOf(topUserId), money);
                }else{
                    log.info("用户非代理停止计算周盈亏缓存");
                }
            });
        }*/
    }

    private double calculation(Long userId,String beginTime,String endTime){
        double money = 0;
        List<AppUserCount> appUserCountList = appUserCountService.getAppUserCountNew(userId,beginTime,endTime);
        if (null != appUserCountList && appUserCountList.size() > 0) {
            //游戏输钱
            double loseAmount = appUserCountList.stream().mapToDouble(e -> e.getGameLoseAmount()).sum();
            //游戏赢钱
            double winAmount = appUserCountList.stream().mapToDouble(e -> e.getGameWinAmount()).sum();
            //提现手续费
            double withdrawalCommission = appUserCountList.stream().mapToDouble(e -> e.getWithdrawalCommission()).sum();
            //游戏佣金
            double gameCommission = appUserCountList.stream().mapToDouble(e -> e.getGameCommission()).sum();
            //直播佣金
            double liveCommission = appUserCountList.stream().mapToDouble(e -> e.getLiveCommission()).sum();
            //充值赠送
            double rechargeGive = appUserCountList.stream().mapToDouble(e -> e.getRechargeGive()).sum();

            //计算分红金额 （输-赢）
//                        double money = (loseAmount - winAmount) - withdrawalCommission - gameCommission - liveCommission;
            money = (loseAmount - winAmount)  - gameCommission - rechargeGive;

        }
        return money;
    }


}