package com.fs.company.controller.company;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fs.common.core.domain.R;
import com.fs.common.core.redis.RedisCache;
import com.fs.common.utils.PubFun;
import com.fs.common.utils.ServletUtils;
import com.fs.common.utils.date.DateUtil;
import com.fs.company.domain.Company;
import com.fs.company.domain.CompanyTrafficRecord;
import com.fs.company.domain.CompanyTrafficRecordLog;
import com.fs.company.mapper.CompanyMapper;
import com.fs.company.mapper.CompanyMoneyLogsMapper;
import com.fs.company.mapper.CompanyTrafficRecordLogMapper;
import com.fs.company.mapper.CompanyTrafficRecordMapper;
import com.fs.framework.security.LoginUser;
import com.fs.framework.service.TokenService;
import com.fs.statis.StatisticsRedisConstant;
import com.fs.statis.dto.*;
import com.fs.statis.service.IStatisticsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

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

/**
 * 首页-统计
 */
@RestController
@RequestMapping("/index/statistics")
public class IndexStatisticsController {
    @Autowired
    private RedisCache redisCache;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private IStatisticsService statisticsService;
    @Autowired
    private CompanyMoneyLogsMapper moneyLogsMapper;
    @Autowired
    private CompanyMapper companyMapper;
    @Autowired
    private CompanyTrafficRecordMapper companyTrafficRecordMapper;
    @Autowired
    private CompanyTrafficRecordLogMapper companyTrafficRecordLogMapper;
    @Value("${cloud_host.company_name}")
    private String signProjectName;

    Function<Long, String> tranTraffic = traffic -> {
        int unitInt = 1024;
        BigDecimal unit = BigDecimal.valueOf(unitInt);
        BigDecimal kb = BigDecimal.valueOf(traffic);
        if(traffic < unitInt){
            return traffic + "KB";
        }
        BigDecimal mb = kb.divide(unit, 2, RoundingMode.HALF_UP);
        if(mb.doubleValue() < unitInt){
            return mb + "MB";
        }
        BigDecimal gb = mb.divide(unit, 2, RoundingMode.HALF_UP);
        if(gb.doubleValue() < unitInt){
            return mb + "GB";
        }
        return gb.divide(unit, 2, RoundingMode.HALF_UP) + "TB";
    };

    /**
     * 分析概览
     */
    @PostMapping("/analysisPreview")
    public R analysisPreview(@RequestBody AnalysisPreviewQueryDTO param){
        AnalysisPreviewDTO analysisPreviewDTO = null;
        Integer type = param.getType();
        Integer userType = param.getUserType();

        if(type == null) {
            type = 0;
        }

        if(userType == null) {
            userType = 0;
        }
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        param.setCompanyId(loginUser.getCompany().getCompanyId());
        analysisPreviewDTO = redisCache.getCacheObject(String.format("%s:%d:%d:%d",DATA_OVERVIEW_DEALER_ANALYSISPREVIEW,type,userType,param.getCompanyId()));

        return R.ok().put("data",analysisPreviewDTO);
    }


    /**
     * 消费余额
     */
    @GetMapping("/rechargeComsumption")
    public R rechargeComsumption(){
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        Long companyId = loginUser.getCompany().getCompanyId();
        ConsumptionBalanceDataDTO dto;
        if("医健宝".equals(signProjectName)){
            dto = new ConsumptionBalanceDataDTO();
            Company company = companyMapper.selectCompanyById(companyId);
            List<BigDecimal> subList = moneyLogsMapper.selectCompanyRedPackage(companyId);
            dto.setBalance(company.getMoney());
            dto.setTodayComsumption(subList.stream().map(BigDecimal::abs).reduce(BigDecimal.ZERO, BigDecimal::add));
        }else{
            dto = redisCache.getCacheObject(String.format("%s:%d",StatisticsRedisConstant.DATA_OVERVIEW_DEALER_BALANCE,companyId));
        }
        return R.ok().put("data", dto);
    }

    /**
     * 获取统计流量
     * @return
     */
    @GetMapping("/trafficLog")
    public R getTrafficLog(){
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        Long companyId = loginUser.getCompany().getCompanyId();
        CompanyTrafficRecord companyTrafficRecord = companyTrafficRecordMapper.selectOne(new QueryWrapper<CompanyTrafficRecord>().eq("company_id", companyId));
        TrafficLogDTO trafficLogDTO;
        if("医健宝".equals(signProjectName)){
            trafficLogDTO = new TrafficLogDTO();
            if(companyTrafficRecord != null){
                trafficLogDTO.setTraffic(tranTraffic.apply(companyTrafficRecord.getBalance()));
                List<CompanyTrafficRecordLog> monthLogs = companyTrafficRecordLogMapper.selectMonth(companyId);
                List<CompanyTrafficRecordLog> toDayLos = monthLogs.stream().filter(e -> DateUtil.dateToLocalDateTime(e.getCreateTime()).toLocalDate().equals(LocalDate.now())).collect(Collectors.toList());
                Function<List<CompanyTrafficRecordLog>, Long> traffic = list -> list.stream().mapToLong(CompanyTrafficRecordLog::getTrafficAmount).sum();
                trafficLogDTO.setToday(traffic.apply(toDayLos));
                trafficLogDTO.setThisMonth(traffic.apply(monthLogs));
            }
        }else{
            trafficLogDTO = redisCache.getCacheObject(String.format("%s:%d",DATA_OVERVIEW_TRAFFIC_LOG,companyId));
        }
        return R.ok().put("data",trafficLogDTO);
    }

    /**
     * 观看趋势
     */
    @PostMapping("/watchEndPlayTrend")
    public R watchEndPlayTrend(@RequestBody AnalysisPreviewQueryDTO param){
        Integer type = param.getType();
        Integer userType = param.getUserType();

        if(type == null) {
            type = 0;
        }
        if(userType == null){
            userType = 0;
        }
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        Long companyId = loginUser.getCompany().getCompanyId();
        param.setCompanyId(companyId);

        String key = String.format("%s:%d:%d:%d", DATA_OVERVIEW_DEALER_CHARTS, type,userType,param.getCompanyId());
        List<DeaMemberTopTenDTO> deaMemberTopTenDTOS = redisCache.getCacheObject(key);
        return R.ok().put("data", deaMemberTopTenDTOS);
    }

    /**
     * 经销商会员观看
     */
    @PostMapping("/deaMemberTopTen")
    public R deaMemberTopTen(@RequestBody AnalysisPreviewQueryDTO param){
        Integer type = param.getType();
        Integer statisticalType = param.getStatisticalType();
        Integer userType = param.getUserType();

        if(type == null) {
            type = 0;
        }
        if(userType == null){
            userType = 0;
        }
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        Long companyId = loginUser.getCompany().getCompanyId();
        param.setCompanyId(companyId);

        List<DeaMemberTopTenDTO> deaMemberTopTenDTOS = redisCache.getCacheObject(String.format("%s:%d:%d:%d:%d", CHARTS_MEMBER_TOP_TEN_WATCH, type, statisticalType,userType,param.getCompanyId()));
        if(deaMemberTopTenDTOS == null){
            deaMemberTopTenDTOS = new ArrayList<>();
        }
        return R.ok().put("data", deaMemberTopTenDTOS);
    }

    /**
     * 奖励金额top10
     */
    @PostMapping("/rewardMoneyTopTen")
    public R rewardMoneyTopTen(@RequestBody AnalysisPreviewQueryDTO param){
        Integer type = param.getType();
        Integer dataType = param.getDataType();
        Integer userType = param.getUserType();
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        Long companyId = loginUser.getCompany().getCompanyId();
        param.setCompanyId(companyId);

        List<RewardMoneyTopTenDTO> rewardMoneyTopTenDTOS = redisCache.getCacheObject( String.format("%s:%d:%d:%d:%d", CHARTS_REWARD_MONEY_TOP_TEN, type,dataType,userType,param.getCompanyId()));
        return R.ok().put("data", rewardMoneyTopTenDTOS);
    }

    /**
     * 答题红包金额趋势图
     */
    @PostMapping("/rewardMoneyTrend")
    public R rewardMoneyTrend(@RequestBody AnalysisPreviewQueryDTO param){
        Integer type = param.getType();
        Integer userType = param.getUserType();
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        Long companyId = loginUser.getCompany().getCompanyId();
        param.setCompanyId(companyId);

        List<RewardMoneyTrendDTO> rewardMoneyTrendDTOS = redisCache.getCacheObject( String.format("%s:%d:%d:%d", CHARTS_REWARD_MONEY_TREND, type,userType,param.getCompanyId()));
        return R.ok().put("data", rewardMoneyTrendDTOS);
    }

    /**
     * 课程观看top10
     */
    @PostMapping("/watchCourseTopTen")
    public R watchCourseTopTen(@RequestBody AnalysisPreviewQueryDTO param){
        Integer type = param.getType();
        String sort = param.getSort();
        Integer statisticalType = param.getStatisticalType();
        Integer userType = param.getUserType();
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        Long companyId = loginUser.getCompany().getCompanyId();
        param.setCompanyId(companyId);

        List<CourseStatsDTO> courseStatsDTOS = redisCache.getCacheObject(String.format("%s:%d:%d:%d:%s:%d", CHARTS_WATCH_TOP_TEN, type,statisticalType,userType,sort,param.getCompanyId()));
        return R.ok().put("data", courseStatsDTOS);
    }

    /**
     * 数据概览
     */
    @GetMapping("/dealerAggregated")
    public R dealerAggregated(){
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        Long companyId = loginUser.getCompany().getCompanyId();

        DealerAggregatedDTO dealerAggregatedDTO = redisCache.getCacheObject(String.format("%s:%d",StatisticsRedisConstant.DATA_OVERVIEW_DEALER_AGGREGATED,companyId));

        return R.ok().put("data",dealerAggregatedDTO);
    }

    /**
     * 短信余额
     */
    @GetMapping("/smsBalance")
    public R smsBalance(){
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        Long companyId = loginUser.getCompany().getCompanyId();

        Long smsBalance = redisCache.getCacheObject(String.format("%s:%d",StatisticsRedisConstant.DATA_OVERVIEW_DEALER_SMS_BALANCE,companyId));

        return R.ok().put("data", smsBalance);
    }


    /**
     * 授权信息
     */
    @GetMapping("/authorizationInfo")
    public R authorizationInfo(){
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        Long companyId = loginUser.getCompany().getCompanyId();

        AuthorizationInfoDTO authorizationInfoDTO = redisCache.getCacheObject(String.format("%s:%d",StatisticsRedisConstant.DATA_OVERVIEW_DEALER_AUTHORIZATION_INFO,companyId));

        return R.ok().put("data", authorizationInfoDTO);
    }


    /**
     * 当月订单数统计
     * @return
     */
    @GetMapping("/thisMonthOrderCount")
    public R thisMonthOrderCount(){
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        Long companyId = loginUser.getCompany().getCompanyId();

        R result = redisCache.getCacheObject(String.format("%s:%d",StatisticsRedisConstant.THIS_MONTH_ORDER_COUNT,companyId));
        return result;
    }

    /**
     * 当月收益统计
     * @return
     */
    @GetMapping("/thisMonthRecvCount")
    public R thisMonthRecvCount(){
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        Long companyId = loginUser.getCompany().getCompanyId();

        R result = redisCache.getCacheObject(String.format("%s:%d",StatisticsRedisConstant.THIS_MONTH_RECV_COUNT,companyId));
        return result;
    }

    /**
     * @Description: 看课统计按公司
     * @Param:
     * @Return:
     * @Author xgb
     * @Date 2025/10/27 16:29
     */
    @PostMapping("/getWatchCourseStatisticsData")
    public R getWatchCourseStatisticsData(@RequestBody AnalysisPreviewQueryDTO param){
        // 获取公司ID
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        Long companyId = loginUser.getCompany().getCompanyId();
        if(param.getCompanyId()==null){
            param.setCompanyId(companyId);
        }
        // 从缓存获取看客统计数据
        List<WatchCourseStatisticsResultDTO> data=statisticsService.getWatchCourseStatisticsData(param);

        return R.ok().put("data", data);
    }
}
