package com.fs.statis.service.impl;

import com.fs.common.core.redis.RedisCache;
import com.fs.company.cache.ICompanyCacheService;
import com.fs.course.mapper.FsCourseTrafficLogMapper;
import com.fs.statis.StatisticsRedisConstant;
import com.fs.statis.dto.*;
import com.fs.statis.mapper.ConsumptionBalanceMapper;
import com.fs.statis.service.IStatisticsService;
import com.fs.statis.service.utils.TrendDataFiller;
import com.fs.store.service.cache.IFsUserCourseCacheService;
import com.hc.openapi.tool.util.ObjectUtils;
import com.hc.openapi.tool.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.List;

import static com.fs.statis.StatisticsRedisConstant.*;

@Service("statisticsService")
public class StatisticsServiceImpl implements IStatisticsService {
    @Autowired
    private ConsumptionBalanceMapper consumptionBalanceMapper;

    @Autowired
    private IFsUserCourseCacheService fsUserCourseCacheService;

    @Autowired
    private ICompanyCacheService companyCacheService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private FsCourseTrafficLogMapper fsCourseTrafficLogMapper;


    @Override
    public void dataOverviewTask() {
        DealerAggregatedDTO dealerAggregatedDTO = this.dealerAggregated();
        ConsumptionBalanceDataDTO consumptionBalanceDataDTO = this.rechargeConsumption();
        AuthorizationInfoDTO authorizationInfoDTO = authorizationInfo();
        Long smsBalance = this.smsBalance();
        TrafficLogDTO trafficLog = this.getTrafficLog();

        redisCache.setCacheObject(StatisticsRedisConstant.DATA_OVERVIEW_DEALER_AGGREGATED, dealerAggregatedDTO);
        redisCache.setCacheObject(StatisticsRedisConstant.DATA_OVERVIEW_DEALER_BALANCE, consumptionBalanceDataDTO);
        redisCache.setCacheObject(StatisticsRedisConstant.DATA_OVERVIEW_DEALER_AUTHORIZATION_INFO, authorizationInfoDTO);
        redisCache.setCacheObject(StatisticsRedisConstant.DATA_OVERVIEW_DEALER_SMS_BALANCE, smsBalance);
        redisCache.setCacheObject(StatisticsRedisConstant.DATA_OVERVIEW_TRAFFIC_LOG,trafficLog);
    }


    public void analysisPreviewTask0(){
        analysisPreviewTask(0,1);
        analysisPreviewTask(0,2);
    }

    public void analysisPreviewTask1(){
        analysisPreviewTask(0,1);
        analysisPreviewTask(1,1);
        analysisPreviewTask(2,1);
        analysisPreviewTask(3,1);
        analysisPreviewTask(4,1);

        analysisPreviewTask(0,2);
        analysisPreviewTask(1,2);
        analysisPreviewTask(2,2);
        analysisPreviewTask(3,2);
        analysisPreviewTask(4,2);
    }


    @Override
    public void analysisPreviewTask(Integer type,Integer userType) {
        // 根据type计算出时间范围
        String startDate = "";
        String endDate = "";

        LocalDate now = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");


        if(0 == type){
            startDate = now.format(formatter);
            endDate = now.format(formatter);
        } else if(1 == type){
            LocalDate yesterday = now.minusDays(1);
            startDate = yesterday.format(formatter);
            endDate = yesterday.format(formatter);
        } else if(2 == type) {
            LocalDate startOfWeek = now.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
            startDate = startOfWeek.format(formatter);
            endDate = now.format(formatter);
        } else if(3 == type) {
            LocalDate startOfMonth = now.withDayOfMonth(1);
            startDate = startOfMonth.format(formatter);
            endDate = now.format(formatter);
        } else if(4 == type) {
            LocalDate firstDayOfPreviousMonth = now.minusMonths(1).withDayOfMonth(1);
            LocalDate lastDayOfPreviousMonth = now.withDayOfMonth(1).minusDays(1);
            startDate = firstDayOfPreviousMonth.format(formatter);
            endDate = lastDayOfPreviousMonth.format(formatter);
        }

        AnalysisPreviewQueryDTO param = new AnalysisPreviewQueryDTO();
        param.setStartTime(startDate);
        param.setEndTime(endDate);
        param.setType(type);
        param.setUserType(userType);

        AnalysisPreviewDTO analysisPreviewDTO = this.analysisPreview(param);

        redisCache.setCacheObject(String.format("%s:%d:%d",DATA_OVERVIEW_DEALER_ANALYSISPREVIEW,type,userType), analysisPreviewDTO);
    }

    public void watchEndPlayTrendTask0(){
        this.watchEndPlayTrendTask(0,1);
        this.watchEndPlayTrendTask(0,2);
    }

    public void watchEndPlayTrendTask1(){
        this.watchEndPlayTrendTask(1,1);
        this.watchEndPlayTrendTask(2,1);
        this.watchEndPlayTrendTask(3,1);
        this.watchEndPlayTrendTask(4,1);

        this.watchEndPlayTrendTask(1,2);
        this.watchEndPlayTrendTask(2,2);
        this.watchEndPlayTrendTask(3,2);
        this.watchEndPlayTrendTask(4,2);
    }


    @Override
    public void watchEndPlayTrendTask(Integer type,Integer userType) {
        // 根据type计算出时间范围
        String startDate = "";
        String endDate = "";

        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");


        if(0 == type){
            startDate = now.format(formatter);
            endDate = now.format(formatter);
        } else if(1 == type){
            LocalDateTime yesterday = now.minusDays(1);
            startDate = yesterday.format(formatter);
            endDate = yesterday.format(formatter);
        } else if(2 == type) {
            LocalDateTime startOfWeek = now.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
            startDate = startOfWeek.format(formatter);
            endDate = now.format(formatter);
        } else if(3 == type) {
            LocalDateTime startOfMonth = now.withDayOfMonth(1);
            startDate = startOfMonth.format(formatter);
            endDate = now.format(formatter);
        } else if(4 == type) {
            LocalDateTime firstDayOfPreviousMonth = now.minusMonths(1).withDayOfMonth(1);
            LocalDateTime lastDayOfPreviousMonth = now.withDayOfMonth(1).minusDays(1);
            startDate = firstDayOfPreviousMonth.format(formatter);
            endDate = lastDayOfPreviousMonth.format(formatter);
        }

        AnalysisPreviewQueryDTO param = new AnalysisPreviewQueryDTO();
        param.setStartTime(startDate);
        param.setEndTime(endDate);
        param.setType(type);

        param.setUserType(userType);
        List<WatchEndPlayTrendDTO> watchEndPlayTrendDTOS = this.watchEndPlayTrend(param);

        redisCache.setCacheObject(String.format("%s:%d:%d",DATA_OVERVIEW_DEALER_CHARTS,type,userType),watchEndPlayTrendDTOS);

    }


    public void companyWatchCourseTopTenTask0(){
        companyWatchCourseTopTenTask(0,0,1);
        companyWatchCourseTopTenTask(0,1,1);


        companyWatchCourseTopTenTask(0,0,2);
        companyWatchCourseTopTenTask(0,1,2);
    }

    public void companyWatchCourseTopTenTask1(){
        companyWatchCourseTopTenTask(1,0,1);
        companyWatchCourseTopTenTask(1,1,1);
        companyWatchCourseTopTenTask(2,0,1);
        companyWatchCourseTopTenTask(2,1,1);
        companyWatchCourseTopTenTask(3,0,1);
        companyWatchCourseTopTenTask(3,1,1);
        companyWatchCourseTopTenTask(4,0,1);
        companyWatchCourseTopTenTask(4,1,1);

        companyWatchCourseTopTenTask(1,0,2);
        companyWatchCourseTopTenTask(1,1,2);
        companyWatchCourseTopTenTask(2,0,2);
        companyWatchCourseTopTenTask(2,1,2);
        companyWatchCourseTopTenTask(3,0,2);
        companyWatchCourseTopTenTask(3,1,2);
        companyWatchCourseTopTenTask(4,0,2);
        companyWatchCourseTopTenTask(4,1,2);


    }

    @Override
    public void companyWatchCourseTopTenTask(Integer type,Integer statisticalType,Integer userType) {

        AnalysisPreviewQueryDTO dto = new AnalysisPreviewQueryDTO();
        dto.setType(type);
        dto.setStatisticalType(statisticalType);

        String startDate = "";
        String endDate = "";

        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");


        if(0 == type){
            startDate = now.format(formatter);
            endDate = now.format(formatter);
        } else if(1 == type){
            LocalDateTime yesterday = now.minusDays(1);
            startDate = yesterday.format(formatter);
            endDate = yesterday.format(formatter);
        } else if(2 == type) {
            LocalDateTime startOfWeek = now.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
            startDate = startOfWeek.format(formatter);
            endDate = now.format(formatter);
        } else if(3 == type) {
            LocalDateTime startOfMonth = now.withDayOfMonth(1);
            startDate = startOfMonth.format(formatter);
            endDate = now.format(formatter);
        } else if(4 == type) {
            LocalDateTime firstDayOfPreviousMonth = now.minusMonths(1).withDayOfMonth(1);
            LocalDateTime lastDayOfPreviousMonth = now.withDayOfMonth(1).minusDays(1);
            startDate = firstDayOfPreviousMonth.format(formatter);
            endDate = lastDayOfPreviousMonth.format(formatter);
        }

        dto.setStartTime(startDate);
        dto.setEndTime(endDate);
        dto.setUserType(userType);

        List<DeaMemberTopTenDTO> deaMemberTopTenDTOS = deaMemberTopTen(dto);
        redisCache.setCacheObject(String.format("%s:%d:%d:%d", CHARTS_MEMBER_TOP_TEN_WATCH, type,statisticalType,userType), deaMemberTopTenDTOS);
    }

    @Override
    public void watchCourseTopTenTask(Integer type,Integer statisticalType,Integer userType,String sort) {
        AnalysisPreviewQueryDTO dto = new AnalysisPreviewQueryDTO();
        dto.setType(type);
        dto.setStatisticalType(statisticalType);
        dto.setSort(sort);

        String startDate = "";
        String endDate = "";

        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");


        if(0 == type){
            startDate = now.format(formatter);
            endDate = now.format(formatter);
        } else if(1 == type){
            LocalDateTime yesterday = now.minusDays(1);
            startDate = yesterday.format(formatter);
            endDate = yesterday.format(formatter);
        } else if(2 == type) {
            LocalDateTime startOfWeek = now.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
            startDate = startOfWeek.format(formatter);
            endDate = now.format(formatter);
        } else if(3 == type) {
            LocalDateTime startOfMonth = now.withDayOfMonth(1);
            startDate = startOfMonth.format(formatter);
            endDate = now.format(formatter);
        } else if(4 == type) {
            LocalDateTime firstDayOfPreviousMonth = now.minusMonths(1).withDayOfMonth(1);
            LocalDateTime lastDayOfPreviousMonth = now.withDayOfMonth(1).minusDays(1);
            startDate = firstDayOfPreviousMonth.format(formatter);
            endDate = lastDayOfPreviousMonth.format(formatter);
        }

        dto.setStartTime(startDate);
        dto.setEndTime(endDate);
        dto.setUserType(userType);
        List<CourseStatsDTO> courseStatsDTOS = watchCourseTopTen(dto);

        redisCache.setCacheObject( String.format("%s:%d:%d:%d:%s", CHARTS_WATCH_TOP_TEN, type,statisticalType,userType,sort), courseStatsDTOS);
    }

    public void watchCourseTopTenTask0(){
        watchCourseTopTenTask(0,0,1,"DESC");
        watchCourseTopTenTask(0,0,1,"ASC");
        watchCourseTopTenTask(0,1,1,"DESC");
        watchCourseTopTenTask(0,1,1,"ASC");
        watchCourseTopTenTask(0,2,1,"DESC");
        watchCourseTopTenTask(0,2,1,"ASC");
        watchCourseTopTenTask(0,3,1,"DESC");
        watchCourseTopTenTask(0,3,1,"ASC");

        watchCourseTopTenTask(0,0,1,"DESC");
        watchCourseTopTenTask(0,0,1,"ASC");
        watchCourseTopTenTask(0,1,1,"DESC");
        watchCourseTopTenTask(0,1,1,"ASC");
        watchCourseTopTenTask(0,2,1,"DESC");
        watchCourseTopTenTask(0,2,1,"ASC");
        watchCourseTopTenTask(0,3,1,"DESC");
        watchCourseTopTenTask(0,3,1,"ASC");
    }

    public void watchCourseTopTenTask1(){
        watchCourseTopTenTask(1,0,1,"DESC");
        watchCourseTopTenTask(1,0,1,"ASC");

        watchCourseTopTenTask(1,0,2,"DESC");
        watchCourseTopTenTask(1,0,2,"ASC");


        watchCourseTopTenTask(1,1,1,"DESC");
        watchCourseTopTenTask(1,1,1,"ASC");

        watchCourseTopTenTask(1,1,2,"DESC");
        watchCourseTopTenTask(1,1,2,"ASC");

        watchCourseTopTenTask(1,2,1,"DESC");
        watchCourseTopTenTask(1,2,1,"ASC");

        watchCourseTopTenTask(1,2,2,"DESC");
        watchCourseTopTenTask(1,2,2,"ASC");


        watchCourseTopTenTask(1,3,1,"DESC");
        watchCourseTopTenTask(1,3,1,"ASC");

        watchCourseTopTenTask(1,3,2,"DESC");
        watchCourseTopTenTask(1,3,2,"ASC");

        watchCourseTopTenTask(2,0,1,"DESC");
        watchCourseTopTenTask(2,0,1,"ASC");

        watchCourseTopTenTask(2,0,2,"DESC");
        watchCourseTopTenTask(2,0,2,"ASC");

        watchCourseTopTenTask(2,1,1,"DESC");
        watchCourseTopTenTask(2,1,1,"ASC");

        watchCourseTopTenTask(2,1,2,"DESC");
        watchCourseTopTenTask(2,1,2,"ASC");

        watchCourseTopTenTask(2,2,1,"DESC");
        watchCourseTopTenTask(2,2,1,"ASC");

        watchCourseTopTenTask(2,2,2,"DESC");
        watchCourseTopTenTask(2,2,2,"ASC");


        watchCourseTopTenTask(2,3,1,"DESC");
        watchCourseTopTenTask(2,3,1,"ASC");

        watchCourseTopTenTask(2,3,2,"DESC");
        watchCourseTopTenTask(2,3,2,"ASC");

        watchCourseTopTenTask(3,0,1,"DESC");
        watchCourseTopTenTask(3,0,1,"ASC");

        watchCourseTopTenTask(3,0,2,"DESC");
        watchCourseTopTenTask(3,0,2,"ASC");

        watchCourseTopTenTask(3,1,1,"DESC");
        watchCourseTopTenTask(3,1,1,"ASC");

        watchCourseTopTenTask(3,1,2,"DESC");
        watchCourseTopTenTask(3,1,2,"ASC");

        watchCourseTopTenTask(3,2,1,"DESC");
        watchCourseTopTenTask(3,2,1,"ASC");

        watchCourseTopTenTask(3,2,2,"DESC");
        watchCourseTopTenTask(3,2,2,"ASC");

        watchCourseTopTenTask(3,3,1,"DESC");
        watchCourseTopTenTask(3,3,1,"ASC");

        watchCourseTopTenTask(3,3,2,"DESC");
        watchCourseTopTenTask(3,3,2,"ASC");

        watchCourseTopTenTask(4,0,1,"DESC");
        watchCourseTopTenTask(4,0,1,"ASC");

        watchCourseTopTenTask(4,0,2,"DESC");
        watchCourseTopTenTask(4,0,2,"ASC");

        watchCourseTopTenTask(4,1,1,"DESC");
        watchCourseTopTenTask(4,1,1,"ASC");
        watchCourseTopTenTask(4,2,1,"DESC");
        watchCourseTopTenTask(4,2,1,"ASC");
        watchCourseTopTenTask(4,3,1,"DESC");
        watchCourseTopTenTask(4,3,1,"ASC");

        watchCourseTopTenTask(4,1,2,"DESC");
        watchCourseTopTenTask(4,1,2,"ASC");
        watchCourseTopTenTask(4,2,2,"DESC");
        watchCourseTopTenTask(4,2,2,"ASC");
        watchCourseTopTenTask(4,3,2,"DESC");
        watchCourseTopTenTask(4,3,2,"ASC");
    }


    public void rewardMoneyTask15Minutes(){
        rewardMoneyTopTenTask(0,0,1);
        rewardMoneyTopTenTask(0,1,1);

        rewardMoneyTradeTask(0,1);

        rewardMoneyTopTenTask(0,0,2);
        rewardMoneyTopTenTask(0,1,2);

        rewardMoneyTradeTask(0,2);
    }


    public void rewardMoneyTaskEveryday(){
        rewardMoneyTopTenTask(1,0,1);
        rewardMoneyTopTenTask(1,1,1);


        rewardMoneyTopTenTask(2,0,1);
        rewardMoneyTopTenTask(2,1,1);

        rewardMoneyTopTenTask(3,0,1);
        rewardMoneyTopTenTask(3,1,1);

        rewardMoneyTopTenTask(4,0,1);
        rewardMoneyTopTenTask(4,1,1);


        rewardMoneyTradeTask(1,1);
        rewardMoneyTradeTask(2,1);
        rewardMoneyTradeTask(3,1);
        rewardMoneyTradeTask(4,1);


        rewardMoneyTopTenTask(1,0,2);
        rewardMoneyTopTenTask(1,1,2);
        rewardMoneyTopTenTask(2,0,2);
        rewardMoneyTopTenTask(2,1,2);
        rewardMoneyTopTenTask(3,0,2);
        rewardMoneyTopTenTask(3,1,2);
        rewardMoneyTopTenTask(4,0,2);
        rewardMoneyTopTenTask(4,1,2);

        rewardMoneyTradeTask(1,2);
        rewardMoneyTradeTask(2,2);
        rewardMoneyTradeTask(3,2);
        rewardMoneyTradeTask(4,2);
    }

    @Override
    public void rewardMoneyTopTenTask(Integer type,Integer dataType,Integer userType) {
        AnalysisPreviewQueryDTO dto = new AnalysisPreviewQueryDTO();
        dto.setType(type);
        dto.setDataType(dataType);

        String startDate = "";
        String endDate = "";

        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");


        if(0 == type){
            startDate = now.format(formatter);
            endDate = now.format(formatter);
        } else if(1 == type){
            LocalDateTime yesterday = now.minusDays(1);
            startDate = yesterday.format(formatter);
            endDate = yesterday.format(formatter);
        } else if(2 == type) {
            LocalDateTime startOfWeek = now.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
            startDate = startOfWeek.format(formatter);
            endDate = now.format(formatter);
        } else if(3 == type) {
            LocalDateTime startOfMonth = now.withDayOfMonth(1);
            startDate = startOfMonth.format(formatter);
            endDate = now.format(formatter);
        } else if(4 == type) {
            LocalDateTime firstDayOfPreviousMonth = now.minusMonths(1).withDayOfMonth(1);
            LocalDateTime lastDayOfPreviousMonth = now.withDayOfMonth(1).minusDays(1);
            startDate = firstDayOfPreviousMonth.format(formatter);
            endDate = lastDayOfPreviousMonth.format(formatter);
        }

        dto.setStartTime(startDate);
        dto.setEndTime(endDate);
        dto.setUserType(userType);

        List<RewardMoneyTopTenDTO> rewardMoneyTopTenDTOS = rewardMoneyTopTen(dto);

        redisCache.setCacheObject( String.format("%s:%d:%d:%d", CHARTS_REWARD_MONEY_TOP_TEN, type,dataType,userType), rewardMoneyTopTenDTOS);

    }

    @Override
    public void rewardMoneyTradeTask(Integer type,Integer userType) {
        AnalysisPreviewQueryDTO dto = new AnalysisPreviewQueryDTO();
        dto.setType(type);

        String startDate = "";
        String endDate = "";

        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");


        if(0 == type){
            startDate = now.format(formatter);
            endDate = now.format(formatter);
        } else if(1 == type){
            LocalDateTime yesterday = now.minusDays(1);
            startDate = yesterday.format(formatter);
            endDate = yesterday.format(formatter);
        } else if(2 == type) {
            LocalDateTime startOfWeek = now.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
            startDate = startOfWeek.format(formatter);
            endDate = now.format(formatter);
        } else if(3 == type) {
            LocalDateTime startOfMonth = now.withDayOfMonth(1);
            startDate = startOfMonth.format(formatter);
            endDate = now.format(formatter);
        } else if(4 == type) {
            LocalDateTime firstDayOfPreviousMonth = now.minusMonths(1).withDayOfMonth(1);
            LocalDateTime lastDayOfPreviousMonth = now.withDayOfMonth(1).minusDays(1);
            startDate = firstDayOfPreviousMonth.format(formatter);
            endDate = lastDayOfPreviousMonth.format(formatter);
        }

        dto.setStartTime(startDate);
        dto.setEndTime(endDate);
        dto.setUserType(userType);
        List<RewardMoneyTrendDTO> rewardMoneyTrendDTOS = rewardMoneyTrendDTO(dto);
        redisCache.setCacheObject( String.format("%s:%d:%d", CHARTS_REWARD_MONEY_TREND, type,userType), rewardMoneyTrendDTOS);

    }


    @Override
    public DealerAggregatedDTO dealerAggregated() {
        return consumptionBalanceMapper.dealerAggregated();
    }

    @Override
    public ConsumptionBalanceDataDTO rechargeConsumption() {
        return consumptionBalanceMapper.rechargeConsumption();
    }

    @Override
    public AnalysisPreviewDTO analysisPreview(AnalysisPreviewQueryDTO param) {
        AnalysisPreviewDTO dto = new AnalysisPreviewDTO();

        Long watchUserCount = consumptionBalanceMapper.queryWatchUserCount(param);
        Long completedUserCount = consumptionBalanceMapper.queryCompletedUserCount(param);

        if(watchUserCount == null){
            watchUserCount = 0L;
        }
        if(completedUserCount == null){
            completedUserCount = 0L;
        }

        // 观看人数
        dto.setWatchUserCount(watchUserCount);
        // 完播人数
        dto.setCompletedUserCount(completedUserCount);

        // 完播率
        if(!ObjectUtils.equals(watchUserCount,0L)){
            BigDecimal multiply = (BigDecimal.valueOf(completedUserCount)
                    .divide(BigDecimal.valueOf(watchUserCount),4,BigDecimal.ROUND_HALF_UP))
                    .multiply(BigDecimal.valueOf(100));

            dto.setCompletedRate(multiply.setScale(2,BigDecimal.ROUND_HALF_UP).toPlainString());
        } else {
            dto.setCompletedRate("0");
        }

        Long watchCount = consumptionBalanceMapper.queryWatchCount(param);
        Long completedCount = consumptionBalanceMapper.queryCompletedCount(param);

        if(watchCount == null){
            watchCount = 0L;
        }
        if(completedCount == null){
            completedCount = 0L;
        }

        // 观看次数
        dto.setWatchCount(watchCount);
        // 完播次数
        dto.setCompletedCount(completedCount);
        // 视频完播率
        if(!ObjectUtils.equals(watchCount, 0L)){
            BigDecimal multiply = BigDecimal.valueOf(completedCount)
                    .divide(BigDecimal.valueOf(watchCount),4,BigDecimal.ROUND_HALF_UP)
                    .multiply(BigDecimal.valueOf(100));

            dto.setWatchRate(multiply.setScale(2,BigDecimal.ROUND_HALF_UP).toPlainString());
        } else {
            dto.setWatchRate("0");
        }

        Long answerMemberCount = consumptionBalanceMapper.queryAnswerMemberCount(param);
        Long correctUserCount = consumptionBalanceMapper.queryCorrectUserCount(param);

        if(answerMemberCount == null){
            answerMemberCount = 0L;
        }
        if(correctUserCount == null){
            correctUserCount = 0L;
        }
        // 答题人数
        dto.setAnswerMemberCount(answerMemberCount);
        // 正确人数
        dto.setCorrectUserCount(correctUserCount);
        // 正确比例
        if(!ObjectUtils.equals(answerMemberCount, 0L)){
            BigDecimal multiply = BigDecimal.valueOf(correctUserCount)
                    .divide(BigDecimal.valueOf(answerMemberCount),4,BigDecimal.ROUND_HALF_UP)
                    .multiply(BigDecimal.valueOf(100));

            dto.setCorrectRate(multiply.setScale(2, RoundingMode.HALF_UP).toPlainString());
        } else {
            dto.setCorrectRate("0");
        }
        Long rewardCount = consumptionBalanceMapper.queryRewardCount(param);
        if(rewardCount == null) {
            rewardCount = 0L;
        }
        BigDecimal rewardMoney = consumptionBalanceMapper.queryRewardMoney(param);
        if(rewardMoney == null) {
            rewardMoney = BigDecimal.ZERO;
        }
        // 答题红包个数
        dto.setRewardCount(rewardCount);
        // 答题红包金额
        dto.setRewardMoney(rewardMoney);

        return dto;
    }

    @Override
    public Long smsBalance() {
        Long smsBalance = consumptionBalanceMapper.smsBalance();
        if(smsBalance != null) {
            smsBalance = 0L;
        }
        return smsBalance;
    }

    @Override
    public AuthorizationInfoDTO authorizationInfo() {
        return consumptionBalanceMapper.authorizationInfo();
    }

    @Override
    public List<WatchEndPlayTrendDTO> watchEndPlayTrend(AnalysisPreviewQueryDTO param) {
        List<WatchEndPlayTrendDTO> watchEndPlayTrendDTOS = consumptionBalanceMapper.watchEndPlayTrend(param);
        // 今日，昨日 格式为24小时
        if(ObjectUtils.equals(param.getType(),0) || ObjectUtils.equals(param.getType(),1)){
            watchEndPlayTrendDTOS = TrendDataFiller.fillHourData(watchEndPlayTrendDTOS);
            // 否则都是按天为维度的时间范围
        } else {
            watchEndPlayTrendDTOS = TrendDataFiller.fillDateSegmentData(watchEndPlayTrendDTOS, param.getStartTime(), param.getEndTime());
        }

        return watchEndPlayTrendDTOS;
    }

    @Override
    public List<DeaMemberTopTenDTO> deaMemberTopTen(AnalysisPreviewQueryDTO param) {
        List<DeaMemberTopTenDTO> deaMemberTopTenDTOS = consumptionBalanceMapper.deaMemberTopTen(param);
        for (DeaMemberTopTenDTO dto : deaMemberTopTenDTOS) {
            Long companyId = dto.getCompanyId();
            String companyName = companyCacheService.selectCompanyNameById(companyId);
            if(StringUtils.isNotBlank(companyName)){
                dto.setCompanyName(companyName);
            }
        }
        return deaMemberTopTenDTOS;
    }

    @Override
    public List<CourseStatsDTO> watchCourseTopTen(AnalysisPreviewQueryDTO param) {
        List<CourseStatsDTO> courseStatsDTOS = consumptionBalanceMapper.watchCourseTopTen(param);
        for (CourseStatsDTO courseStatsDTO : courseStatsDTOS) {
            String courseName = fsUserCourseCacheService.selectCourseNameByCourseId(courseStatsDTO.getCourseId());
            if(StringUtils.isNotBlank(courseName)){
                courseStatsDTO.setCourseName(courseName);
            }
        }
        return courseStatsDTOS;
    }

    @Override
    public List<RewardMoneyTopTenDTO> rewardMoneyTopTen(AnalysisPreviewQueryDTO param) {
        List<RewardMoneyTopTenDTO> rewardMoneyTopTenDTOS = consumptionBalanceMapper.rewardMoneyTopTen(param);
        for (RewardMoneyTopTenDTO dto : rewardMoneyTopTenDTOS) {
            if(dto.getCompanyId() != null) {
                String companyName = companyCacheService.selectCompanyNameById(dto.getCompanyId());
                dto.setCompanyName(companyName);
            }
            if(dto.getCourseId() != null){
                String courseName = fsUserCourseCacheService.selectCourseNameByCourseId(dto.getCourseId());
                dto.setCourseName(courseName);
            }

        }
        return rewardMoneyTopTenDTOS;
    }

    @Override
    public List<RewardMoneyTrendDTO> rewardMoneyTrendDTO(AnalysisPreviewQueryDTO param) {
        List<RewardMoneyTrendDTO> rewardMoneyTrendDTOS = consumptionBalanceMapper.rewardMoneyTrendDTO(param);

        // 今日，昨日 格式为24小时
        if(ObjectUtils.equals(param.getType(),0) || ObjectUtils.equals(param.getType(),1)){
            rewardMoneyTrendDTOS = TrendDataFiller.fillRewardHourData(rewardMoneyTrendDTOS);
            // 否则都是按天为维度的时间范围
        } else {
            rewardMoneyTrendDTOS = TrendDataFiller.fillRewardDateSegmentData(rewardMoneyTrendDTOS, param.getStartTime(), param.getEndTime());
        }


        return rewardMoneyTrendDTOS;
    }

    @Override
    public TrafficLogDTO getTrafficLog() {
        TrafficLogDTO trafficLogDTO = new TrafficLogDTO();
        Long todayTrafficLog = fsCourseTrafficLogMapper.getTodayTrafficLog();
        Long monthTrafficLog = fsCourseTrafficLogMapper.getMonthTrafficLog();
        trafficLogDTO.setToday(todayTrafficLog);
        trafficLogDTO.setThisMonth(monthTrafficLog);
        return trafficLogDTO;
    }
}
