package com.jevon.controller;

import com.jevon.model.*;
import com.jevon.service.*;
import com.jevon.vo.BaseVo;
import com.jevon.vo.req.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

@RestController
@RequestMapping(value = "/schedule")
@Api(value = "排课表")
public class ScheduleController {

    @Autowired
    ClassCourseService classCourseService;

    @Autowired
    ClassModelService classModelService;

    @Autowired
    TeacherCourseService teacherCourseService;

    @Autowired
    TeacherClassService teacherClassService;

    @Autowired
    CourseService courseService;

    @Autowired
    JoinClassService joinClassService;

    @Autowired
    ScheduleService scheduleService;

    @ApiOperation("作息安排")
    @RequestMapping(value = "firstChoose", method = RequestMethod.POST)
    public BaseVo firstChoose(@RequestBody FirstReqVo firstReqVo){
        BaseVo baseVo = new BaseVo();
        Schedule schedule = scheduleService.selectById(firstReqVo.getScheduleId());
        if(schedule != null && schedule.getSpeed() == 0){
            schedule.setMorning(firstReqVo.getMorning());
            schedule.setAfternoon(firstReqVo.getAfternoon());
            schedule.setNight(firstReqVo.getNight());
            scheduleService.updateZuoxi(schedule);
            firstReqVo.setDayNumber(firstReqVo.getMorning()+firstReqVo.getAfternoon()+firstReqVo.getNight());
            List<ClassCourse> classCourses = new ArrayList<>();
            //暂时只有单周
            for (int i = 1; i <= 7; i++) {
                classCourses.addAll(setClassCourse(false,i,firstReqVo));
            }
            classCourseService.insertSchoolClass(classCourses);
            schedule.setSpeed(2);
            scheduleService.updateSpeed(schedule);
        }else {
            baseVo.setMessage("排课计划不存在或已生成作息");
            baseVo.setSuccess(false);
        }
        return  baseVo;
    }

    @ApiOperation("设置公共资源课,主课,副课")
    @RequestMapping(value = "setCourseType", method = RequestMethod.POST)
    public BaseVo setCourseType(@RequestBody SetTypeReqVo setTypeReqVo){
        BaseVo baseVo = new BaseVo();
        Schedule schedule = scheduleService.selectById(setTypeReqVo.getScheduleId());
        if(schedule == null){
            baseVo.setMessage("参数有误");
            baseVo.setSuccess(false);
            return baseVo;
        }
        if(teacherClassService.selectHasSchedule(schedule.getSchoolId(),schedule.getTeam()) >0){
            baseVo.setMessage("已经部分排课,不能再设置");
            baseVo.setSuccess(false);
            return baseVo;
        }
        for(Integer courseId : setTypeReqVo.getCourseIdList()){
            if(setTypeReqVo.getCourseType() !=1 && setTypeReqVo.getCourseType() != 2 &&setTypeReqVo.getCourseType() != 3){
                baseVo.setMessage("课程类型错误");
                baseVo.setSuccess(false);
                return baseVo;
            }
            courseService.updateCourseType(courseId,setTypeReqVo.getCourseType(),schedule.getSchoolId());
        }
        return baseVo;
    }

    @ApiOperation("合班")
    @RequestMapping(value = "joinClass", method = RequestMethod.POST)
    public BaseVo joinClass(@RequestBody JoinClassReqVo joinClassReqVo){
        BaseVo baseVo = new BaseVo();
        Schedule schedule = scheduleService.selectById(joinClassReqVo.getScheduleId());
        if(teacherClassService.selectHasSchedule(schedule.getSchoolId(),schedule.getTeam()) >0){
            baseVo.setMessage("已经部分排课,不能再设置");
            baseVo.setSuccess(false);
            return baseVo;
        }
        Course course = courseService.selectBySchoolIdAndCourseId(schedule.getSchoolId(),joinClassReqVo.getCourseId());
        List<JoinClass> list = new ArrayList<>();
        String grade = null ;
        String teacherName = null ;
        for(Integer classId : joinClassReqVo.getClassIdList()){
            ClassModel classModel = classModelService.selectByPrimaryKey(classId);
            if(grade == null){
                grade = classModel.getGrade();
            }
            if(!grade.equals(classModel.getGrade())){
                baseVo.setMessage("合班不能跨年段");
                baseVo.setSuccess(false);
                return baseVo;
            }
            TeacherClass teacherClass = new TeacherClass();
            teacherClass.setTeam(schedule.getTeam());
            teacherClass.setSchoolId(schedule.getSchoolId());
            teacherClass.setCourseName(course.getCourseName());
            teacherClass.setClassId(classId);
            TeacherClass resultTeacherClass = teacherClassService.selectByCourseAndClass(teacherClass);
            if(teacherName == null){
                teacherName = resultTeacherClass.getTeacherName();
            }
            if(!teacherName.equals(resultTeacherClass.getTeacherName())){
                baseVo.setMessage("合班必须同一个老师");
                baseVo.setSuccess(false);
                return baseVo;
            }
            JoinClass joinClass = new JoinClass();
            joinClass.setSchoolId(schedule.getSchoolId());
            joinClass.setClassId(classId);
            joinClass.setTeam(schedule.getTeam());
            joinClass.setCourseId(course.getCourseId());
            joinClass.setCourseName(course.getCourseName());
            List<JoinClass> joinClasses = joinClassService.selectByCourse(joinClass);
            if(joinClasses != null && joinClasses.size() > 0){
                baseVo.setSuccess(false);
                baseVo.setMessage("不能重复合班");
                return baseVo;
            }
            list.add(joinClass);
        }
        joinClassService.insertBatch(list);
        return baseVo;
    }

    @ApiOperation("删除某个合班信息")
    @RequestMapping(value = "deleteJoinClass", method = RequestMethod.POST)
    public BaseVo deleteJoinClass(@RequestBody CourseGroupReqVo courseGroupReqVo){
        BaseVo baseVo = new BaseVo();
        Schedule schedule = scheduleService.selectById(courseGroupReqVo.getScheduleId());
        if(teacherClassService.selectHasSchedule(schedule.getSchoolId(),schedule.getTeam()) >0){
            baseVo.setMessage("已经部分排课,不能再删除");
            baseVo.setSuccess(false);
            return baseVo;
        }
        joinClassService.deleteCourseGroup(courseGroupReqVo.getCourseGroup());
        return baseVo;
    }

    @ApiOperation("不排课")
    @RequestMapping(value = "noSchedule", method = RequestMethod.POST)
    public BaseVo noSchedule(@RequestBody NoScheduleReqVo noScheduleReqVo){
        BaseVo baseVo = new BaseVo();
        Schedule schedule =scheduleService.selectById(noScheduleReqVo.getScheduleId());
        if(teacherClassService.selectHasSchedule(schedule.getSchoolId(),schedule.getTeam()) >0){
            baseVo.setMessage("已经部分排课,不能再设置");
            baseVo.setSuccess(false);
            return baseVo;
        }
        for(String msg : noScheduleReqVo.getList()){
            try {
                String[] arrayMsg = msg.split("-");
                ClassCourse classCourse = new ClassCourse();
                classCourse.setTeam(schedule.getTeam());
                classCourse.setSchoolId(schedule.getSchoolId());
                classCourse.setWeek(Integer.valueOf(arrayMsg[0]));
                classCourse.setCourseNumber(Integer.valueOf(arrayMsg[1]));
                classCourse.setSingleOrDouble(1);
                if(noScheduleReqVo.getLevel() == 1){
                    classCourse.setClassId(noScheduleReqVo.getClassId());
                }
                if(noScheduleReqVo.getLevel() == 2){
                    classCourse.setGrade(noScheduleReqVo.getGrade());
                }
                List<ClassCourse> list = classCourseService.selectClassCourseByClass(classCourse);
                for(ClassCourse temp : list){
                    temp.setCourseName("不排课");
                    classCourseService.updateByPrimaryKey(temp);
                }
            }catch (Exception e){
                System.out.println("不排课"+e.toString());
                baseVo.setSuccess(false);
                baseVo.setMessage("格式不对");
            }
        }
        return baseVo;
    }

    @ApiOperation("选择拟排科目类型,设置优先区间  提示")
    @RequestMapping(value = "secondChooseBefore", method = RequestMethod.POST)
    public BaseVo secondChooseBefore(@RequestBody ParallelClassReqVo parallelClassReqVo){
        BaseVo baseVo = new BaseVo();
        Schedule schedule = scheduleService.selectById(parallelClassReqVo.getScheduleId());
        StringBuffer stringBuffer = new StringBuffer();
        if(parallelClassReqVo.getLevel() == 1){
            ClassModel classModel = classModelService.selectByPrimaryKey(parallelClassReqVo.getClassId());
            stringBuffer.append("本次不排课设置,只涉及"+classModel.getClassName());
        }else if(parallelClassReqVo.getLevel() == 2){
            List<ClassModel> list = classModelService.selectBySchoolIdAndGrade(schedule.getSchoolId(),parallelClassReqVo.getGrade());
            stringBuffer.append("本次不排课设置,共涉及"+list.size()+"个班");
        }else {
            List<ClassModel> list = classModelService.selectBySchoolId(schedule.getSchoolId());
            stringBuffer.append("本次不排课设置,共涉及"+list.size()+"个班");
        }
        baseVo.setMessage(stringBuffer.toString());
        return baseVo;
    }

    @Transactional
    @ApiOperation("选择拟排科目类型,设置优先区间")
    @RequestMapping(value = "secondChoose", method = RequestMethod.POST)
    public BaseVo secondChoose(@RequestBody ParallelClassReqVo parallelClassReqVo) {
        BaseVo baseVo = new BaseVo();
        Schedule schedule = scheduleService.selectById(parallelClassReqVo.getScheduleId());
        //TODO  暂时只有单周
        boolean isDouble = false;
        //优先范围
        List<ClassCourse> limitList = new ArrayList<>();
        for(String msg : parallelClassReqVo.getIntervalList()){
            String[] arrayMsg = msg.split("-");
            ClassCourse classCourse = new ClassCourse();
            if(Integer.valueOf(arrayMsg[0]) > 5){
                classCourse.setSingleOrDouble(2);
                classCourse.setWeek(Integer.valueOf(arrayMsg[0])-5);
            }else {
                classCourse.setSingleOrDouble(1);
                classCourse.setWeek(Integer.valueOf(arrayMsg[0]));
            }
            classCourse.setCourseNumber(Integer.valueOf(arrayMsg[1]));
            limitList.add(classCourse);
        }

        //查询该课程类型下 所有的老师授课信息
        Course course = new Course();
        course.setSchoolId(schedule.getSchoolId());
        course.setCourseType(parallelClassReqVo.getCourseType());
        List<Course> courseList = courseService.selectByCourse(course);
        List<TeacherClass> teacherClasss = new ArrayList<>();
        int courseCount = 0 ;
        for(Course course1 : courseList){
            TeacherClass search = new TeacherClass();
            search.setSchoolId(schedule.getSchoolId());
            search.setCourseName(course1.getCourseName());
            search.setTeam(schedule.getTeam());
            if(parallelClassReqVo.getLevel() == 1){
                search.setClassId(parallelClassReqVo.getClassId());
            }
            if(parallelClassReqVo.getLevel() == 2){
                search.setGrade(parallelClassReqVo.getGrade());
            }
            List<TeacherClass> teacherClassList = teacherClassService.selectByCourseName(search);
            courseCount = courseCount + teacherClassList.get(0).getTimes();
            teacherClasss.addAll(teacherClassList);
        }
        if(courseCount > limitList.size()){
            baseVo.setSuccess(false);
            baseVo.setMessage("所要设置的公共课程数大于选择课表时段,请重新设置");
            return baseVo;
        }
        //联排的优先级
        List<Integer> joinList = new ArrayList<>();
        for(int i = 1 ; i <= 5 ; i++) {
            joinList.add(i);
        }
        Set<TeacherClass> teacherClassSet = new HashSet<>(teacherClasss);
        for (TeacherClass temp : teacherClassSet) {
            TeacherCourse teacherCourse = new TeacherCourse();
            teacherCourse.setSchoolId(schedule.getSchoolId());
            teacherCourse.setTeacherName(temp.getTeacherName());
            teacherCourse.setTeam(schedule.getTeam());
            //插入教师排课表
            if(teacherCourseService.isCreateCourse(teacherCourse) == 0){
                //插入教师排课表
                insertTeacherCourse(isDouble, teacherCourse);
            }
            TeacherClass searchTeacher = new TeacherClass();
            searchTeacher.setTeacherName(temp.getTeacherName());
            searchTeacher.setSchoolId(temp.getSchoolId());
            searchTeacher.setClassId(temp.getClassId());
            searchTeacher.setTeam(temp.getTeam());
            TeacherClass teacherClass = teacherClassService.selectByTeacher(searchTeacher);
            if(teacherClass.getStatus() == 1){
                //已经排课不再排课
            }else {
                ClassCourse classCourse = new ClassCourse();
                classCourse.setClassId(temp.getClassId());
                classCourse.setTeam(schedule.getTeam());
                if(isDouble){
//                    //双周排课 先排第一周
//                    int times = teacherClass.getTimes();
//                    int joinTimes = teacherClass.getJoinTimes();
//                    classCourse.setSingleOrDouble(1);
//                    teacherClass.setJoinTimes(times/2);
//                    teacherClass.setJoinTimes(joinTimes/2);
//                    List<ClassCourse> classCourses = classCourseService.selectByClassIdAndSingleOrDouble(classCourse);
//                    initWeekCourse(joinList,teacherClass,teacherCourse,classCourses,limitList,0);
//                    //第二周
//                    classCourse.setSingleOrDouble(1);
//                    teacherClass.setJoinTimes(times/2+1);
//                    teacherClass.setJoinTimes(joinTimes/2+1);
//                    classCourses = classCourseService.selectByClassIdAndSingleOrDouble(classCourse);
//                    initWeekCourse(joinList,teacherClass,teacherCourse,classCourses,limitList,0);
                }else {
                    classCourse.setSingleOrDouble(1);
                    List<ClassCourse> classCourses = classCourseService.selectByClassIdAndSingleOrDouble(classCourse);
                    initWeekCourse(joinList,teacherClass,teacherCourse,classCourses,limitList,0);
                    //排课结束,更新
                    //如果是合班的话,需要更新多个teacherClass
                    teacherClassService.updateSchedule(teacherClass.gettClassId());
                    JoinClass joinClass = new JoinClass();
                    joinClass.setSchoolId(schedule.getSchoolId());
                    joinClass.setTeam(schedule.getTeam());
                    joinClass.setCourseId(courseService.selectBySchoolIdAndCourseName(schedule.getSchoolId(),teacherClass.getCourseName()).getCourseId());
                    joinClass.setClassId(classCourse.getClassId());
                    List<JoinClass> joinClasses = joinClassService.selectByCourse(joinClass);
                    if(joinClasses != null && joinClasses.size() > 0){
                        List<JoinClass> resultList = joinClassService.selectByCourseGroup(joinClasses.get(0).getCourseGroup());
                        for(JoinClass joinClass1 :resultList){
                                TeacherClass searchTeacherClass = new TeacherClass();
                                searchTeacherClass.setSchoolId(schedule.getSchoolId());
                                searchTeacherClass.setTeam(schedule.getTeam());
                                searchTeacherClass.setCourseName(teacherClass.getCourseName());
                                searchTeacherClass.setClassId(joinClass1.getClassId());
                                TeacherClass resultTeacherClass = teacherClassService.selectByCourseAndClass(searchTeacherClass);
                                teacherClassService.updateSchedule(resultTeacherClass.gettClassId());
                        }
                    }
                }
            }
        }
        return baseVo;
    }

    @ApiOperation("排课撤回")
    @RequestMapping(value = "recall", method = RequestMethod.POST)
    public BaseVo recall(@RequestBody RecallReqVo recallReqVo){
        BaseVo baseVo = new BaseVo();
        Schedule schedule = scheduleService.selectById(recallReqVo.getScheduleId());
        switch (recallReqVo.getNumber()){
            case 1:
                //不排课撤回
                ClassCourse classCourse1 = new ClassCourse();
                classCourse1.setSchoolId(schedule.getSchoolId());
                classCourse1.setCourseName("不排课");
                classCourseService.recallClassCourse(classCourse1);
                break;
            case 2:
                //公共课不排课
                recall(3,schedule);
                break;
            case 3:
                //主课
                recall(1,schedule);
                break;
            case 4:
                recall(2,schedule);
                break;
        }
        return baseVo;
    }

    private void recall(int courseType , Schedule schedule){
        Course course = new Course();
        course.setSchoolId(schedule.getSchoolId());
        course.setCourseType(courseType);
        List<Course> list = courseService.selectByCourse(course);
        for(Course temp : list){
            ClassCourse classCourse2 = new ClassCourse();
            classCourse2.setSchoolId(schedule.getSchoolId());
            classCourse2.setCourseName(temp.getCourseName());
            classCourseService.recallClassCourse(classCourse2);
            TeacherClass teacherClass = new TeacherClass();
            teacherClass.setSchoolId(schedule.getSchoolId());
            teacherClass.setTeam(schedule.getTeam());
            teacherClass.setCourseName(temp.getCourseName());
            List<TeacherClass> teacherClasses = teacherClassService.selectByCourseName(teacherClass);
            for(TeacherClass teacherClass1 : teacherClasses){
                TeacherCourse teacherCourse2 = new TeacherCourse();
                teacherCourse2.setSchoolId(schedule.getSchoolId());
                teacherCourse2.setTeam(schedule.getTeam());
                teacherCourse2.setTeacherName(teacherClass1.getTeacherName());
                teacherCourse2.setCourseName(temp.getCourseName());
                teacherCourseService.recallTeacherCourse(teacherCourse2);
                teacherClassService.recallTeacherClass(teacherClass1.gettClassId());
            }

        }
    }

    //设置当天课的信息
    private List<ClassCourse> setClassCourse(boolean isDouble , int i , FirstReqVo firstReqVo){
        List<ClassCourse> classCourses = new ArrayList<>();
        Schedule schedule = scheduleService.selectById(firstReqVo.getScheduleId());
        Date date = new Date();
        for(int j = 1 ; j <= firstReqVo.getDayNumber() ; j++){
            ClassCourse classCourse = new ClassCourse();
            classCourse.setSingleOrDouble(isDouble ? 2 : 1);
            classCourse.setSchoolId(schedule.getSchoolId());
            classCourse.setWeek(i);
            classCourse.setCourseNumber(j);
            classCourse.setCreateTime(date);
            classCourses.add(classCourse);
            classCourse.setTeam(schedule.getTeam());
        }
        return classCourses;
    }

    private void initWeekCourse(List<Integer> joinList ,TeacherClass teacherClass , TeacherCourse teacherCourse ,
                                List<ClassCourse> list , List<ClassCourse> limitList ,int functionTimes){
       List<Integer> sort = new ArrayList<>();
        String team = teacherClass.getTeam();
        int singleOrDouble = list.get(0).getSingleOrDouble();
        for(ClassCourse classCourse : limitList){
            if(!sort.contains(classCourse.getCourseNumber())){
                sort.add(classCourse.getCourseNumber());
            }
        }
        int times = 0 ;  //已经排课数
        //先排联课
        int joinTimes = 0 ;  //已经排联课数
        for(int w = 0 ; w <= 4 ; w++) {
            int week = joinList.get(w);
            if(joinTimes == teacherClass.getJoinTimes()){
                break;
            }
            for (int i = 0; i < sort.size(); i++) {
                int courseNumber = sort.get(i);
                ClassCourse classCourse = getClassCourse(list, week, courseNumber);
                if(!sort.contains(courseNumber+1)){
                    continue;
                }
                ClassCourse classCourseNext =getClassCourse(list, week, courseNumber+1);
                if (StringUtils.isBlank(classCourse.getCourseName()) && StringUtils.isBlank(classCourseNext.getCourseName())) {
                    Course course = courseService.selectBySchoolIdAndCourseName(teacherClass.getSchoolId(),teacherCourse.getCourseName());
                    classCourse.setCourseOpenId(course.getCourseId());
                    classCourse.setCourseName(teacherClass.getCourseName());
                    classCourseNext.setCourseOpenId(course.getCourseId());
                    classCourseNext.setCourseName(teacherClass.getCourseName());
                    TeacherCourse searchTeacherCourse = new TeacherCourse();
                    searchTeacherCourse.setTeam(team);
                    searchTeacherCourse.setSchoolId(teacherCourse.getSchoolId());
                    searchTeacherCourse.setGrade(teacherCourse.getGrade());
                    searchTeacherCourse.setTeacherName(teacherCourse.getTeacherName());
                    searchTeacherCourse.setSingleOrDouble(singleOrDouble);
                    searchTeacherCourse.setWeek(week);
                    searchTeacherCourse.setCourseName(teacherCourse.getCourseName());
                    //查询当天老师的课是否已经大于等于2  防止老师一天课程太多
                    int dayCourse = teacherCourseService.selectTeacherDayCourseNumber(searchTeacherCourse);
                    if(dayCourse >= 2){
                        break;
                    }
                    searchTeacherCourse.setCourseNumber(courseNumber);
                    TeacherCourse teacherFirst = teacherCourseService.selectTeacherCourse(searchTeacherCourse);
                    searchTeacherCourse.setCourseNumber(courseNumber+1);
                    TeacherCourse teacherSecond = teacherCourseService.selectTeacherCourse(searchTeacherCourse);
                    if (StringUtils.isBlank(teacherFirst.getCourseName()) && StringUtils.isBlank(teacherSecond.getCourseName())) {
                        classCourseService.updateByPrimaryKey(classCourse);
                        classCourseService.updateByPrimaryKey(classCourseNext);
                        teacherFirst.setCourseName(teacherCourse.getCourseName());
                        teacherFirst.setClassId(classCourse.getClassId()+"");
                        teacherSecond.setCourseName(teacherCourse.getCourseName());
                        teacherSecond.setClassId(classCourse.getClassId()+"");
                        teacherCourseService.updateTeacherCourse(teacherFirst);
                        teacherCourseService.updateTeacherCourse(teacherSecond);
                        times = times + 2;
                        reSort(sort,courseNumber);
                        reSort(sort,courseNumber+1);
                        reSort(joinList,week);
                        joinTimes++ ;
                        break;
                    } else {
                        continue;
                    }
                }
            }
        }
        //单节课
        int before = 0 ;
        for(int week = 1 ; week <= 5 ; week++){
            if(times == teacherClass.getTimes()){
                break;
            }
            if(before > 0){
                sort = reSort(sort,before);
            }
            for(int i = 0 ; i < sort.size() ; i++){
                int courseNumber = sort.get(i);
                ClassCourse classCourse = getClassCourse(list,week,courseNumber);
                boolean flag = false ;
                //去判断 查出的classCourse 是否在limitList
                for(ClassCourse temp : limitList){
                    if(temp.getWeek() == classCourse.getWeek() &&
                            temp.getCourseNumber() == classCourse.getCourseNumber()){
                        flag = true ;
                        break;
                    }
                }
                if(flag){
                    if(StringUtils.isBlank(classCourse.getCourseName())){
                        Course course = courseService.selectBySchoolIdAndCourseName(teacherClass.getSchoolId(),teacherClass.getCourseName());
                        classCourse.setCourseOpenId(course.getCourseId());
                        classCourse.setCourseName(teacherClass.getCourseName());
                        //判断当天是否已经排该课程
                        if(classCourseService.selectCourseByClassIdAndWeek(classCourse) > 1){
                            break;
                        }
                        TeacherCourse searchTeacherCourse = new TeacherCourse();
                        searchTeacherCourse.setTeam(team);
                        searchTeacherCourse.setSchoolId(teacherCourse.getSchoolId());
                        searchTeacherCourse.setGrade(teacherCourse.getGrade());
                        searchTeacherCourse.setTeacherName(teacherCourse.getTeacherName());
                        searchTeacherCourse.setSingleOrDouble(singleOrDouble);
                        searchTeacherCourse.setWeek(week);
                        searchTeacherCourse.setCourseNumber(courseNumber);
                        searchTeacherCourse.setCourseName(teacherClass.getCourseName());
                        TeacherCourse result = teacherCourseService.selectTeacherCourse(searchTeacherCourse);
                        //老师当天课程不能多于2
                        if(teacherCourseService.selectTeacherDayCourseNumber(searchTeacherCourse) >= 2){
                            break;
                        }
                        //合课 多做一层判断  另一个班级这节课也为空
                        JoinClass joinClass = new JoinClass();
                        joinClass.setSchoolId(classCourse.getSchoolId());
                        joinClass.setTeam(classCourse.getTeam());
                        joinClass.setCourseId(classCourse.getCourseOpenId());
                        joinClass.setClassId(classCourse.getClassId());
                        List<JoinClass> joinClasses = joinClassService.selectByCourse(joinClass);
                        if(joinClasses != null && joinClasses.size() > 0){
                            //说明是合班的课程
                            boolean isClash = false ;
                            List<ClassCourse> joinClassList = new ArrayList<>();
                            List<JoinClass> resultList = joinClassService.selectByCourseGroup(joinClasses.get(0).getCourseGroup());
                            for(JoinClass temp : resultList){
                                ClassCourse joinClassCourse = new ClassCourse();
                                joinClassCourse.setTeam(classCourse.getTeam());
                                joinClassCourse.setClassId(temp.getClassId());
                                joinClassCourse.setWeek(classCourse.getWeek());
                                joinClassCourse.setCourseNumber(classCourse.getCourseNumber());
                                joinClassCourse.setSingleOrDouble(classCourse.getSingleOrDouble());
                                ClassCourse joinResultClassCourse = classCourseService.selectClassCourse(joinClassCourse);
                                joinClassList.add(joinResultClassCourse);
                                if(StringUtils.isNotBlank(joinResultClassCourse.getCourseName())){
                                    isClash = true ;
                                    break;
                                }
                            }
                            if(isClash){
                                //合班的班级有 该节次的课 已经有老师上了
                                continue;
                            }else {
                                String classIdString = "";
                                for(ClassCourse temp : joinClassList){
                                    classIdString = course.getCourseId() + "," ;
                                    temp.setCourseOpenId(course.getCourseId());
                                    temp.setCourseName(teacherClass.getCourseName());
                                    classCourseService.updateByPrimaryKey(temp);
                                }
                                result.setGrade(classCourse.getGrade());
                                result.setClassId(classIdString);
                                result.setCourseName(classCourse.getCourseName());
                                teacherCourseService.updateTeacherCourse(result);
                                times++;
                                before = courseNumber;
                                break;
                            }
                        }else {
                            //普通课程
                            if(StringUtils.isBlank(result.getCourseName())){
                                classCourseService.updateByPrimaryKey(classCourse);
                                result.setGrade(classCourse.getGrade());
                                result.setClassId(classCourse.getClassId()+"");
                                result.setCourseName(classCourse.getCourseName());
                                teacherCourseService.updateTeacherCourse(result);
                                times++;
                                before = courseNumber;
                                break;
                            }else {
                                continue;
                            }
                        }
                    }
                }
            }
        }
        if(functionTimes > 1){
            //递归次数限制,防止无限循环,内存溢出,手动优化课程
            optimizeCourse(teacherClass);
        }else{
            if(times < teacherClass.getTimes()){
                //优先时段中课程数 不够
                teacherClass.setTimes(teacherClass.getTimes()-times);
                teacherClass.setJoinTimes(teacherClass.getJoinTimes()-joinTimes);
                //放大范围
                limitList = new ArrayList<>();
                int maxCourseNumber =classCourseService.selectMaxCourseNumber(teacherClass.getSchoolId(),team);
                for(int i = 1 ; i<= 5 ; i++){
                    for(int j = 1 ; j <=maxCourseNumber ; j++) {
                        ClassCourse temp = new ClassCourse();
                        temp.setWeek(i);
                        temp.setCourseNumber(j);
                        limitList.add(temp);
                    }
                }
                functionTimes ++ ;
                initWeekCourse(joinList,teacherClass,teacherCourse,list,limitList,functionTimes);
            }
        }
    }

    //课程冲突 ,调优
    private void optimizeCourse(TeacherClass teacherClass){
        int times = teacherClass.getTimes();
        while (times > 0){
            boolean flag = false ;
            List<ClassCourse> noClassList = classCourseService.selectNoCourse(teacherClass.getClassId(),teacherClass.getTeam());
            for(ClassCourse classCourse : noClassList){
                for(int i = -2 ; i <= 2 ; i++){
                    int weekChange = classCourse.getWeek()+i ;
                    if(weekChange > 5){
                        weekChange = weekChange - 5;
                    }
                    if(weekChange < 1){
                        weekChange = weekChange + 5;
                    }
                    List<ClassCourse> list = classCourseService.selectWeekCourse(classCourse.getClassId(),weekChange,classCourse.getSingleOrDouble(),teacherClass.getCourseName(),teacherClass.getTeam());
                    //查询当天是否已经有该节课,扩大了
                    if(list.size() > 1){
                        continue;
                    }
                    for(int j = -1 ; j<=1 ; j++){
                        int  courseNumberChange = classCourse.getCourseNumber() + j ;
                        if(courseNumberChange > classCourseService.selectMaxCourseNumber(teacherClass.getSchoolId(),teacherClass.getTeam())){
                            continue;
                        }
                        if(courseNumberChange < 1){
                            continue;
                        }
                        if(changeClass(classCourse,teacherClass,weekChange,courseNumberChange)){
                            flag = true;
                            break;
                        }
                    }
                    if(flag){
                        break;
                    }
                }
                if(flag){
                    break;
                }
            }
            if(flag){
                times-- ;
            }
        }
    }

    private boolean changeClass(ClassCourse classCourse , TeacherClass teacherClass , int weekChange ,int courseNumberChange){
        String team = classCourse.getTeam();
        int week = classCourse.getWeek();
        int courseNumber = classCourse.getCourseNumber();
        ClassCourse searchClass = new ClassCourse();
        searchClass.setSingleOrDouble(classCourse.getSingleOrDouble());
        searchClass.setClassId(classCourse.getClassId());
        searchClass.setWeek(weekChange);
        searchClass.setCourseNumber(courseNumberChange);
        searchClass.setTeam(team);
        ClassCourse nextClass = classCourseService.selectClassCourse(searchClass);
        if(StringUtils.isBlank(nextClass.getCourseName())){
            //替换的课 本来就没课
            String className =teacherClass.getCourseName();
            String nextNameClass = nextClass.getCourseName();
            classCourse.setCourseOpenId(courseService.selectBySchoolIdAndCourseName(classCourse.getSchoolId(),nextNameClass).getCourseId());
            classCourse.setCourseName(nextNameClass);
            nextClass.setCourseOpenId(courseService.selectBySchoolIdAndCourseName(classCourse.getSchoolId(),className).getCourseId());
            nextClass.setCourseName(className);
            classCourseService.updateByPrimaryKey(classCourse);
            classCourseService.updateByPrimaryKey(nextClass);

            TeacherCourse teacherCourse = new TeacherCourse();
            teacherCourse.setTeam(team);
            teacherCourse.setSchoolId(classCourse.getSchoolId());
            teacherCourse.setSingleOrDouble(classCourse.getSingleOrDouble());
            teacherCourse.setGrade(classCourse.getGrade());
            teacherCourse.setWeek(weekChange);
            teacherCourse.setCourseNumber(courseNumberChange);
            teacherCourse.setCourseName(className);
            teacherCourse.setTeacherName(teacherClass.getTeacherName());
            teacherCourse.setClassId(classCourse.getClassId()+"");
            teacherCourseService.updateTeacherCourse(teacherCourse);
            return true ;
        }else {
            //增加判断  不排课的课程不能替换 合班的课程不能替换  联课的可能不能替换
            JoinClass joinClass = new JoinClass();
            joinClass.setSchoolId(nextClass.getSchoolId());
            joinClass.setTeam(nextClass.getTeam());
            joinClass.setCourseId(nextClass.getCourseId());
            joinClass.setClassId(nextClass.getClassId());
            List<JoinClass> joinClasses = joinClassService.selectByCourse(joinClass);
            boolean joinClassFlag = joinClasses != null && joinClasses.size() > 0 ;
            TeacherClass searchTeacherClass = new TeacherClass();
            searchTeacherClass.setSchoolId(nextClass.getSchoolId());
            searchTeacherClass.setTeam(nextClass.getTeam());
            searchTeacherClass.setCourseName(nextClass.getCourseName());
            List<TeacherClass> teacherClasses = teacherClassService.selectByCourseName(searchTeacherClass);
            boolean joinTimesFlag = teacherClasses.get(0).getJoinTimes()>0?true:false;
            if(nextClass.getCourseName().equals("不排课") || joinClassFlag || joinTimesFlag){
                //这些课 不能替换
            }else {
                TeacherClass replaceClassTeacher = new TeacherClass();
                replaceClassTeacher.setSchoolId(classCourse.getSchoolId());
                replaceClassTeacher.setGrade(classCourse.getGrade());
                replaceClassTeacher.setClassId(classCourse.getClassId());
                replaceClassTeacher.setCourseName(nextClass.getCourseName());
                replaceClassTeacher.setTeam(team);
                String nextTeacher = teacherClassService.selectByCourseAndClass(replaceClassTeacher).getTeacherName();

                //原课的老师 下一节课是否有课 ;下一节课的老师 上一节是否有课
                TeacherCourse searchTeacher = new TeacherCourse();
                searchTeacher.setSchoolId(classCourse.getSchoolId());
                searchTeacher.setSingleOrDouble(classCourse.getSingleOrDouble());
                searchTeacher.setTeacherName(teacherClass.getTeacherName());
                searchTeacher.setWeek(weekChange);
                searchTeacher.setCourseNumber(courseNumberChange);
                searchTeacher.setTeam(team);
                TeacherCourse teacherCourse = teacherCourseService.selectTeacherCourse(searchTeacher);

                TeacherCourse nextTeacherCourseSearch = new TeacherCourse();
                nextTeacherCourseSearch.setSchoolId(classCourse.getSchoolId());
                nextTeacherCourseSearch.setSingleOrDouble(classCourse.getSingleOrDouble());
                nextTeacherCourseSearch.setTeacherName(nextTeacher);
                nextTeacherCourseSearch.setWeek(week);
                nextTeacherCourseSearch.setCourseNumber(courseNumber);
                nextTeacherCourseSearch.setTeam(team);
                TeacherCourse nextTeacherCourse = teacherCourseService.selectTeacherCourse(nextTeacherCourseSearch);
                if(StringUtils.isBlank(nextTeacherCourse.getCourseName()) && StringUtils.isBlank(teacherCourse.getCourseName())){
                    //则上下替换课程  班级课程上下替换,老师课程交换
                    String className =teacherClass.getCourseName();
                    String nextClassName = nextClass.getCourseName();
                    classCourse.setCourseName(nextClassName);
                    nextClass.setCourseName(className);
                    classCourseService.updateByPrimaryKey(classCourse);
                    classCourseService.updateByPrimaryKey(nextClass);

                    teacherCourse.setGrade(teacherClass.getGrade());
                    teacherCourse.setCourseName(className);
                    teacherCourse.setClassId(teacherClass.getClassId()+"");
                    teacherCourseService.updateTeacherCourse(teacherCourse);

                    nextTeacherCourse.setGrade(nextClass.getGrade());
                    nextTeacherCourse.setCourseName(nextClassName);
                    nextTeacherCourse.setClassId(nextClass.getClassId()+"");
                    teacherCourseService.updateTeacherCourse(nextTeacherCourse);

                    nextTeacherCourse.setWeek(weekChange);
                    nextTeacherCourse.setCourseNumber(courseNumberChange);
                    nextTeacherCourse.setCourseName(null);
                    nextTeacherCourse.setClassId(null);
                    teacherCourseService.updateTeacherCourse(nextTeacherCourse);
                    return true ;
                }
            }
        }
        return  false ;
    }

    //所谓权重  节次优先级
    private List<Integer> reSort(List<Integer> list , int number){
        int index = -1 ;
        for(Integer i = 0 ; i < list.size() ;i++){
            if(list.get(i) == number){
                index = i ;
                break ;
            }
        }
        list.remove(index);
        list.add(number);
        return list ;
    }

    //查所在课表中 返回某天某节课
    private ClassCourse getClassCourse(List<ClassCourse> list  , int week , int courseNumber){
        ClassCourse result = null ;
        for(ClassCourse classCourse : list){
            if(classCourse.getWeek() == week && classCourse.getCourseNumber() == courseNumber){
                result = classCourse ;
                break;
            }
        }
        return result;
    }

    //生成教师排课表
    private void insertTeacherCourse(boolean isDouble , TeacherCourse teacherCourse){
        List<TeacherCourse> list = new ArrayList<>();
        //单周课表必生成
        list.addAll(createWeekTeacherCourse(teacherCourse,false));
        if(isDouble){
            list.addAll(createWeekTeacherCourse(teacherCourse,true));
        }
        teacherCourseService.insertBatch(list);
    }

    // 创建教师 周课表 单周isDouble false 双周isDouble true
    private List<TeacherCourse> createWeekTeacherCourse(TeacherCourse teacherCourse , boolean isDouble){
        int singleOrDouble = 1 ;
        if(isDouble){
            singleOrDouble = 2;
        }
        Date date =new Date();
        List<TeacherCourse> list = new ArrayList<>();
        int courseNumMax = classCourseService.selectMaxCourseNumber(teacherCourse.getSchoolId(),teacherCourse.getTeam());
        for (int i = 1; i <= 7; i++) {
            for(int j = 1 ; j <= courseNumMax ; j++){
                TeacherCourse temp = new TeacherCourse() ;
                temp.setTeam(teacherCourse.getTeam());
                temp.setSchoolId(teacherCourse.getSchoolId());
                temp.setClassId(teacherCourse.getClassId());
                temp.setGrade(teacherCourse.getGrade());
                temp.setTeacherName(teacherCourse.getTeacherName());
                temp.setWeek(i);
                temp.setCourseNumber(j);
                temp.setCreateTime(date);
                temp.setSingleOrDouble(singleOrDouble);
                list.add(temp);
            }
        }
        return list ;
    }

}