package com.ytpm.middle.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.ytpm.agent.view.AgentAppView;
import com.ytpm.feign.AppFeign;
import com.ytpm.general.Result;
import com.ytpm.middle.dao.ApkMapper;
import com.ytpm.middle.dao.EnterpriseMapper;
import com.ytpm.middle.dao.RiskMapper;
import com.ytpm.middle.service.CountService;
import com.ytpm.middle.util.RedisUtil;
import com.ytpm.middle.view.AppRankingListVO;
import com.ytpm.middle.view.AppUserHourVO;
import com.ytpm.middle.view.DashboardAppRevenueVO;
import com.ytpm.middle.view.DashboardRankingListVO;
import com.ytpm.middle.view.DashboardRevenueVO;
import com.ytpm.middle.view.DashboardRiskVO;
import com.ytpm.middle.view.DashboardTopCountVo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@RefreshScope
public class CountServiceImpl implements CountService {

    @Resource
    private EnterpriseMapper enterpriseMapper;
    @Resource
    private ApkMapper apkMapper;
    @Resource
    private AppFeign appFeign;
    @Resource
    private RiskMapper riskMapper;
    @Resource
    private RedisUtil redisUtil;
    @Value("${ranking.expire}")
    private long rankingExpire;
    @Value("${ranking.limit}")
    private int rankingLimit;
    private static final String RANKING_KEY = "yt_ranking";
    /**
     * 获取顶部数据统计
     */
    @Override
    public Result<DashboardTopCountVo> getTopCount() {
        DashboardTopCountVo vo = new DashboardTopCountVo();
        vo.setAgentCount(enterpriseMapper.countEnterprise());
        vo.setApkCount(apkMapper.countApk());
        Map<String, BigDecimal> map = appFeign.getAdCount(apkMapper.getAppIds());
        if(!map.isEmpty()){
            BigDecimal adCount = map.get("adCount");
            BigDecimal revenue = map.get("expectRevenue");
            vo.setAdCount(Objects.isNull(adCount) ? 0 : adCount.intValue());
            vo.setExpectRevenue(Objects.isNull(revenue) ? BigDecimal.ZERO : revenue);
        }
        return Result.resultObjOk(vo);
    }

    /**
     * 按照排行榜类型、排序规则统计排行榜信息
     */
    @Override
    public Result<DashboardRankingListVO> getRankingList(Integer sortBy) {
        //判断redis中是否存在排行榜信息 不存在则查询数据进行更新，存在则直接取出
        if(Boolean.TRUE.equals(redisUtil.hasKey(RANKING_KEY+sortBy))){
            String ranking = redisUtil.getStr(RANKING_KEY+sortBy);
            long expire = redisUtil.getExpire(RANKING_KEY + sortBy);
            if(Math.subtractExact(rankingExpire,expire)<2){
                getRankingAnCache(sortBy);
            }
            return Result.resultObjOk(JSON.parseObject(ranking, DashboardRankingListVO.class));
        }
        return Result.resultObjOk(getRankingAnCache(sortBy));
    }

    /**
     * 查询排行榜并缓存
     */
    private DashboardRankingListVO getRankingAnCache(Integer sortBy) {
        DashboardRankingListVO rankingVO = appFeign.queryRankingList(sortBy,rankingLimit);
        List<AppRankingListVO> appRankingList = rankingVO.getAppRankingList();
        List<AgentAppView> views = apkMapper.queryAll();
        Map<String, String> collect = views.stream().collect(Collectors.toMap(AgentAppView::getAppId, AgentAppView::getAppName));
        for (AppRankingListVO vo : appRankingList) {
            vo.setAppName(collect.get(vo.getAppId()));
        }
        rankingVO.setAppRankingList(appRankingList);
        redisUtil.setTimeOutMinutesStr(RANKING_KEY+sortBy, JSON.toJSONString(rankingVO),rankingExpire);
        return rankingVO;
    }

    /**
     * 根据应用查询各渠道包分时收益
     */
    @Override
    public Result<DashboardRevenueVO> getRevenueStatics(String appId) {
        List<AgentAppView> apkList =  apkMapper.queryBySuperiorId(appId);
        String apkIds = apkList.stream().map(AgentAppView::getAppId).collect(Collectors.joining(","));
        DashboardRevenueVO vo =  appFeign.revenueStatics(apkIds);
        Map<String, String> appNameMap = apkList.stream().collect(Collectors.toMap(AgentAppView::getAppId, AgentAppView::getAppName));
        List<DashboardAppRevenueVO> appRevenueList = vo.getAppRevenueList();
        for (DashboardAppRevenueVO revenueVO : appRevenueList) {
            revenueVO.setAppName(appNameMap.get(revenueVO.getAppId()));
        }
        vo.setAppRevenueList(appRevenueList);
        return Result.resultObjOk(vo);
    }

    /**
     * 根据应用查询风控用户数据
     */
    @Override
    public Result<DashboardRiskVO> getUserStatics(String appId) {
        DashboardRiskVO vo = appFeign.userStatics(appId);
        vo.setTodayBannedCount(riskMapper.countBanned(appId,1));
        vo.setYesterdayBannedCount(riskMapper.countBanned(appId,2));
        vo.setMonthBannedCount(riskMapper.countBanned(appId,3));
        List<AppUserHourVO> bannedHour = riskMapper.countBannedHour(appId,1);
        bannedHour = bannedHour.stream().filter(
                s-> StrUtil.isNotBlank(s.getTime())).collect(Collectors.toList());
        if(CollUtil.isNotEmpty(bannedHour)){
            Map<String, Integer> collect = bannedHour.stream().collect(
                    Collectors.toMap(AppUserHourVO::getTime, AppUserHourVO::getCount));
            vo.setTodayBannedHourMap(collect);
        }
        return Result.resultObjOk(vo);
    }
}
