package com.ruoyi.course.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.course.util.TimeUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import com.ruoyi.course.domain.*;
import com.ruoyi.course.domain.Clazz;
import com.ruoyi.course.domain.dto.ScheduleRequest;
import com.ruoyi.course.domain.dto.ScheduleResult;
import com.ruoyi.course.mapper.*;
import com.ruoyi.course.service.impl.CourseScheduler;
import com.ruoyi.course.service.impl.TimeTableManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

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

/**
 * 排课控制器
 */
@RestController
@RequestMapping("/course/schedule")
@Tag(name = "排课管理", description = "课程排课、课表查询和排课管理相关接口")
public class ScheduleController {

    @Autowired
    private CourseScheduler courseScheduler;

    @Autowired
    private ClassScheduleMapper classScheduleMapper;

    @Autowired
    private TimeTableManager timeTableManager;

    @Autowired
    private CourseMapper courseMapper;

    @Autowired
    private TeacherMapper teacherMapper;

    @Autowired
    private ClassroomMapper classroomMapper;

    @Autowired
    private ClazzMapper clazzMapper;

    @Autowired
    private StudentMapper studentMapper;

    @Autowired
    private TimeSlotMapper timeSlotMapper;

    @Autowired
    private ScheduleItemMapper scheduleItemMapper;

    @Autowired
    private StudentScheduleMapper studentScheduleMapper;

    @Operation(summary = "执行排课", description = "根据排课请求执行课程排课")
    @PostMapping("/execute")
    public ScheduleResult executeSchedule(@RequestBody ScheduleRequest request) {
        return courseScheduler.scheduleCourses(request);
    }

    @Operation(summary = "获取学生个人课表", description = "获取指定学生在指定学期的个人课表")
    @GetMapping("/student/{studentId}")
    public Map<String, Object> getStudentSchedule(
            @Parameter(description = "学生ID", required = true, example = "1001")
            @PathVariable Long studentId,
            @Parameter(description = "学期", required = true, example = "2025-2026-1")
            @RequestParam String semester) {

        Map<String, Object> result = new HashMap<>();

        // 获取学生信息
        Student student = studentMapper.selectById(studentId);
        if (student == null) {
            result.put("success", false);
            result.put("message", "学生不存在");
            return result;
        }

        // 获取学生课表
        Map<String, Map<Integer, String>> timetable = courseScheduler.getStudentTimetable(studentId, semester);

        result.put("success", true);
        result.put("studentId", studentId);
        result.put("studentName", student.getName());
        result.put("className", getClassName(student.getClassId()));
        result.put("grade", student.getGrade());
        result.put("semester", semester);
        result.put("timetable", timetable);

        return result;
    }

    @Operation(summary = "获取班级课表", description = "获取指定班级在指定学期的课表")
    @GetMapping("/class/{classId}")
    public Map<String, Object> getClassSchedule(
            @Parameter(description = "班级ID", required = true, example = "1")
            @PathVariable Long classId,
            @Parameter(description = "学期", required = true, example = "2025-2026-1")
            @RequestParam String semester) {

        Map<String, Object> result = new HashMap<>();

        // 获取班级信息
        Clazz clazz = clazzMapper.selectById(classId);
        if (clazz == null) {
            result.put("success", false);
            result.put("message", "班级不存在");
            return result;
        }

        // 查询班级的所有排课项
        LambdaQueryWrapper<ScheduleItem> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ScheduleItem::getClassId, classId).eq(ScheduleItem::getSemester, semester).eq(ScheduleItem::getStatus, 1).orderByAsc(ScheduleItem::getDayOfWeek).orderByAsc(ScheduleItem::getPeriod);

        List<ScheduleItem> scheduleItems = scheduleItemMapper.selectList(wrapper);

        // 构建课表
        Map<String, Map<Integer, Map<String, Object>>> timetable = new HashMap<>();
        String[] days = {"周一", "周二", "周三", "周四", "周五", "周六"};
        for (String day : days) {
            timetable.put(day, new HashMap<>());
        }

        for (ScheduleItem item : scheduleItems) {
            String day = TimeUtil.getDayName(item.getDayOfWeek());
            Integer period = item.getPeriod();

            // 获取课程、教师、教室信息
            Course course = courseMapper.selectById(item.getCourseId());
            Teacher teacher = teacherMapper.selectById(item.getTeacherId());
            Classroom classroom = classroomMapper.selectById(item.getClassroomId());

            Map<String, Object> courseInfo = new HashMap<>();
            courseInfo.put("courseId", item.getCourseId());
            courseInfo.put("courseName", course != null ? course.getCourseName() : "未知课程");
            courseInfo.put("teacherId", item.getTeacherId());
            courseInfo.put("teacherName", teacher != null ? teacher.getTeacherName() : "未知教师");
            courseInfo.put("classroomId", item.getClassroomId());
            courseInfo.put("classroomName", classroom != null ? classroom.getRoomName() : "未知教室");
            courseInfo.put("courseType", item.getCourseType());

            timetable.get(day).put(period, courseInfo);
        }

        result.put("success", true);
        result.put("classId", classId);
        result.put("className", clazz.getClassName());
        result.put("grade", clazz.getGrade());
        result.put("semester", semester);
        result.put("timetable", timetable);

        return result;
    }



    @Operation(summary = "获取排课统计", description = "获取指定学期的排课统计信息")
    @GetMapping("/statistics")
    public Map<String, Object> getScheduleStatistics(
            @Parameter(description = "学期", required = true, example = "2025-2026-1")
            @RequestParam String semester) {
        Map<String, Object> result = new HashMap<>();

        try {
            // 排课项统计
            LambdaQueryWrapper<ScheduleItem> itemWrapper = new LambdaQueryWrapper<>();
            itemWrapper.eq(ScheduleItem::getSemester, semester);
            Long totalItems = scheduleItemMapper.selectCount(itemWrapper);

            // 按课程类型统计
            LambdaQueryWrapper<ScheduleItem> requiredWrapper = new LambdaQueryWrapper<>();
            requiredWrapper.eq(ScheduleItem::getSemester, semester).eq(ScheduleItem::getCourseType, "必修");
            Long requiredCourses = scheduleItemMapper.selectCount(requiredWrapper);

            LambdaQueryWrapper<ScheduleItem> electiveWrapper = new LambdaQueryWrapper<>();
            electiveWrapper.eq(ScheduleItem::getSemester, semester).eq(ScheduleItem::getCourseType, "选修");
            Long electiveCourses = scheduleItemMapper.selectCount(electiveWrapper);

            // 学生课表统计
            LambdaQueryWrapper<StudentSchedule> studentScheduleWrapper = new LambdaQueryWrapper<>();
            studentScheduleWrapper.eq(StudentSchedule::getSemester, semester);
            Long studentSchedules = studentScheduleMapper.selectCount(studentScheduleWrapper);

            // 时间槽统计
            Map<String, Object> timeSlotStats = timeTableManager.getTimeSlotStatistics(semester);

            result.put("success", true);
            result.put("semester", semester);
            result.put("totalScheduleItems", totalItems);
            result.put("requiredCourses", requiredCourses);
            result.put("electiveCourses", electiveCourses);
            result.put("studentSchedules", studentSchedules);
            result.put("timeSlotStats", timeSlotStats);
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取统计信息失败: " + e.getMessage());
        }

        return result;
    }

    @Operation(summary = "优化时间表", description = "优化指定学期的时间表，减少冲突")
    @PostMapping("/optimize")
    public Map<String, Object> optimizeTimetable(
            @Parameter(description = "学期", required = true, example = "2025-2026-1")
            @RequestParam String semester) {
        Map<String, Object> result = new HashMap<>();

        try {
            // 优化前先检查冲突
            List<ScheduleItem> conflicts = timeTableManager.getAllConflicts(semester);

            // 执行优化
            int optimizedCount = timeTableManager.optimizeTimetable(semester);

            // 优化后再次检查冲突
            List<ScheduleItem> remainingConflicts = timeTableManager.getAllConflicts(semester);

            result.put("success", true);
            result.put("message", "时间表优化完成");
            result.put("optimizedCount", optimizedCount);
            result.put("initialConflicts", conflicts.size());
            result.put("remainingConflicts", remainingConflicts.size());
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "时间表优化失败: " + e.getMessage());
        }

        return result;
    }

    @Operation(summary = "获取排课冲突", description = "获取指定学期的排课冲突信息")
    @GetMapping("/conflicts")
    public Map<String, Object> getConflicts(
            @Parameter(description = "学期", required = true, example = "2025-2026-1")
            @RequestParam String semester) {
        Map<String, Object> result = new HashMap<>();

        try {
            List<ScheduleItem> teacherConflicts = timeTableManager.getTeacherConflicts(semester);
            List<ScheduleItem> classroomConflicts = timeTableManager.getClassroomConflicts(semester);
            List<ScheduleItem> allConflicts = timeTableManager.getAllConflicts(semester);

            result.put("success", true);
            result.put("semester", semester);
            result.put("teacherConflicts", teacherConflicts.size());
            result.put("classroomConflicts", classroomConflicts.size());
            result.put("totalConflicts", allConflicts.size());
            result.put("teacherConflictDetails", formatConflicts(teacherConflicts, "教师"));
            result.put("classroomConflictDetails", formatConflicts(classroomConflicts, "教室"));
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取冲突信息失败: " + e.getMessage());
        }

        return result;
    }

    @Operation(summary = "批量禁用时间槽（节假日）", description = "批量禁用时间槽，用于节假日设置")
    @PostMapping("/disable-slots")
    public Map<String, Object> disableTimeSlots(
            @Parameter(description = "日期列表（1-7代表周一至周日）", required = true, example = "[6,7]")
            @RequestParam List<Integer> days,
            @Parameter(description = "禁用原因", required = false, example = "节假日")
            @RequestParam(defaultValue = "节假日") String reason) {

        Map<String, Object> result = new HashMap<>();

        try {
            int disabledCount = timeTableManager.disableTimeSlots(days, reason);

            result.put("success", true);
            result.put("message", "时间槽禁用成功");
            result.put("disabledCount", disabledCount);
            result.put("days", days);
            result.put("reason", reason);
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "时间槽禁用失败: " + e.getMessage());
        }

        return result;
    }

    @Operation(summary = "批量启用时间槽", description = "批量启用已禁用的时间槽")
    @PostMapping("/enable-slots")
    public Map<String, Object> enableTimeSlots(
            @Parameter(description = "日期列表（1-7代表周一至周日）", required = true, example = "[6,7]")
            @RequestParam List<Integer> days) {
        Map<String, Object> result = new HashMap<>();

        try {
            int enabledCount = timeTableManager.enableTimeSlots(days);

            result.put("success", true);
            result.put("message", "时间槽启用成功");
            result.put("enabledCount", enabledCount);
            result.put("days", days);
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "时间槽启用失败: " + e.getMessage());
        }

        return result;
    }

    @Operation(summary = "获取节假日时间槽", description = "获取所有节假日时间槽信息")
    @GetMapping("/holiday-slots")
    public Map<String, Object> getHolidaySlots() {
        Map<String, Object> result = new HashMap<>();

        try {
            List<TimeSlot> holidaySlots = timeTableManager.getHolidaySlots();

            result.put("success", true);
            result.put("total", holidaySlots.size());
            result.put("holidaySlots", holidaySlots);
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取节假日时间槽失败: " + e.getMessage());
        }

        return result;
    }



    @Operation(summary = "清除指定学期的排课数据", description = "清除指定学期的所有排课相关数据")
    @DeleteMapping("/clear")
    public Map<String, Object> clearScheduleData(
            @Parameter(description = "学期", required = true, example = "2025-2026-1")
            @RequestParam String semester) {
        Map<String, Object> result = new HashMap<>();

        try {
            // 删除排课项
            LambdaQueryWrapper<ScheduleItem> itemWrapper = new LambdaQueryWrapper<>();
            itemWrapper.eq(ScheduleItem::getSemester, semester);
            int itemCount = scheduleItemMapper.delete(itemWrapper);

            // 删除学生课表
            LambdaQueryWrapper<StudentSchedule> studentWrapper = new LambdaQueryWrapper<>();
            studentWrapper.eq(StudentSchedule::getSemester, semester);
            int studentCount = studentScheduleMapper.delete(studentWrapper);

            // 删除班级课表
            LambdaQueryWrapper<ClassSchedule> classWrapper = new LambdaQueryWrapper<>();
            classWrapper.eq(ClassSchedule::getSemester, semester);
            int classCount = classScheduleMapper.delete(classWrapper);

            result.put("success", true);
            result.put("message", "排课数据清除成功");
            result.put("semester", semester);
            result.put("deletedScheduleItems", itemCount);
            result.put("deletedStudentSchedules", studentCount);
            result.put("deletedClassSchedules", classCount);
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "排课数据清除失败: " + e.getMessage());
        }

        return result;
    }

    /**
     * 格式化冲突信息
     */
    private List<Map<String, Object>> formatConflicts(List<ScheduleItem> conflicts, String conflictType) {
        return conflicts.stream().map(conflict -> {
            Map<String, Object> conflictInfo = new HashMap<>();
            conflictInfo.put("id", conflict.getId());
            conflictInfo.put("conflictType", conflictType);

            // 获取详细信息
            Course course = courseMapper.selectById(conflict.getCourseId());
            Teacher teacher = teacherMapper.selectById(conflict.getTeacherId());
            Classroom classroom = classroomMapper.selectById(conflict.getClassroomId());
            TimeSlot timeSlot = timeSlotMapper.selectById(conflict.getTimeSlotId());

            conflictInfo.put("courseName", course != null ? course.getCourseName() : "未知课程");
            conflictInfo.put("teacherName", teacher != null ? teacher.getTeacherName() : "未知教师");
            conflictInfo.put("classroomName", classroom != null ? classroom.getRoomName() : "未知教室");
            conflictInfo.put("day", conflict.getDayOfWeek());
            conflictInfo.put("period", conflict.getPeriod());
            conflictInfo.put("timeSlotName", timeSlot != null ? timeSlot.getSlotName() : "未知时间");

            return conflictInfo;
        }).collect(java.util.stream.Collectors.toList());
    }

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


}