package com.game.business.controller;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.game.business.domain.AppUser;
import com.game.business.domain.AppUserAgent;
import com.game.business.domain.AppUserCount;
import com.game.business.domain.FinTranRecord;
import com.game.business.dto.*;
import com.game.business.service.IAppUserAgentService;
import com.game.business.service.IAppUserCountService;
import com.game.business.service.IAppUserService;
import com.game.business.service.IFinTranRecordService;
import com.game.business.vo.AppAgentTeamVo;
import com.game.business.vo.AppUserAgentJournalIndexVO;
import com.game.business.vo.AppUserTeamTranserRecordVo;
import com.game.common.constant.CacheConstants;
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.page.TableDataInfo;
import com.game.common.core.redis.RedisCache;
import com.game.common.utils.MessageUtils;
import com.game.common.utils.SecurityUtils;
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.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/business/agent")
@Api(value = "AppGameBettingController", description = "用户代理表接口", tags = {"用户代理表接口"})
public class AppAgentController extends BaseController {

    @Autowired
    private IAppUserCountService appUserCountService;

    @Autowired
    private IAppUserService appUserService;

    @Autowired
    private IAppUserAgentService appUserAgentService;

    @Autowired
    private IFinTranRecordService finTranRecordService;

    @Autowired
    private RedisCache redisCache;


    /**
     * 首页
     */
    @PostMapping(value = "/index")
    @ApiOperation(value = "用户代理统计", notes = "用户代理统计")
    public HttpRet<AppUserAgentJournalIndexVO> index(@RequestBody AgentIndexDTO agentIndexDto)
    {
        Date now = DateUtil.date();
        Long userId = SecurityUtils.getUserId();
        if(null != agentIndexDto.getUserId()){
            userId = agentIndexDto.getUserId();
        }
        AppUserAgent appUserAgent = appUserAgentService.selectInfo(userId);
        long topUserId = userId;
        if(null != appUserAgent && appUserAgent.getPid() > 0){
            topUserId = appUserAgent.getTopId();
        }
        AppUserAgentJournalIndexVO vo = new AppUserAgentJournalIndexVO();
        Date curDate = DateUtil.date();
        if(agentIndexDto.getType() == 1){
//            curDate = DateUtil.offsetMonth(curDate,-1); //上个月
            //上一个周期
            curDate = DateUtil.offsetDay(curDate,-15);
        }
        String formatP = "yyyy-MM-dd";
        /*Date beginDate = DateUtil.beginOfMonth(curDate);
        Date endDate = DateUtil.endOfMonth(curDate);*/
        int curDay = Integer.parseInt(DateUtil.format(curDate,"dd"));

        Date weekBegin = null;
        Date weekend = null;
        if(curDay <= 15){
            weekBegin = DateUtil.beginOfMonth(curDate);
            weekend = DateUtil.parse(DateUtil.format(curDate,"yyyy-MM-".concat("15").concat(" 23:59:59")),"yyyy-MM-dd HH:mm:ss");
        }else{
            weekBegin = DateUtil.parse(DateUtil.format(curDate,"yyyy-MM-".concat("15").concat(" 00:00:00")),"yyyy-MM-dd HH:mm:ss");
            weekend = DateUtil.endOfMonth(curDate);
        }

        List<AppUserCount> appUserCountList = appUserCountService.getAppUserCountNew(userId,DateUtil.format(weekBegin,formatP),DateUtil.format(weekend,formatP));
        AppUserAgent queryAppUserAgent = new AppUserAgent();
        queryAppUserAgent.setPid(userId);
        //查询用户下级代理
        List<AppUserAgent> appUserAgentList = appUserAgentService.selectAllAgentList(userId,null,null,null);
        if(null == appUserCountList){
            appUserCountList = new ArrayList<>();
        }
        //处理下级代理树形列表
        AppUserAgent teamUser = AppUserAgent.buildTree(appUserAgentList,userId,appUserCountList);
        //佣金
        double money = 0;
        if(null != appUserCountList && appUserCountList.size() > 0){
//            List<AppUserCount> finalAppUserCountList = appUserCountList;
            /*money = appUserAgentList.stream().mapToDouble(appUserAgent1 -> {
                return finalAppUserCountList.stream().mapToDouble(e->{
                    return (e.getGameLoseAmount() - e.getGameWinAmount() - e.getGameCommission() - e.getRechargeGive()) * appUserAgent1.getDividendGuaranteeRate()/100;
                }).sum();
            }).sum();*/
            /*if(teamUser.getChildrenList() != null && teamUser.getChildrenList().size()>0) {
                money = teamUser.getChildrenList().stream().mapToDouble(e -> {
                    double winLose = 0;
                    winLose = AppUserAgent.calMoney(e, winLose);
                    if (winLose > 0) {
                        return BigDecimal.valueOf(winLose * e.getDividendGuaranteeRate() / 100).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                    } else {
                        return 0;
                    }
                }).sum();
            }*/
//            money = dealChildel(teamUser,money);

            //计算当前用户分红
            double winLose = appUserCountList.stream().mapToDouble(e->{
               return e.getGameLoseAmount() - (e.getGameWinAmount() - (e.getGameBetting() - e.getGameLoseAmount())) - e.getGameCommission() - e.getRechargeGive() - e.getRechargeCommission() - e.getWithdrawalCommission();
            }).sum();

            if(winLose > 0){
                money +=  BigDecimal.valueOf(winLose * teamUser.getDividendGuaranteeRate() / 100).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            }

        }


        /*if(null != appUserAgent.getDividendGuaranteeRate()){
            money = money * appUserAgent.getDividendGuaranteeRate() / 100 ;
        }else{
            money = 0;
        }*/
        //预计分红
        vo.setMyCommission(BigDecimal.valueOf(money>0?money:0).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue());
        vo.setLiveCommission(BigDecimal.valueOf(appUserCountList.stream().mapToDouble(e->e.getLiveCommission()).sum()).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
        vo.setGameCommission(BigDecimal.valueOf(appUserCountList.stream().mapToDouble(e->e.getGameCommission()).sum()).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
        //团队人数
        vo.setTeamUser(appUserAgentList.stream().collect(Collectors.toList()).size());
        //团队充值
        vo.setTeamRecharge(BigDecimal.valueOf(appUserCountList.stream().mapToDouble(e->{
            return e.getRechargeAmount();
        }).sum()).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue());
        //团队充值赠送金额
        vo.setRechargeGive(BigDecimal.valueOf(appUserCountList.stream().mapToDouble(e->e.getRechargeGive()).sum()).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue());
        //团队充值手续费
        vo.setRechargeCommission(BigDecimal.valueOf(appUserCountList.stream().mapToDouble(e->e.getRechargeCommission()).sum()).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue());
        //团队提现手续费
        vo.setWithdrawalCommission(BigDecimal.valueOf(appUserCountList.stream().mapToDouble(e->e.getWithdrawalCommission()).sum()).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue());
        //团队投注
        vo.setTeamBetting(BigDecimal.valueOf(appUserCountList.stream().mapToDouble(e->e.getGameBetting()).sum()).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue());
        //团队直播消费
        vo.setTeamLive(BigDecimal.valueOf(appUserCountList.stream().mapToDouble(e->e.getLiveUseAmount()).sum()).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue());
        //团队投注赢
        vo.setTeamWin(BigDecimal.valueOf(appUserCountList.stream().mapToDouble(
                e->{
                    return e.getGameWinAmount();
                }
        ).sum()).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue());
        //团队投注输
        vo.setTeamLose(BigDecimal.valueOf(appUserCountList.stream().mapToDouble(e->e.getGameLoseAmount()).sum()).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue());
        //活跃人数
        vo.setActiveUser(appUserCountList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(()-> new TreeSet<>(Comparator.comparing(f->f.getUserId()))), ArrayList::new)).size());
        //昨日新增
        Date yesterDay = DateUtil.offsetDay(DateUtil.date(),-1);
        vo.setYesterdayUser(appUserAgentList.stream().filter(e->
                compareTime(e.getCreateTime(),yesterDay,yesterDay)
        ).collect(Collectors.toList()).size());
        vo.setMonthUser(appUserAgentList.stream().filter(e->
                compareTime(e.getCreateTime(),DateUtil.beginOfMonth(new Date()),DateUtil.endOfMonth(new Date()))
        ).collect(Collectors.toList()).size());

        //直播收益
        Long finalUserId = userId;
        vo.setLiveProfit(BigDecimal.valueOf(appUserCountList.stream().filter(e->e.getUserId().equals(finalUserId)).mapToDouble(e->e.getLiveProfit()).sum()).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue());
        //直播邀请奖励
        vo.setLiveInvite(BigDecimal.valueOf(appUserCountList.stream().filter(e->e.getUserId().equals(finalUserId)).mapToDouble(e->e.getLiveInvite()).sum()).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue());

        return HttpRet.success(MessageUtils.message("11022"),vo);
    }

    /**
     * 修改直播分成、分红保底
     */
    /*@PostMapping(value = "/updateSetting")
    @ApiOperation(value = "修改直播分成、分红保底", notes = "修改直播分成、分红保底")
    public HttpRet<Boolean> updateSetting(@RequestBody AppAgentEditDto editDto)
    {
        return appUserAgentService.updateSetting(editDto);
    }*/

    /**
     * 团队列表
     */
    @PostMapping(value = "/teamList")
    @ApiOperation(value = "团队列表", notes = "团队列表")
    public HttpRetPageArr<AppAgentTeamVo> teamList(@RequestBody AppAgentTeamDto teamDto)
    {

//        startPageBySize(10);//每页最多10条
        List<AppAgentTeamVo> list = appUserAgentService.teamList(teamDto);
        return HttpRetPageArr.success(MessageUtils.message("11022"),getDataTable(list));
    }

    /**
     * 团队转账
     */
    @PostMapping(value = "/transfer")
    @ApiOperation(value = "团队转账", notes = "团队转账")
    public HttpRet<Boolean> transfer(@RequestBody @Validated AppUserTeamTranserDto transerDto)
    {
        Long userId = SecurityUtils.getUserId();
       //查询当前用户代理信息
       LambdaQueryWrapper<AppUserAgent> queryWrapper = new LambdaQueryWrapper<>();
       queryWrapper.eq(AppUserAgent::getUserId,userId);
       queryWrapper.eq(AppUserAgent::getAuditStatus,1);
       AppUserAgent appUserAgent = appUserAgentService.getOne(queryWrapper);
       if(null == appUserAgent){
           return HttpRet.fail("转账失败，受益人不是代理");
       }
       if(appUserAgent.getPid().longValue() == 0 || isTwoLevel(appUserAgent.getPid())){
           List<AppUserAgent> appUserAgentList = appUserAgentService.selectAllAgentList(userId,transerDto.getToUserId(),null,null);
           if(null == appUserAgentList || appUserAgentList.size() < 1){
               return HttpRet.fail("转账失败，只能给团队成员转账");
           }
       }else{
            if(!isTeam(userId,transerDto.getToUserId())){
                return HttpRet.fail("转账失败，只能给下级成员转账");
            }
       }
       return finTranRecordService.transfer(transerDto);
    }

    /**
     * 团队转账记录
     */
    @PostMapping(value = "/transferRecord")
    @ApiOperation(value = "团队转账记录(分页 链接上拼pageSize和pageNum)", notes = "团队转账记录（分页 链接上拼pageSize和pageNum）")
    public HttpRetPageArr<AppUserTeamTranserRecordVo> transferRecord(@RequestBody @Validated AppUserTeamTranserRecordDto transerDto)
    {
        startPage();
        List<FinTranRecord> list = finTranRecordService.transferRecord(transerDto);
        TableDataInfo<FinTranRecord> tableDataInfo = getDataTable(list);
        TableDataInfo resultDataInfo = new TableDataInfo();
        BeanUtils.copyProperties(tableDataInfo,resultDataInfo);
        if(null != tableDataInfo.getRows() && tableDataInfo.getRows().size() > 0){
            List<AppUser> appUsers = null;
            if(0 == transerDto.getType()){
                //转出
                appUsers = appUserService.selectListByIds(
                        tableDataInfo.getRows().stream().map(e->e.getToUid()).collect(Collectors.toList())
                );
            }else{
                //转入
                appUsers = appUserService.selectListByIds(
                        tableDataInfo.getRows().stream().map(e->e.getFromUid()).collect(Collectors.toList())
                );
            }
            Map<String,AppUser> userMap = new HashMap<>();
            if(null != appUsers && appUsers.size() > 0){
                userMap = appUsers.stream().collect(Collectors.toMap(e->{return String.valueOf(e.getUserid());}, Function.identity(),(k1,k2)->k2));
            }
            Map<String, AppUser> finalUserMap = userMap;
            resultDataInfo.setRows(tableDataInfo.getRows().stream().map(e->{
                AppUserTeamTranserRecordVo vo = new AppUserTeamTranserRecordVo();
                vo.setMoney(e.getDiamondCoinChange());
                vo.setTime(e.getCreateTime());
                AppUser appUser = null;
                if(0 == transerDto.getType()){
                    //转出
                    long userId = e.getToUid();
                    appUser = finalUserMap.get(String.valueOf(userId));
                    vo.setUserId(userId);
                    if(null != appUser){
                        vo.setNickName(appUser.getUsername());
                    }
                }else{
                    //转入
                    long userId = e.getFromUid();
                    appUser = finalUserMap.get(String.valueOf(userId));
                    vo.setUserId(userId);
                    if(null != appUser){
                        vo.setNickName(appUser.getUsername());
                    }
                }
                return vo;
            }).collect(Collectors.toList()));
        }else{
            resultDataInfo.setRows(new ArrayList());
        }
        return HttpRetPageArr.success(MessageUtils.message("11022"),resultDataInfo);
    }

    //查询用户是否为下级代理
    private boolean isTeam(Long pid,Long userId){
        //查询当前用户代理信息
        LambdaQueryWrapper<AppUserAgent> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AppUserAgent::getUserId,userId);
        queryWrapper.eq(AppUserAgent::getAuditStatus,1);
        AppUserAgent appUserAgent = appUserAgentService.getOne(queryWrapper);
        if(null != appUserAgent && appUserAgent.getPid().longValue() == pid){
            return true;
        }
        return false;
    }

    /**
     * 查询是否为第二级代理
     * */
    private boolean isTwoLevel(Long userId){
        LambdaQueryWrapper<AppUserAgent> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AppUserAgent::getUserId,userId);
        AppUserAgent appUserAgent = appUserAgentService.getOne(queryWrapper);
        if(appUserAgent.getPid().longValue() == 0){
            return true;
        }
        return false;
    }

    private boolean compareTime(Date curTime,Date beginTime,Date endTime){
        beginTime = DateUtil.parse(DateUtil.format(beginTime,"yyyy-MM-dd").concat(" 00:00:00"));
        endTime = DateUtil.parse(DateUtil.format(endTime,"yyyy-MM-dd").concat(" 23:59:59"));
        return curTime.getTime() >= beginTime.getTime() && curTime.getTime() <= endTime.getTime();
    }

    public double dealChildel(AppUserAgent appUserAgent,double money){
        double winlose = 0;
        winlose = AppUserAgent.calMoney(appUserAgent,winlose);
        if(winlose > 0){
            money += winlose * appUserAgent.getDividendGuaranteeRate() / 100;
        }
        if(null != appUserAgent.getChildrenList() && appUserAgent.getChildrenList().size() > 0){
            for(AppUserAgent child : appUserAgent.getChildrenList()){
                money = dealChildel(child,money);
            }
        }
        return money;
    }
}
