package com.lesingle.edu.service.impl;

import com.lesingle.edu.dto.response.CourseReportResponse;
import com.lesingle.edu.dto.response.ReportOverviewResponse;
import com.lesingle.edu.dto.response.StudentReportResponse;
import com.lesingle.edu.dto.response.TeacherReportResponse;
import com.lesingle.edu.mapper.ReportMapper;
import com.lesingle.edu.service.SchoolReportService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 学校端 - 数据报告服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SchoolReportServiceImpl implements SchoolReportService {

    private final ReportMapper reportMapper;

    @Override
    public ReportOverviewResponse getOverview(Long tenantId, LocalDate startDate, LocalDate endDate) {
        // 计算时间范围
        LocalDateTime startTime;
        LocalDateTime endTime;

        if (startDate != null) {
            startTime = startDate.atStartOfDay();
        } else {
            // 默认本月 1 号
            startTime = LocalDateTime.now().withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
        }

        if (endDate != null) {
            endTime = endDate.atTime(23, 59, 59);
        } else {
            // 默认今天
            endTime = LocalDateTime.now();
        }

        log.info("获取报告概览，租户 ID: {}, 统计周期：{} ~ {}", tenantId, startTime, endTime);

        // 查询概览数据
        Map<String, Object> stats = reportMapper.getOverviewStats(tenantId, startTime, endTime);

        if (stats == null) {
            return ReportOverviewResponse.builder()
                    .reportDate(LocalDate.now())
                    .totalTeachers(0)
                    .totalStudents(0)
                    .totalClasses(0)
                    .monthlyLessons(0)
                    .monthlyTasksCompleted(0)
                    .build();
        }

        return ReportOverviewResponse.builder()
                .reportDate(LocalDate.now())
                .totalTeachers(convertToInt(stats.get("totalTeachers")))
                .totalStudents(convertToInt(stats.get("totalStudents")))
                .totalClasses(convertToInt(stats.get("totalClasses")))
                .monthlyLessons(convertToInt(stats.get("monthlyLessons")))
                .monthlyTasksCompleted(convertToInt(stats.get("monthlyTasksCompleted")))
                .build();
    }

    @Override
    public List<TeacherReportResponse> getTeacherReports(Long tenantId, LocalDate startDate, LocalDate endDate, int limit) {
        // 计算时间范围
        LocalDateTime startTime;
        LocalDateTime endTime;

        if (startDate != null) {
            startTime = startDate.atStartOfDay();
        } else {
            startTime = LocalDateTime.now().withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
        }

        if (endDate != null) {
            endTime = endDate.atTime(23, 59, 59);
        } else {
            endTime = LocalDateTime.now();
        }

        log.info("获取教师报告，租户 ID: {}, 统计周期：{} ~ {}", tenantId, startTime, endTime);

        List<Map<String, Object>> rawData = reportMapper.getTeacherReports(tenantId, startTime, endTime, limit);

        if (rawData == null || rawData.isEmpty()) {
            return new ArrayList<>();
        }

        return rawData.stream().map(row -> {
            Integer lessonCount = convertToInt(row.get("lessonCount"));
            Integer taskCount = convertToInt(row.get("taskCount"));
            Double averageRating = convertToDouble(row.get("averageRating"));
            LocalDateTime lastLessonTime = (LocalDateTime) row.get("lastLessonTime");

            return TeacherReportResponse.builder()
                    .teacherId((Long) row.get("teacherId"))
                    .teacherName((String) row.get("teacherName"))
                    .lessonCount(lessonCount)
                    .taskCount(taskCount)
                    .averageRating(averageRating)
                    .lastLessonTime(lastLessonTime)
                    .build();
        }).collect(java.util.stream.Collectors.toList());
    }

    @Override
    public List<CourseReportResponse> getCourseReports(Long tenantId, LocalDate startDate, LocalDate endDate, int limit) {
        // 计算时间范围
        LocalDateTime startTime;
        LocalDateTime endTime;

        if (startDate != null) {
            startTime = startDate.atStartOfDay();
        } else {
            startTime = LocalDateTime.now().withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
        }

        if (endDate != null) {
            endTime = endDate.atTime(23, 59, 59);
        } else {
            endTime = LocalDateTime.now();
        }

        log.info("获取课程报告，租户 ID: {}, 统计周期：{} ~ {}", tenantId, startTime, endTime);

        List<Map<String, Object>> rawData = reportMapper.getCourseReports(tenantId, startTime, endTime, limit);

        if (rawData == null || rawData.isEmpty()) {
            return new ArrayList<>();
        }

        return rawData.stream().map(row -> {
            Integer lessonCount = convertToInt(row.get("lessonCount"));
            Integer studentCount = convertToInt(row.get("studentCount"));
            Double averageRating = convertToDouble(row.get("averageRating"));
            Double completionRate = convertToDouble(row.get("completionRate"));

            return CourseReportResponse.builder()
                    .courseId((Long) row.get("courseId"))
                    .courseName((String) row.get("courseName"))
                    .lessonCount(lessonCount)
                    .studentCount(studentCount)
                    .averageRating(averageRating)
                    .completionRate(completionRate)
                    .build();
        }).collect(java.util.stream.Collectors.toList());
    }

    @Override
    public List<StudentReportResponse> getStudentReports(Long tenantId, LocalDate startDate, LocalDate endDate, int limit) {
        // 计算时间范围
        LocalDateTime startTime;
        LocalDateTime endTime;

        if (startDate != null) {
            startTime = startDate.atStartOfDay();
        } else {
            startTime = LocalDateTime.now().withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
        }

        if (endDate != null) {
            endTime = endDate.atTime(23, 59, 59);
        } else {
            endTime = LocalDateTime.now();
        }

        log.info("获取学生报告，租户 ID: {}, 统计周期：{} ~ {}", tenantId, startTime, endTime);

        List<Map<String, Object>> rawData = reportMapper.getStudentReports(tenantId, startTime, endTime, limit);

        if (rawData == null || rawData.isEmpty()) {
            return new ArrayList<>();
        }

        return rawData.stream().map(row -> {
            Integer taskCount = convertToInt(row.get("taskCount"));
            Integer readingCount = convertToInt(row.get("readingCount"));
            Integer growthRecordCount = convertToInt(row.get("growthRecordCount"));
            Double attendanceRate = convertToDouble(row.get("attendanceRate"));

            return StudentReportResponse.builder()
                    .studentId((Long) row.get("studentId"))
                    .studentName((String) row.get("studentName"))
                    .className((String) row.get("className"))
                    .taskCount(taskCount)
                    .readingCount(readingCount)
                    .growthRecordCount(growthRecordCount)
                    .attendanceRate(attendanceRate)
                    .build();
        }).collect(java.util.stream.Collectors.toList());
    }

    /**
     * 将 Object 转换为 Integer，处理 null 和 Number 类型
     */
    private Integer convertToInt(Object value) {
        if (value == null) {
            return 0;
        }
        if (value instanceof Number) {
            return ((Number) value).intValue();
        }
        // 处理 BigDecimal 等类型
        try {
            return Integer.parseInt(value.toString());
        } catch (NumberFormatException e) {
            return 0;
        }
    }

    /**
     * 将 Object 转换为 Double，处理 null 和 Number 类型
     */
    private Double convertToDouble(Object value) {
        if (value == null) {
            return 0.0;
        }
        if (value instanceof Number) {
            return ((Number) value).doubleValue();
        }
        // 处理 BigDecimal 等类型
        try {
            return Double.parseDouble(value.toString());
        } catch (NumberFormatException e) {
            return 0.0;
        }
    }
}
