package com.lesingle.edu.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.lesingle.edu.common.response.Result;
import com.lesingle.edu.dto.response.LessonExportVO;
import com.lesingle.edu.dto.response.StudentStatExportVO;
import com.lesingle.edu.dto.response.TeacherPerformanceExportVO;
import com.lesingle.edu.entity.Clazz;
import com.lesingle.edu.mapper.ClazzMapper;
import com.lesingle.edu.mapper.LessonMapper;
import com.lesingle.edu.service.SchoolExportService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 学校端 - 数据导出服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SchoolExportServiceImpl implements SchoolExportService {

    private final LessonMapper lessonMapper;
    private final ClazzMapper clazzMapper;

    private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm");

    @Override
    public void exportLessons(Long tenantId, LocalDate startDate, LocalDate endDate, HttpServletResponse response) throws IOException {
        log.info("导出授课记录，租户 ID: {}, 时间范围：{} ~ {}", tenantId, startDate, endDate);

        // 1. 查询数据
        List<Map<String, Object>> rawData = lessonMapper.selectExportData(tenantId, startDate, endDate);

        // 2. 空数据处理 - 返回 JSON 响应
        if (rawData == null || rawData.isEmpty()) {
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write(com.alibaba.fastjson2.JSON.toJSONString(
                    Result.error(404, "指定时间范围内暂无授课记录")
            ));
            return;
        }

        // 3. 转换为 VO 对象
        List<LessonExportVO> data = rawData.stream().map(row -> {
            LessonExportVO vo = new LessonExportVO();
            // 修复：SQL 返回的是 java.sql.Date，需要转换为 LocalDate
            Object dateObj = row.get("lesson_date");
            if (dateObj instanceof java.sql.Date) {
                vo.setLessonDate(((java.sql.Date) dateObj).toLocalDate());
            } else if (dateObj instanceof LocalDate) {
                vo.setLessonDate((LocalDate) dateObj);
            }

            // 格式化时间范围 - 修复：SQL 返回的是 java.sql.Time
            Object startTimeObj = row.get("start_time");
            Object endTimeObj = row.get("end_time");
            if (startTimeObj instanceof java.sql.Time && endTimeObj instanceof java.sql.Time) {
                vo.setTimeRange(
                    ((java.sql.Time) startTimeObj).toLocalTime().format(TIME_FORMATTER) + "-" +
                    ((java.sql.Time) endTimeObj).toLocalTime().format(TIME_FORMATTER)
                );
            } else if (startTimeObj instanceof LocalTime && endTimeObj instanceof LocalTime) {
                vo.setTimeRange(
                    ((LocalTime) startTimeObj).format(TIME_FORMATTER) + "-" +
                    ((LocalTime) endTimeObj).format(TIME_FORMATTER)
                );
            }

            vo.setClassName(getStringValue(row, "className"));
            vo.setTeacherName(getStringValue(row, "teacherName"));
            vo.setCourseName(getStringValue(row, "courseName"));
            // 修复：课程类型需要从 lessonType 字段获取，并翻译成中文
            String lessonTypeCode = getStringValue(row, "lessonType");
            vo.setLessonType(translateLessonType(lessonTypeCode));
            vo.setStudentCount(getIntValue(row, "studentCount"));
            vo.setAvgParticipation(getDoubleValue(row, "avgParticipation"));
            vo.setFeedbackContent(getStringValue(row, "feedbackContent"));
            return vo;
        }).toList();

        // 4. 设置响应头
        setupExcelResponse(response, "授课记录");

        // 5. 使用 EasyExcel 导出
        EasyExcel.write(response.getOutputStream(), LessonExportVO.class)
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                .sheet("授课记录")
                .doWrite(data);

        log.info("授课记录导出成功，共{}条记录", data.size());
    }

    @Override
    public void exportTeacherStats(Long tenantId, LocalDate startDate, LocalDate endDate, HttpServletResponse response) throws IOException {
        log.info("导出教师绩效统计，租户 ID: {}, 时间范围：{} ~ {}", tenantId, startDate, endDate);

        // 1. 查询数据
        List<Map<String, Object>> rawData = lessonMapper.selectTeacherExportData(tenantId, startDate, endDate);

        // 2. 空数据处理
        if (rawData == null || rawData.isEmpty()) {
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write(com.alibaba.fastjson2.JSON.toJSONString(
                    Result.error(404, "指定时间范围内暂无教师绩效数据")
            ));
            return;
        }

        // 3. 转换为 VO 对象
        List<TeacherPerformanceExportVO> data = rawData.stream().map(row -> {
            TeacherPerformanceExportVO vo = new TeacherPerformanceExportVO();
            vo.setTeacherName(getStringValue(row, "teacherName"));
            vo.setClassNames(getStringValue(row, "classNames"));
            vo.setLessonCount(getIntValue(row, "lessonCount"));
            vo.setCourseCount(getIntValue(row, "courseCount"));
            // 修复：将活跃等级代码翻译成中文
            String activityLevelCode = getStringValue(row, "activityLevel");
            vo.setActivityLevel(translateActivityLevel(activityLevelCode));
            // 修复：SQL 返回的是 java.sql.Timestamp，需要转换为 LocalDateTime
            Object lastActiveAtObj = row.get("lastActiveAt");
            if (lastActiveAtObj instanceof java.sql.Timestamp) {
                vo.setLastActiveAt(((java.sql.Timestamp) lastActiveAtObj).toLocalDateTime());
            } else if (lastActiveAtObj instanceof LocalDateTime) {
                vo.setLastActiveAt((LocalDateTime) lastActiveAtObj);
            }
            vo.setAvgParticipation(getDoubleValue(row, "avgParticipation"));
            return vo;
        }).toList();

        // 4. 设置响应头
        setupExcelResponse(response, "教师绩效统计");

        // 5. 使用 EasyExcel 导出
        EasyExcel.write(response.getOutputStream(), TeacherPerformanceExportVO.class)
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                .sheet("教师绩效")
                .doWrite(data);

        log.info("教师绩效统计导出成功，共{}条记录", data.size());
    }

    @Override
    public void exportStudentStats(Long tenantId, Long classId, HttpServletResponse response) throws IOException {
        log.info("导出学生统计，租户 ID: {}, 班级 ID: {}", tenantId, classId);

        // 1. 查询数据
        List<Map<String, Object>> rawData = lessonMapper.selectStudentExportData(tenantId, classId);

        // 2. 空数据处理
        if (rawData == null || rawData.isEmpty()) {
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write(com.alibaba.fastjson2.JSON.toJSONString(
                    Result.error(404, "暂无学生统计数据")
            ));
            return;
        }

        // 3. 转换为 VO 对象
        List<StudentStatExportVO> data = rawData.stream().map(row -> {
            StudentStatExportVO vo = new StudentStatExportVO();
            vo.setStudentName(getStringValue(row, "studentName"));
            vo.setGender(getStringValue(row, "gender"));
            vo.setClassName(getStringValue(row, "className"));
            vo.setLessonCount(getIntValue(row, "lessonCount"));
            vo.setAvgParticipation(getDoubleValue(row, "avgParticipation"));
            vo.setAvgFocus(getDoubleValue(row, "avgFocus"));
            return vo;
        }).toList();

        // 4. 设置响应头
        String fileName = classId != null ? getClassName(classId) + "_学生统计" : "全校学生统计";
        setupExcelResponse(response, fileName);

        // 5. 使用 EasyExcel 导出
        EasyExcel.write(response.getOutputStream(), StudentStatExportVO.class)
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                .sheet("学生统计")
                .doWrite(data);

        log.info("学生统计导出成功，共{}条记录", data.size());
    }

    /**
     * 获取班级名称
     */
    private String getClassName(Long classId) {
        Clazz clazz = clazzMapper.selectById(classId);
        return clazz != null ? clazz.getName() : "班级";
    }

    /**
     * 设置 Excel 响应头
     */
    private void setupExcelResponse(HttpServletResponse response, String sheetName) throws IOException {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode(sheetName, "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
    }

    /**
     * 从 Map 中安全获取 String 值
     */
    private String getStringValue(Map<String, Object> row, String key) {
        Object value = row.get(key);
        return value != null ? value.toString() : "";
    }

    /**
     * 翻译活跃等级代码为中文
     */
    private String translateActivityLevel(String code) {
        if (code == null) {
            return "";
        }
        switch (code) {
            case "HIGH":
                return "高";
            case "MEDIUM":
                return "中";
            case "LOW":
                return "低";
            case "INACTIVE":
                return "未活跃";
            default:
                return code;
        }
    }

    /**
     * 翻译课程类型代码为中文
     */
    private String translateLessonType(String code) {
        if (code == null || code.isEmpty()) {
            return "集体";
        }
        switch (code) {
            case "INTRODUCTION":
            case "INTRO":
                return "入门";
            case "COLLECTIVE":
                return "集体";
            case "LANGUAGE":
                return "语言";
            case "HEALTH":
                return "健康";
            case "SCIENCE":
                return "科学";
            case "SOCIAL":
            case "SOCIETY":
                return "社会";
            case "ART":
                return "艺术";
            default:
                return code;
        }
    }

    /**
     * 从 Map 中安全获取 Integer 值
     */
    private Integer getIntValue(Map<String, Object> row, String key) {
        Object value = row.get(key);
        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;
        }
    }

    /**
     * 从 Map 中安全获取 Double 值
     */
    private Double getDoubleValue(Map<String, Object> row, String key) {
        Object value = row.get(key);
        if (value == null) {
            return null;
        }
        if (value instanceof Number) {
            return ((Number) value).doubleValue();
        }
        try {
            return Double.parseDouble(value.toString());
        } catch (NumberFormatException e) {
            return null;
        }
    }
}
