package com.ruoyi.web.controller.education;

import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.education.domain.EduCourseSchedule;
import com.ruoyi.education.service.IEduCourseScheduleService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.StringUtils;

/**
 * 开课节次安排Controller
 * 
 * @author ruoyi
 * @date 2024-09-26
 */
@RestController
@RequestMapping("/education/schedule")
public class EduCourseScheduleController extends BaseController
{
    @Autowired
    private IEduCourseScheduleService eduCourseScheduleService;

    /**
     * 查询开课节次安排列表
     */
    @PreAuthorize("@ss.hasPermi('education:schedule:list')")
    @GetMapping("/list")
    public TableDataInfo list(EduCourseSchedule eduCourseSchedule)
    {
        startPage();
        List<EduCourseSchedule> list = eduCourseScheduleService.selectEduCourseScheduleList(eduCourseSchedule);
        return getDataTable(list);
    }

    /**
     * 导出开课节次安排列表
     */
    @PreAuthorize("@ss.hasPermi('education:schedule:export')")
    @Log(title = "开课节次安排", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, EduCourseSchedule eduCourseSchedule)
    {
        List<EduCourseSchedule> list = eduCourseScheduleService.selectEduCourseScheduleList(eduCourseSchedule);
        ExcelUtil<EduCourseSchedule> util = new ExcelUtil<EduCourseSchedule>(EduCourseSchedule.class);
        util.exportExcel(response, list, "开课节次安排数据");
    }

    /**
     * 获取开课节次安排详细信息
     */
    @PreAuthorize("@ss.hasPermi('education:schedule:query')")
    @GetMapping(value = "/{scheduleId}")
    public AjaxResult getInfo(@PathVariable("scheduleId") Long scheduleId)
    {
        return success(eduCourseScheduleService.selectEduCourseScheduleByScheduleId(scheduleId));
    }

    /**
     * 新增开课节次安排
     */
    @PreAuthorize("@ss.hasPermi('education:schedule:add')")
    @Log(title = "开课节次安排", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody EduCourseSchedule eduCourseSchedule)
    {
        String periodResult = eduCourseScheduleService.checkPeriodValid(eduCourseSchedule);
        if (!"VALID".equals(periodResult))
        {
            return getPeriodErrorMessage(periodResult);
        }
        
        String weeksResult = eduCourseScheduleService.checkWeeksValid(eduCourseSchedule.getWeeks());
        if (!"VALID".equals(weeksResult))
        {
            return getWeeksErrorMessage(weeksResult);
        }
        
        String conflictResult = eduCourseScheduleService.checkTimeConflict(eduCourseSchedule);
        if (!"NO_CONFLICT".equals(conflictResult))
        {
            return getConflictErrorMessage(conflictResult);
        }
        
        eduCourseSchedule.setCreateBy(getUsername());
        return toAjax(eduCourseScheduleService.insertEduCourseSchedule(eduCourseSchedule));
    }

    /**
     * 修改开课节次安排
     */
    @PreAuthorize("@ss.hasPermi('education:schedule:edit')")
    @Log(title = "开课节次安排", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody EduCourseSchedule eduCourseSchedule)
    {
        String periodResult = eduCourseScheduleService.checkPeriodValid(eduCourseSchedule);
        if (!"VALID".equals(periodResult))
        {
            return getPeriodErrorMessage(periodResult);
        }
        
        String weeksResult = eduCourseScheduleService.checkWeeksValid(eduCourseSchedule.getWeeks());
        if (!"VALID".equals(weeksResult))
        {
            return getWeeksErrorMessage(weeksResult);
        }
        
        String conflictResult = eduCourseScheduleService.checkTimeConflict(eduCourseSchedule);
        if (!"NO_CONFLICT".equals(conflictResult))
        {
            return getConflictErrorMessage(conflictResult);
        }
        
        eduCourseSchedule.setUpdateBy(getUsername());
        return toAjax(eduCourseScheduleService.updateEduCourseSchedule(eduCourseSchedule));
    }

    /**
     * 删除开课节次安排
     */
    @PreAuthorize("@ss.hasPermi('education:schedule:remove')")
    @Log(title = "开课节次安排", businessType = BusinessType.DELETE)
	@DeleteMapping("/{scheduleIds}")
    public AjaxResult remove(@PathVariable Long[] scheduleIds)
    {
        return toAjax(eduCourseScheduleService.deleteEduCourseScheduleByScheduleIds(scheduleIds));
    }

    /**
     * 根据开课ID查询节次安排
     */
    @PreAuthorize("@ss.hasPermi('education:schedule:query')")
    @GetMapping("/class/{classId}")
    public AjaxResult getByClassId(@PathVariable Long classId)
    {
        return success(eduCourseScheduleService.selectScheduleByClassId(classId));
    }

    /**
     * 根据开课ID删除节次安排
     */
    @PreAuthorize("@ss.hasPermi('education:schedule:remove')")
    @Log(title = "删除开课节次安排", businessType = BusinessType.DELETE)
    @DeleteMapping("/class/{classId}")
    public AjaxResult removeByClassId(@PathVariable Long classId)
    {
        return toAjax(eduCourseScheduleService.deleteScheduleByClassId(classId));
    }

    /**
     * 查询指定教室的课程安排
     */
    @PreAuthorize("@ss.hasPermi('education:schedule:query')")
    @GetMapping("/classroom/{classroomId}/{semesterId}")
    public AjaxResult getByClassroom(@PathVariable Long classroomId, @PathVariable Long semesterId)
    {
        return success(eduCourseScheduleService.selectScheduleByClassroom(classroomId, semesterId));
    }

    /**
     * 查询指定教师的课程安排
     */
    @PreAuthorize("@ss.hasPermi('education:schedule:query')")
    @GetMapping("/teacher/{teacherId}/{semesterId}")
    public AjaxResult getByTeacher(@PathVariable Long teacherId, @PathVariable Long semesterId)
    {
        return success(eduCourseScheduleService.selectScheduleByTeacher(teacherId, semesterId));
    }

    /**
     * 查询指定学期的所有课程安排
     */
    @PreAuthorize("@ss.hasPermi('education:schedule:query')")
    @GetMapping("/semester/{semesterId}")
    public AjaxResult getBySemester(@PathVariable Long semesterId)
    {
        return success(eduCourseScheduleService.selectScheduleBySemester(semesterId));
    }

    /**
     * 生成教室课表
     */
    @PreAuthorize("@ss.hasPermi('education:schedule:query')")
    @GetMapping("/timetable/classroom/{classroomId}/{semesterId}")
    public AjaxResult generateClassroomTimetable(@PathVariable Long classroomId, @PathVariable Long semesterId)
    {
        return success(eduCourseScheduleService.generateClassroomTimetable(classroomId, semesterId));
    }

    /**
     * 生成教师课表
     */
    @PreAuthorize("@ss.hasPermi('education:schedule:query')")
    @GetMapping("/timetable/teacher/{teacherId}/{semesterId}")
    public AjaxResult generateTeacherTimetable(@PathVariable Long teacherId, @PathVariable Long semesterId)
    {
        return success(eduCourseScheduleService.generateTeacherTimetable(teacherId, semesterId));
    }

    /**
     * 批量添加节次安排
     */
    @PreAuthorize("@ss.hasPermi('education:schedule:add')")
    @Log(title = "批量添加节次安排", businessType = BusinessType.INSERT)
    @PostMapping("/batch/{classId}")
    public AjaxResult batchAdd(@PathVariable Long classId, @RequestBody List<EduCourseSchedule> scheduleList)
    {
        if (scheduleList == null || scheduleList.isEmpty())
        {
            return error("节次安排列表不能为空");
        }
        
        for (EduCourseSchedule schedule : scheduleList)
        {
            String periodResult = eduCourseScheduleService.checkPeriodValid(schedule);
            if (!"VALID".equals(periodResult))
            {
                return error("第" + scheduleList.indexOf(schedule) + "项：" + getPeriodErrorText(periodResult));
            }
            
            String weeksResult = eduCourseScheduleService.checkWeeksValid(schedule.getWeeks());
            if (!"VALID".equals(weeksResult))
            {
                return error("第" + scheduleList.indexOf(schedule) + "项：" + getWeeksErrorText(weeksResult));
            }
            
            String conflictResult = eduCourseScheduleService.checkTimeConflict(schedule);
            if (!"NO_CONFLICT".equals(conflictResult))
            {
                return error("第" + scheduleList.indexOf(schedule) + "项：" + getConflictErrorText(conflictResult));
            }
        }
        
        return toAjax(eduCourseScheduleService.batchAddSchedule(classId, scheduleList));
    }

    /**
     * 复制节次安排
     */
    @PreAuthorize("@ss.hasPermi('education:schedule:add')")
    @Log(title = "复制节次安排", businessType = BusinessType.INSERT)
    @PostMapping("/copy/{sourceClassId}/{targetClassId}")
    public AjaxResult copySchedule(@PathVariable Long sourceClassId, @PathVariable Long targetClassId)
    {
        return toAjax(eduCourseScheduleService.copySchedule(sourceClassId, targetClassId));
    }

    /**
     * 自动排课
     */
    @PreAuthorize("@ss.hasPermi('education:schedule:add')")
    @Log(title = "自动排课", businessType = BusinessType.INSERT)
    @PostMapping("/auto/{classId}/{semesterId}/{courseHours}")
    public AjaxResult autoSchedule(@PathVariable Long classId, @PathVariable Long semesterId, @PathVariable Integer courseHours)
    {
        String result = eduCourseScheduleService.autoSchedule(classId, semesterId, courseHours);
        if ("AUTO_SCHEDULE_NOT_IMPLEMENTED".equals(result))
        {
            return error("自动排课功能暂未实现");
        }
        return success("自动排课完成");
    }

    /**
     * 获取时间段统计信息
     */
    @PreAuthorize("@ss.hasPermi('education:schedule:query')")
    @GetMapping("/statistics/{semesterId}")
    public AjaxResult getStatistics(@PathVariable Long semesterId)
    {
        return success(eduCourseScheduleService.getTimeSlotStatistics(semesterId));
    }

    /**
     * 获取节次校验错误信息
     */
    private AjaxResult getPeriodErrorMessage(String periodResult)
    {
        switch (periodResult)
        {
            case "INVALID_WEEKDAY":
                return error("星期几必须在1-7之间");
            case "INVALID_PERIOD_START":
                return error("开始节次必须在1-12之间");
            case "INVALID_PERIOD_END":
                return error("结束节次必须在1-12之间");
            case "PERIOD_START_AFTER_END":
                return error("开始节次不能大于结束节次");
            case "PERIOD_TOO_LONG":
                return error("单次课程最多不能超过4节课");
            default:
                return error("节次设置无效");
        }
    }

    /**
     * 获取周次校验错误信息
     */
    private AjaxResult getWeeksErrorMessage(String weeksResult)
    {
        switch (weeksResult)
        {
            case "INVALID_FORMAT":
                return error("周次格式不正确，应为数字、逗号、减号的组合");
            case "INVALID_RANGE":
                return error("周次范围格式不正确");
            case "INVALID_WEEK_NUMBER":
                return error("周次必须在1-25之间");
            case "INVALID_NUMBER":
                return error("周次必须为数字");
            default:
                return error("周次设置无效");
        }
    }

    /**
     * 获取冲突校验错误信息
     */
    private AjaxResult getConflictErrorMessage(String conflictResult)
    {
        switch (conflictResult)
        {
            case "CLASSROOM_CONFLICT":
                return error("教室时间冲突");
            case "TEACHER_CONFLICT":
                return error("教师时间冲突");
            default:
                return error("时间冲突");
        }
    }

    /**
     * 获取节次校验错误文本
     */
    private String getPeriodErrorText(String periodResult)
    {
        switch (periodResult)
        {
            case "INVALID_WEEKDAY":
                return "星期几必须在1-7之间";
            case "INVALID_PERIOD_START":
                return "开始节次必须在1-12之间";
            case "INVALID_PERIOD_END":
                return "结束节次必须在1-12之间";
            case "PERIOD_START_AFTER_END":
                return "开始节次不能大于结束节次";
            case "PERIOD_TOO_LONG":
                return "单次课程最多不能超过4节课";
            default:
                return "节次设置无效";
        }
    }

    /**
     * 获取周次校验错误文本
     */
    private String getWeeksErrorText(String weeksResult)
    {
        switch (weeksResult)
        {
            case "INVALID_FORMAT":
                return "周次格式不正确";
            case "INVALID_RANGE":
                return "周次范围格式不正确";
            case "INVALID_WEEK_NUMBER":
                return "周次必须在1-25之间";
            case "INVALID_NUMBER":
                return "周次必须为数字";
            default:
                return "周次设置无效";
        }
    }

    /**
     * 获取冲突校验错误文本
     */
    private String getConflictErrorText(String conflictResult)
    {
        switch (conflictResult)
        {
            case "CLASSROOM_CONFLICT":
                return "教室时间冲突";
            case "TEACHER_CONFLICT":
                return "教师时间冲突";
            default:
                return "时间冲突";
        }
    }
}