package com.ssyf.module.robot.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ssyf.module.robot.domain.entity.ChatInfo;
import com.ssyf.module.robot.domain.entity.RRobotAccount;
import com.ssyf.module.robot.domain.entity.RRobotConsumptionRecord;
import com.ssyf.module.robot.domain.entity.RRobotRunningInfo;
import com.ssyf.module.robot.domain.query.ChatActivityStatisticsQuery;
import com.ssyf.module.robot.domain.query.ConsumptionStatisticsQuery;
import com.ssyf.module.robot.domain.query.LiveRoomStatisticsQuery;
import com.ssyf.module.robot.domain.vo.ChatActivityStatisticsVo;
import com.ssyf.module.robot.domain.vo.ConsumptionStatisticsVo;
import com.ssyf.module.robot.domain.vo.LiveRoomStatisticsVo;
import com.ssyf.module.robot.domain.vo.RobotStatisticsVo;
import com.ssyf.module.robot.service.ChatInfoService;
import com.ssyf.module.robot.service.RRobotAccountService;
import com.ssyf.module.robot.service.RRobotConsumptionRecordService;
import com.ssyf.module.robot.service.RRobotRunningInfoService;
import com.ssyf.module.robot.service.RobotStatisticsService;
import com.ssyf.module.robot.mapper.RRobotRunningInfoMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 机器人统计服务实现
 * 
 * @author ELSA
 */
@Slf4j
@Service
public class RobotStatisticsServiceImpl implements RobotStatisticsService {

    @Autowired
    private RRobotAccountService robotAccountService;

    @Autowired
    private RRobotRunningInfoService robotRunningInfoService;

    @Autowired
    private RRobotConsumptionRecordService consumptionRecordService;

    @Autowired
    private RRobotRunningInfoMapper robotRunningInfoMapper;

    @Autowired
    private ChatInfoService chatInfoService;

    @Override
    public RobotStatisticsVo getRobotStatistics() {
        RobotStatisticsVo statistics = new RobotStatisticsVo();

        // 获取机器人总数（从RRobotAccount表）
        int totalCount = robotAccountService.count(new LambdaQueryWrapper<RRobotAccount>()
                .eq(RRobotAccount::getDeleted, 0) // 未删除的账号
                .eq(RRobotAccount::getStatus, 1)  // 启用的账号
        );
        statistics.setTotalCount(totalCount);

        // 获取在线机器人数量（runningStatus = 1）
        int onlineCount = robotRunningInfoService.count(new LambdaQueryWrapper<RRobotRunningInfo>()
                .eq(RRobotRunningInfo::getRunningStatus, 1) // 在线状态
        );
        statistics.setOnlineCount(onlineCount);

        // 获取离线机器人数量（runningStatus = 2）
        int offlineCount = robotRunningInfoService.count(new LambdaQueryWrapper<RRobotRunningInfo>()
                .eq(RRobotRunningInfo::getRunningStatus, 2) // 离线状态
        );
        statistics.setOfflineCount(offlineCount);

        // 获取在直播间的机器人数量（currentBehavior = 2）
        int inLiveRoomCount = robotRunningInfoService.count(new LambdaQueryWrapper<RRobotRunningInfo>()
                .eq(RRobotRunningInfo::getCurrentBehavior, 2) // 在直播间行为
        );
        statistics.setInLiveRoomCount(inLiveRoomCount);

        return statistics;
    }

    @Override
    public ConsumptionStatisticsVo getConsumptionStatistics(ConsumptionStatisticsQuery query) {
        ConsumptionStatisticsVo result = new ConsumptionStatisticsVo();
        result.setDimension(query.getDimension());

        // 设置默认时间范围（最近7天/周/月）
        LocalDateTime endTime = query.getEndTime() != null ? query.getEndTime() : LocalDateTime.now();
        LocalDateTime startTime = query.getStartTime();
        
        if (startTime == null) {
            int rangeCount = query.getRangeCount() != null ? query.getRangeCount() : 7;
            switch (query.getDimension()) {
                case "day":
                    startTime = endTime.minusDays(rangeCount - 1);
                    break;
                case "week":
                    startTime = endTime.minusWeeks(rangeCount - 1);
                    break;
                case "month":
                    startTime = endTime.minusMonths(rangeCount - 1);
                    break;
                default:
                    startTime = endTime.minusDays(rangeCount - 1);
            }
        }

        // 查询消费记录
        List<RRobotConsumptionRecord> records = consumptionRecordService.list(
                new LambdaQueryWrapper<RRobotConsumptionRecord>()
                        .ge(RRobotConsumptionRecord::getConsumptionTime, startTime)
                        .le(RRobotConsumptionRecord::getConsumptionTime, endTime)
        );

        // 计算总消费额
        BigDecimal totalAmount = records.stream()
                .map(record -> BigDecimal.valueOf(record.getConsumptionAmount()))
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        result.setTotalAmount(totalAmount);

        // 按时间维度分组统计
        List<ConsumptionStatisticsVo.TimeRangeStatistic> timeRangeStats = new ArrayList<>();
        
        switch (query.getDimension()) {
            case "day":
                timeRangeStats = groupByDay(records, startTime, endTime);
                break;
            case "week":
                timeRangeStats = groupByWeek(records, startTime, endTime);
                break;
            case "month":
                timeRangeStats = groupByMonth(records, startTime, endTime);
                break;
            default:
                timeRangeStats = groupByDay(records, startTime, endTime);
        }

        result.setTimeRangeStatistics(timeRangeStats);
        return result;
    }

    /**
     * 按日分组统计
     */
    private List<ConsumptionStatisticsVo.TimeRangeStatistic> groupByDay(
            List<RRobotConsumptionRecord> records, LocalDateTime startTime, LocalDateTime endTime) {
        
        List<ConsumptionStatisticsVo.TimeRangeStatistic> stats = new ArrayList<>();
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        DateTimeFormatter displayFormatter = DateTimeFormatter.ofPattern("MM月dd日");
        
        LocalDateTime current = startTime;
        while (!current.isAfter(endTime)) {
            LocalDateTime nextDay = current.plusDays(1);
            final LocalDateTime finalCurrent = current;
            BigDecimal dayAmount = records.stream()
                    .filter(record -> !record.getConsumptionTime().isBefore(finalCurrent) &&
                                     record.getConsumptionTime().isBefore(nextDay))
                    .map(record -> BigDecimal.valueOf(record.getConsumptionAmount()))
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            
            ConsumptionStatisticsVo.TimeRangeStatistic stat = new ConsumptionStatisticsVo.TimeRangeStatistic();
            stat.setTimeRange(current.format(dateFormatter));
            stat.setDisplayName(current.format(displayFormatter));
            stat.setAmount(dayAmount);
            stats.add(stat);
            
            current = nextDay;
        }
        
        return stats;
    }

    /**
     * 按周分组统计
     */
    private List<ConsumptionStatisticsVo.TimeRangeStatistic> groupByWeek(
            List<RRobotConsumptionRecord> records, LocalDateTime startTime, LocalDateTime endTime) {
        
        List<ConsumptionStatisticsVo.TimeRangeStatistic> stats = new ArrayList<>();
        DateTimeFormatter weekFormatter = DateTimeFormatter.ofPattern("yyyy-ww周");
        
        LocalDateTime current = startTime;
        int weekCount = 1;
        while (!current.isAfter(endTime)) {
            LocalDateTime nextWeek = current.plusWeeks(1);
            final LocalDateTime finalCurrent = current;
            BigDecimal weekAmount = records.stream()
                    .filter(record -> !record.getConsumptionTime().isBefore(finalCurrent) &&
                                     record.getConsumptionTime().isBefore(nextWeek))
                    .map(record -> BigDecimal.valueOf(record.getConsumptionAmount()))
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            
            ConsumptionStatisticsVo.TimeRangeStatistic stat = new ConsumptionStatisticsVo.TimeRangeStatistic();
            stat.setTimeRange(current.format(weekFormatter));
            stat.setDisplayName("第" + weekCount + "周");
            stat.setAmount(weekAmount);
            stats.add(stat);
            
            current = nextWeek;
            weekCount++;
        }
        
        return stats;
    }

    /**
     * 按月分组统计
     */
    private List<ConsumptionStatisticsVo.TimeRangeStatistic> groupByMonth(
            List<RRobotConsumptionRecord> records, LocalDateTime startTime, LocalDateTime endTime) {
        
        List<ConsumptionStatisticsVo.TimeRangeStatistic> stats = new ArrayList<>();
        DateTimeFormatter monthFormatter = DateTimeFormatter.ofPattern("yyyy-MM");
        DateTimeFormatter displayFormatter = DateTimeFormatter.ofPattern("yyyy年MM月");
        
        LocalDateTime current = startTime;
        while (!current.isAfter(endTime)) {
            LocalDateTime nextMonth = current.plusMonths(1);
            final LocalDateTime finalCurrent = current;
            BigDecimal monthAmount = records.stream()
                    .filter(record -> !record.getConsumptionTime().isBefore(finalCurrent) &&
                                     record.getConsumptionTime().isBefore(nextMonth))
                    .map(record -> BigDecimal.valueOf(record.getConsumptionAmount()))
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            
            ConsumptionStatisticsVo.TimeRangeStatistic stat = new ConsumptionStatisticsVo.TimeRangeStatistic();
            stat.setTimeRange(current.format(monthFormatter));
            stat.setDisplayName(current.format(displayFormatter));
            stat.setAmount(monthAmount);
            stats.add(stat);
            
            current = nextMonth;
        }
        
        return stats;
    }

    @Override
    public LiveRoomStatisticsVo getLiveRoomStatistics(LiveRoomStatisticsQuery query) {
        LiveRoomStatisticsVo result = new LiveRoomStatisticsVo();

        // 设置排序方式（默认倒序）
        String sortOrder = "desc".equalsIgnoreCase(query.getSortOrder()) ? "desc" : "asc";

        // 获取所有直播间统计信息
        List<LiveRoomStatisticsVo.LiveRoomStatistic> allStats = robotRunningInfoMapper.getLiveRoomStatistics(sortOrder);

        // 手动分页处理
        int pageNum = query.getPageNum() != null ? query.getPageNum() : 1;
        int pageSize = query.getPageSize() != null ? query.getPageSize() : 10;
        
        // 计算分页参数
        int total = allStats.size();
        int totalPages = (int) Math.ceil((double) total / pageSize);
        
        // 确保页码在有效范围内
        if (pageNum < 1) pageNum = 1;
        if (pageNum > totalPages && totalPages > 0) pageNum = totalPages;
        
        // 计算分页起始位置
        int startIndex = (pageNum - 1) * pageSize;
        int endIndex = Math.min(startIndex + pageSize, total);
        
        // 获取当前页数据
        List<LiveRoomStatisticsVo.LiveRoomStatistic> pageStats = new ArrayList<>();
        if (startIndex < total) {
            pageStats = allStats.subList(startIndex, endIndex);
        }

        // 设置返回结果
        result.setTotal((long) total);
        result.setPageNum(pageNum);
        result.setPageSize(pageSize);
        result.setTotalPages(totalPages);
        result.setLiveRoomStatistics(pageStats);

        return result;
    }

    @Override
    public ChatActivityStatisticsVo getChatActivityStatistics(ChatActivityStatisticsQuery query) {
        ChatActivityStatisticsVo result = new ChatActivityStatisticsVo();
        result.setDimension(query.getDimension());

        // 设置默认时间范围（最近7天/周/月）
        LocalDateTime endTime = query.getEndTime() != null ? query.getEndTime() : LocalDateTime.now();
        LocalDateTime startTime = query.getStartTime();
        
        if (startTime == null) {
            int rangeCount = query.getRangeCount() != null ? query.getRangeCount() : 7;
            switch (query.getDimension()) {
                case "day":
                    startTime = endTime.minusDays(rangeCount - 1);
                    break;
                case "week":
                    startTime = endTime.minusWeeks(rangeCount - 1);
                    break;
                case "month":
                    startTime = endTime.minusMonths(rangeCount - 1);
                    break;
                default:
                    startTime = endTime.minusDays(rangeCount - 1);
            }
        }

        // 查询聊天记录
        List<ChatInfo> chatRecords = chatInfoService.list(
                new LambdaQueryWrapper<ChatInfo>()
                        .ge(ChatInfo::getChatTime, startTime)
                        .le(ChatInfo::getChatTime, endTime)
        );

        // 计算总发言次数
        Long totalChatCount = (long) chatRecords.size();
        result.setTotalChatCount(totalChatCount);

        // 按机器人分组统计发言次数
        Map<String, Integer> robotChatCountMap = new HashMap<>();
        Map<String, String> robotAccountMap = new HashMap<>();
        Map<String, String> robotNickNameMap = new HashMap<>();
        Map<String, String> robotGroupMap = new HashMap<>();

        for (ChatInfo chat : chatRecords) {
            String robotUuid = chat.getRobotUuid();
            robotChatCountMap.put(robotUuid, robotChatCountMap.getOrDefault(robotUuid, 0) + 1);
            robotAccountMap.putIfAbsent(robotUuid, chat.getRobotAccount());
            robotNickNameMap.putIfAbsent(robotUuid, chat.getRobotNickName());
            robotGroupMap.putIfAbsent(robotUuid, chat.getRobotGroupName());
        }

        // 转换为机器人统计列表并排序
        List<ChatActivityStatisticsVo.RobotChatStatistic> robotStats = robotChatCountMap.entrySet().stream()
                .map(entry -> {
                    ChatActivityStatisticsVo.RobotChatStatistic stat = new ChatActivityStatisticsVo.RobotChatStatistic();
                    stat.setRobotUuid(entry.getKey());
                    stat.setRobotAccount(robotAccountMap.get(entry.getKey()));
                    stat.setRobotNickName(robotNickNameMap.get(entry.getKey()));
                    stat.setRobotGroupName(robotGroupMap.get(entry.getKey()));
                    stat.setChatCount(entry.getValue());
                    return stat;
                })
                .sorted((a, b) -> {
                    if ("asc".equalsIgnoreCase(query.getSortOrder())) {
                        return a.getChatCount().compareTo(b.getChatCount());
                    } else {
                        return b.getChatCount().compareTo(a.getChatCount());
                    }
                })
                .collect(Collectors.toList());

        result.setRobotStatistics(robotStats);
        result.setTotalRobotCount(robotStats.size());

        // 按时间维度分组统计
        List<ChatActivityStatisticsVo.TimeRangeStatistic> timeRangeStats = new ArrayList<>();
        
        switch (query.getDimension()) {
            case "day":
                timeRangeStats = groupChatByDay(chatRecords, startTime, endTime);
                break;
            case "week":
                timeRangeStats = groupChatByWeek(chatRecords, startTime, endTime);
                break;
            case "month":
                timeRangeStats = groupChatByMonth(chatRecords, startTime, endTime);
                break;
            default:
                timeRangeStats = groupChatByDay(chatRecords, startTime, endTime);
        }

        result.setTimeRangeStatistics(timeRangeStats);
        return result;
    }

    /**
     * 按日分组统计发言次数
     */
    private List<ChatActivityStatisticsVo.TimeRangeStatistic> groupChatByDay(
            List<ChatInfo> records, LocalDateTime startTime, LocalDateTime endTime) {
        
        List<ChatActivityStatisticsVo.TimeRangeStatistic> stats = new ArrayList<>();
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        DateTimeFormatter displayFormatter = DateTimeFormatter.ofPattern("MM月dd日");
        
        LocalDateTime current = startTime;
        while (!current.isAfter(endTime)) {
            LocalDateTime nextDay = current.plusDays(1);
            final LocalDateTime finalCurrent = current;
            
            int dayChatCount = (int) records.stream()
                    .filter(record -> !record.getChatTime().isBefore(finalCurrent) && 
                                     record.getChatTime().isBefore(nextDay))
                    .count();
            
            ChatActivityStatisticsVo.TimeRangeStatistic stat = new ChatActivityStatisticsVo.TimeRangeStatistic();
            stat.setTimeRange(current.format(dateFormatter));
            stat.setDisplayName(current.format(displayFormatter));
            stat.setChatCount(dayChatCount);
            stats.add(stat);
            
            current = nextDay;
        }
        
        return stats;
    }

    /**
     * 按周分组统计发言次数
     */
    private List<ChatActivityStatisticsVo.TimeRangeStatistic> groupChatByWeek(
            List<ChatInfo> records, LocalDateTime startTime, LocalDateTime endTime) {
        
        List<ChatActivityStatisticsVo.TimeRangeStatistic> stats = new ArrayList<>();
        DateTimeFormatter weekFormatter = DateTimeFormatter.ofPattern("yyyy-ww周");
        
        LocalDateTime current = startTime;
        int weekCount = 1;
        while (!current.isAfter(endTime)) {
            LocalDateTime nextWeek = current.plusWeeks(1);
            final LocalDateTime finalCurrent = current;
            
            int weekChatCount = (int) records.stream()
                    .filter(record -> !record.getChatTime().isBefore(finalCurrent) && 
                                     record.getChatTime().isBefore(nextWeek))
                    .count();
            
            ChatActivityStatisticsVo.TimeRangeStatistic stat = new ChatActivityStatisticsVo.TimeRangeStatistic();
            stat.setTimeRange(current.format(weekFormatter));
            stat.setDisplayName("第" + weekCount + "周");
            stat.setChatCount(weekChatCount);
            stats.add(stat);
            
            current = nextWeek;
            weekCount++;
        }
        
        return stats;
    }

    /**
     * 按月分组统计发言次数
     */
    private List<ChatActivityStatisticsVo.TimeRangeStatistic> groupChatByMonth(
            List<ChatInfo> records, LocalDateTime startTime, LocalDateTime endTime) {
        
        List<ChatActivityStatisticsVo.TimeRangeStatistic> stats = new ArrayList<>();
        DateTimeFormatter monthFormatter = DateTimeFormatter.ofPattern("yyyy-MM");
        DateTimeFormatter displayFormatter = DateTimeFormatter.ofPattern("yyyy年MM月");
        
        LocalDateTime current = startTime;
        while (!current.isAfter(endTime)) {
            LocalDateTime nextMonth = current.plusMonths(1);
            final LocalDateTime finalCurrent = current;
            
            int monthChatCount = (int) records.stream()
                    .filter(record -> !record.getChatTime().isBefore(finalCurrent) && 
                                     record.getChatTime().isBefore(nextMonth))
                    .count();
            
            ChatActivityStatisticsVo.TimeRangeStatistic stat = new ChatActivityStatisticsVo.TimeRangeStatistic();
            stat.setTimeRange(current.format(monthFormatter));
            stat.setDisplayName(current.format(displayFormatter));
            stat.setChatCount(monthChatCount);
            stats.add(stat);
            
            current = nextMonth;
        }
        
        return stats;
    }
}