package com.lesingle.edu.controller.teacher;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lesingle.edu.common.enums.CourseStatus;
import com.lesingle.edu.common.annotation.Log;
import com.lesingle.edu.common.mapper.ClassMapper;
import com.lesingle.edu.common.mapper.CoursePackageMapper;
import com.lesingle.edu.common.mapper.StudentMapper;
import com.lesingle.edu.common.mapper.TeacherMapper;
import com.lesingle.edu.common.response.PageResult;
import com.lesingle.edu.common.response.Result;
import com.lesingle.edu.common.security.SecurityUtils;
import com.lesingle.edu.dto.response.ClassResponse;
import com.lesingle.edu.dto.response.ClassStudentsResponse;
import com.lesingle.edu.dto.response.CourseResponse;
import com.lesingle.edu.dto.response.LessonTagResponse;
import com.lesingle.edu.dto.response.StudentResponse;
import com.lesingle.edu.dto.response.TeacherResponse;
import com.lesingle.edu.entity.Clazz;
import com.lesingle.edu.entity.Lesson;
import com.lesingle.edu.entity.ParentStudent;
import com.lesingle.edu.entity.CoursePackage;
import com.lesingle.edu.entity.Student;
import com.lesingle.edu.entity.Teacher;
import com.lesingle.edu.entity.CourseLesson;
import com.lesingle.edu.mapper.LessonMapper;
import com.lesingle.edu.mapper.ParentMapper;
import com.lesingle.edu.mapper.ParentStudentMapper;
import com.lesingle.edu.mapper.StudentRecordMapper;
import com.lesingle.edu.service.ClassService;
import com.lesingle.edu.service.CourseLessonService;
import com.lesingle.edu.service.CoursePackageService;
import com.lesingle.edu.service.StudentService;
import com.lesingle.edu.service.TeacherService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Tag(name = "教师端 - 课程管理", description = "教师端课程 API")
@RestController
@RequestMapping("/api/v1/teacher")
@RequiredArgsConstructor
public class TeacherCourseController {

    private final CoursePackageService courseService;
    private final CourseLessonService courseLessonService;
    private final ClassService classService;
    private final StudentService studentService;
    private final TeacherService teacherService;
    private final CoursePackageMapper courseMapper;
    private final ClassMapper classMapper;
    private final StudentMapper studentMapper;
    private final TeacherMapper teacherMapper;
    private final LessonMapper lessonMapper;
    private final ParentMapper parentMapper;
    private final ParentStudentMapper parentStudentMapper;
    private final StudentRecordMapper studentRecordMapper;

    @Operation(summary = "获取教师的班级列表")
    @GetMapping("/classes")
    public Result<List<ClassResponse>> getClasses() {
        Long teacherId = SecurityUtils.getCurrentUserId();
        Long tenantId = SecurityUtils.getCurrentTenantId();
        List<Clazz> classes = classService.getClassesByTeacherId(teacherId, tenantId);

        List<ClassResponse> voList = classMapper.toVO(classes);
        for (ClassResponse vo : voList) {
            int studentCount = studentService.getStudentListByClassId(vo.getId()).size();
            long lessonCount = 0;
            try {
                lessonCount = lessonMapper.selectCount(
                        new LambdaQueryWrapper<Lesson>().eq(Lesson::getClassId, vo.getId()));
            } catch (Exception e) {
                // 忽略 lesson 表不存在等异常
            }
            String role = classService.getTeacherRoleInClass(vo.getId(), teacherId);
            vo.setStudentCount(studentCount);
            vo.setLessonCount((int) lessonCount);
            vo.setMyRole(mapRoleToFrontend(role));
            vo.setIsPrimary(isPrimaryRole(role));
        }
        return Result.success(voList);
    }

    private static String mapRoleToFrontend(String role) {
        if (role == null) return "ASSIST";
        return switch (role) {
            case "班主任", "主班" -> "MAIN";
            case "保育员" -> "CARE";
            default -> "ASSIST";
        };
    }

    private static boolean isPrimaryRole(String role) {
        return role != null && ("班主任".equals(role) || "主班".equals(role));
    }

    @Operation(summary = "根据 ID 获取课程")
    @GetMapping("/courses/{id}")
    public Result<CourseResponse> getCourse(@PathVariable Long id) {
        return Result.success(courseService.getCourseByIdWithLessons(id));
    }

    @Operation(summary = "获取课程分页列表")
    @GetMapping("/courses")
    public Result<PageResult<CourseResponse>> getCoursePage(
            @RequestParam(required = false, defaultValue = "1") Integer pageNum,
            @RequestParam(required = false, defaultValue = "10") Integer pageSize,
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) String grade,
            @RequestParam(required = false) String domain,
            @RequestParam(required = false) String lessonType) {
        Long tenantId = SecurityUtils.getCurrentTenantId();
        // 按 学校 -> 套餐 -> 课程包 层级查询，支持 grade/domain/lessonType 筛选
        Page<CoursePackage> page = courseService.getTenantPackageCoursePage(
                tenantId, pageNum, pageSize, keyword, grade, domain, lessonType, CourseStatus.PUBLISHED.getCode());
        List<CourseResponse> voList = courseMapper.toVO(page.getRecords());
        // 填充 lessonTags（仅 name、lessonType）供列表 tag 展示
        for (CourseResponse vo : voList) {
            List<CourseLesson> lessons = courseLessonService.findByCourseId(vo.getId());
            vo.setLessonTags(lessons.stream()
                    .map(l -> LessonTagResponse.builder()
                            .name(l.getName())
                            .lessonType(l.getLessonType())
                            .build())
                    .collect(Collectors.toList()));
        }
        return Result.success(PageResult.of(voList, page.getTotal(), page.getCurrent(), page.getSize()));
    }

    @Operation(summary = "获取所有课程")
    @GetMapping("/courses/all")
    public Result<List<CourseResponse>> getAllCourses(
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) String grade,
            @RequestParam(required = false) String domain) {
        Long tenantId = SecurityUtils.getCurrentTenantId();
        // 按 学校 -> 套餐 -> 课程包 层级查询
        List<CoursePackage> courses = courseService.getTenantPackageCourses(tenantId, keyword, grade, domain, null);
        return Result.success(courseMapper.toVO(courses));
    }

    @Operation(summary = "获取教师教授的所有学生")
    @GetMapping("/students")
    public Result<PageResult<StudentResponse>> getAllStudents(
            @RequestParam(required = false, defaultValue = "1") Integer pageNum,
            @RequestParam(required = false, defaultValue = "10") Integer pageSize,
            @RequestParam(required = false) String keyword) {
        Long teacherId = SecurityUtils.getCurrentUserId();
        Long tenantId = SecurityUtils.getCurrentTenantId();

        // 获取教师教授的所有班级
        List<Clazz> classes = classService.getActiveClassesByTenantId(tenantId);
        List<Long> classIds = classes.stream()
            .filter(clazz -> {
                // 检查教师是否教授该班级
                List<Long> teacherIds = classService.getTeacherIdsByClassId(clazz.getId());
                return teacherIds.contains(teacherId);
            })
            .map(Clazz::getId)
            .collect(Collectors.toList());

        if (classIds.isEmpty()) {
            return Result.success(PageResult.of(List.of(), 0L, (long) pageNum, (long) pageSize));
        }

        // 分页获取学生
        Page<Student> page = new Page<>(pageNum, pageSize);
        List<Student> students = studentService.getStudentsByClassIds(classIds, keyword, page);

        List<StudentResponse> voList = studentMapper.toVO(students);
        return Result.success(PageResult.of(voList, page.getTotal(), page.getCurrent(), page.getSize()));
    }

    @Operation(summary = "获取班级学生列表")
    @GetMapping("/classes/{id}/students")
    public Result<ClassStudentsResponse> getClassStudents(
            @PathVariable Long id,
            @RequestParam(required = false, defaultValue = "1") Integer pageNum,
            @RequestParam(required = false, defaultValue = "10") Integer pageSize,
            @RequestParam(required = false) String keyword) {
        Long tenantId = SecurityUtils.getCurrentTenantId();
        Clazz clazz = classService.getClassByIdWithTenantCheck(id, tenantId);
        Page<Student> page = studentService.getStudentsByClassId(id, pageNum, pageSize, keyword);
        List<StudentResponse> voList = studentMapper.toVO(page.getRecords());
        List<Long> studentIds = voList.stream().map(StudentResponse::getId).toList();
        List<Map<String, Object>> statsList = studentIds.isEmpty()
                ? List.of()
                : studentRecordMapper.selectStudentStats(studentIds);
        Map<Long, Map<String, Object>> statsMap = statsList.stream()
                .collect(Collectors.toMap(m -> ((Number) m.get("studentId")).longValue(), m -> m));

        for (StudentResponse vo : voList) {
            var parentRelation = parentStudentMapper.selectOne(
                    new LambdaQueryWrapper<ParentStudent>()
                            .eq(ParentStudent::getStudentId, vo.getId())
                            .eq(ParentStudent::getIsPrimary, 1)
                            .last("LIMIT 1"));
            if (parentRelation != null) {
                var parent = parentMapper.selectById(parentRelation.getParentId());
                if (parent != null) {
                    vo.setParentName(parent.getName());
                    vo.setParentPhone(parent.getPhone());
                }
            }
            var stats = statsMap.get(vo.getId());
            if (stats != null) {
                vo.setReadingCount(((Number) stats.getOrDefault("readingCount", 0)).intValue());
                vo.setLessonCount(vo.getReadingCount());
                vo.setAvgScore(((Number) stats.getOrDefault("avgScore", 0)).intValue());
            } else {
                vo.setReadingCount(0);
                vo.setLessonCount(0);
                vo.setAvgScore(0);
            }
        }

        int studentCount = studentService.getStudentListByClassId(id).size();
        long lessonCount = 0;
        try {
            lessonCount = lessonMapper.selectCount(
                    new LambdaQueryWrapper<Lesson>().eq(Lesson::getClassId, id));
        } catch (Exception e) {
            // 忽略 lesson 表不存在等异常
        }

        ClassStudentsResponse.ClassInfo classInfo = ClassStudentsResponse.ClassInfo.builder()
                .id(clazz.getId())
                .name(clazz.getName())
                .grade(clazz.getGrade())
                .studentCount(studentCount)
                .lessonCount((int) lessonCount)
                .build();

        ClassStudentsResponse response = ClassStudentsResponse.builder()
                .list(voList)
                .total(page.getTotal())
                .pageNum(page.getCurrent())
                .pageSize(page.getSize())
                .classInfo(classInfo)
                .build();
        return Result.success(response);
    }

    @Operation(summary = "获取班级教师列表")
    @GetMapping("/classes/{id}/teachers")
    public Result<List<TeacherResponse>> getClassTeachers(@PathVariable Long id) {
        List<Long> teacherIds = classService.getTeacherIdsByClassId(id);
        if (teacherIds.isEmpty()) {
            return Result.success(List.of());
        }
        List<Teacher> teachers = teacherService.getTeachersByIds(teacherIds);
        return Result.success(teacherMapper.toVO(teachers));
    }

}
