package yangtz.cs.liu.campus.service.impl.curricula;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import yangtz.cs.liu.campus.domain.curricula.SchoolDivisionClasses;
import yangtz.cs.liu.campus.domain.curricula.SchoolDivisionStudent;
import yangtz.cs.liu.campus.mapper.curricula.DivisionClassesMapper;
import yangtz.cs.liu.campus.mapper.curricula.DivisionStudentMapper;
import yangtz.cs.liu.campus.service.curricula.ICurriculaStudentService;
import yangtz.cs.liu.campus.service.curricula.IDivisionClassesService;
import yangtz.cs.liu.campus.vo.curricula.CurriculaStudentVo;
import yangtz.cs.liu.campus.vo.curricula.SchoolDivisionClassesVo;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class DivisionClassesServiceImpl extends ServiceImpl<DivisionClassesMapper, SchoolDivisionClasses> implements IDivisionClassesService {

    @Autowired
    private DivisionClassesMapper divisionClassesMapper;
    @Autowired
    private ICurriculaStudentService curriculaStudentService;
    @Autowired
    private DivisionStudentMapper divisionStudentMapper;

    /**
     * 首次分班规则
     * @param list
     * @return
     */
    @Override
    @Transactional
    public int insertDivisionClasses(List<SchoolDivisionClassesVo> list) {
        int row = 0;
        for (SchoolDivisionClassesVo classesVo : list) {
            if (StringUtils.isEmpty(classesVo.getDivisionClassesRule())){
                throw new ServiceException("请选择分班规则");
            }
            if (null == classesVo.getClassesNumber() || null == classesVo.getPeopleNumber()){
                throw new ServiceException("班级数量或每班人数不能为空");
            }
            if (classesVo.getClassesNumber() == 0 || classesVo.getPeopleNumber() == 0){
                throw new ServiceException("班级数量或每班人数不能为0");
            }
            if (classesVo.getCoursePeopleNumber() < classesVo.getClassesNumber()){
                throw new ServiceException("输入的班级数量大于该课程总人数");
            }
            if (classesVo.getClassesNumber() * classesVo.getPeopleNumber() > classesVo.getCoursePeopleNumber() || classesVo.getClassesNumber() * classesVo.getPeopleNumber() < classesVo.getCoursePeopleNumber()){
                throw new ServiceException("输入的班级数量和每班人数不符");
            }
            if (classesVo.getPeopleNumber() > classesVo.getCoursePeopleNumber()){
                throw new ServiceException("输入的每班人数大于该课程总人数");
            }
            //创建班级
            //输入的班级数量
            int classesNumber = classesVo.getClassesNumber();
            String className = "";
            switch (classesVo.getCourse()){
                case "1" :
                    className = "物政化";
                    break;
                case "2":
                    className = "物政生";
                    break;
                case "3":
                    className = "物政地";
                    break;
                case "4":
                    className = "物政历";
                    break;
                case "5":
                    className = "物历化";
                    break;
                case "6":
                    className = "物历生";
                    break;
                case "7":
                    className = "物地化";
                    break;
                case "8":
                    className = "物地生";
                    break;
                case "9":
                    className = "物化生";
                    break;
                case "10":
                    className = "物历地";
                    break;
                case "11":
                    className = "化政地";
                    break;
                case "12":
                    className = "化政历";
                    break;
                case "13":
                    className = "化政生";
                    break;
                case "14":
                    className = "化历地";
                    break;
                case "15":
                    className = "化历生";
                    break;
                case "16":
                    className = "化地生";
                    break;
                case "17":
                    className = "生政地";
                    break;
                case "18":
                    className = "生历地";
                    break;
                case "19":
                    className = "生政历";
                    break;
                case "20":
                    className = "政历地";
                    break;
            }
            //新增班级
            SchoolDivisionClasses schoolDivisionClasses = new SchoolDivisionClasses();
            schoolDivisionClasses.setCurriculaId(classesVo.getCurriculaId());
            schoolDivisionClasses.setCourse(classesVo.getCourse());
            schoolDivisionClasses.setDivisionClassesRule(classesVo.getDivisionClassesRule());
            schoolDivisionClasses.setDivisionClassesFrequency(classesVo.getDivisionClassesFrequency());
            schoolDivisionClasses.setCreateBy(SecurityUtils.getLoginUser().getUser().getUserName());
            schoolDivisionClasses.setCreateTime(DateUtils.getNowDate());
            for (int i = 1; i <= classesNumber; i++) {
                schoolDivisionClasses.setDivisionClassesName(className + i + "班");
                row += divisionClassesMapper.insert(schoolDivisionClasses);
            }

            //查询首次分班对应的班级
            LambdaQueryWrapper<SchoolDivisionClasses> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SchoolDivisionClasses::getCurriculaId,classesVo.getCurriculaId())
                    .eq(SchoolDivisionClasses::getCourse,classesVo.getCourse())
                    .eq(SchoolDivisionClasses::getDivisionClassesFrequency,"1")
                    .eq(SchoolDivisionClasses::getDelFlag,"0")
                    .orderByAsc(SchoolDivisionClasses::getDivisionClassesName);
            List<SchoolDivisionClasses> divisionClasses = divisionClassesMapper.selectList(wrapper);

            CurriculaStudentVo curriculaStudentVo = new CurriculaStudentVo();
            curriculaStudentVo.setCurriculaId(classesVo.getCurriculaId());
            curriculaStudentVo.setSelectedCourse(classesVo.getCourse());
            curriculaStudentVo.setCourseType("2");
            List<CurriculaStudentVo> curriculaStudentVoList = curriculaStudentService.selectCurriculaStudentListXj(curriculaStudentVo);

            //判断此次分班是平行分班还是分层分班
            if (classesVo.getDivisionClassesRule().equals("1")){
                //平行分班
                //根据成绩进行排名 从高到低
                List<CurriculaStudentVo> curriculaStudentVos = curriculaStudentVoList.stream().sorted(Comparator.comparing(CurriculaStudentVo::getCourseScore).reversed()).collect(Collectors.toList());

                //生成不重复随机数
                Random random = new Random();
                List<Integer> list1 = new ArrayList<>();
                while (true){
                    int index = random.nextInt(divisionClasses.size());
                    if (!list1.contains(index)){
                        list1.add(index);
                    }
                    if (list1.size() == divisionClasses.size()){
                        break;
                    }
                }
                List<CurriculaStudentVo> studentVoList = new ArrayList<>();
                //新增成绩好的学生与分班班级关系
                for (int i = 0; i < divisionClasses.size(); i++) {
                    SchoolDivisionStudent schoolDivisionStudent = new SchoolDivisionStudent();
                    schoolDivisionStudent.setDivisionClassesId(divisionClasses.get(list1.get(i)).getId());
                    CurriculaStudentVo curriculaStudentVo1 = curriculaStudentVos.get(i);
                    schoolDivisionStudent.setStudentId(curriculaStudentVo1.getStudentId());
                    schoolDivisionStudent.setFbcs("1");
                    divisionStudentMapper.insert(schoolDivisionStudent);
                    studentVoList.add(curriculaStudentVo1);
                }
                for (CurriculaStudentVo studentVo : studentVoList) {
                    curriculaStudentVos.remove(studentVo);
                }

                //随机新增剩余同学与分班班级关系
                for (int i = 0; i < divisionClasses.size(); i++) {

                    //随机生成每班人数减1个随机数
                    Random random1 = new Random();
                    List<Integer> people = new ArrayList<>();
                    if (classesVo.getPeopleNumber() - 1 != 0){
                        while (true){
                            int index = random1.nextInt(classesVo.getPeopleNumber() - 1);
                            if (!people.contains(index)){
                                people.add(index);
                            }
                            if (people.size() == classesVo.getPeopleNumber() - 1){
                                break;
                            }
                        }
                    }

                    for (int j = 0; j < classesVo.getPeopleNumber() - 1; j++) {
                        SchoolDivisionStudent schoolDivisionStudent = new SchoolDivisionStudent();
                        schoolDivisionStudent.setDivisionClassesId(divisionClasses.get(i).getId());
                        CurriculaStudentVo curriculaStudentVo1 = curriculaStudentVos.get(people.get(j));
                        schoolDivisionStudent.setStudentId(curriculaStudentVo1.getStudentId());
                        schoolDivisionStudent.setFbcs("1");
                        divisionStudentMapper.insert(schoolDivisionStudent);
                    }
                }
            }else {
                //分层分班
                //根据成绩进行排名 从高到低
                List<CurriculaStudentVo> curriculaStudentVos = curriculaStudentVoList.stream().sorted(Comparator.comparing(CurriculaStudentVo::getCourseScore).reversed()).collect(Collectors.toList());

                int index = 0;

                for (SchoolDivisionClasses schoolDivisionClasses1 : divisionClasses) {
                    SchoolDivisionStudent schoolDivisionStudent = new SchoolDivisionStudent();
                    //分班班级id
                    Long id = schoolDivisionClasses1.getId();
                    schoolDivisionStudent.setDivisionClassesId(id);
                    schoolDivisionStudent.setFbcs("1");

                    List<CurriculaStudentVo> studentVoList = new ArrayList<>();

                    //判断学生人数能不能整除输入的每班人数
                    if (curriculaStudentVos.size() % classesVo.getPeopleNumber() == 0){
                        for (int i = 0; i < classesVo.getPeopleNumber(); i++) {
                            CurriculaStudentVo studentVo = curriculaStudentVos.get(i);
                            schoolDivisionStudent.setStudentId(studentVo.getStudentId());
                            divisionStudentMapper.insert(schoolDivisionStudent);
                            studentVoList.add(studentVo);
                        }
                        for (CurriculaStudentVo studentVo : studentVoList) {
                            curriculaStudentVos.remove(studentVo);
                        }
                        studentVoList.clear();
                    }else {
                        int index1 = curriculaStudentVos.size() / classesVo.getPeopleNumber();
                        if (index == index1){
                            for (int i = 0; i < curriculaStudentVos.size() % classesVo.getPeopleNumber(); i++) {
                                CurriculaStudentVo studentVo = curriculaStudentVos.get(i);
                                schoolDivisionStudent.setStudentId(studentVo.getStudentId());
                                divisionStudentMapper.insert(schoolDivisionStudent);
                                studentVoList.add(studentVo);
                            }
                            for (CurriculaStudentVo studentVo : studentVoList) {
                                curriculaStudentVos.remove(studentVo);
                            }
                            studentVoList.clear();
                        }else {
                            for (int j = 0; j < classesVo.getPeopleNumber(); j++) {
                                CurriculaStudentVo studentVo = curriculaStudentVos.get(j);
                                schoolDivisionStudent.setStudentId(studentVo.getStudentId());
                                divisionStudentMapper.insert(schoolDivisionStudent);
                                studentVoList.add(studentVo);
                            }
                            for (CurriculaStudentVo studentVo : studentVoList) {
                                curriculaStudentVos.remove(studentVo);
                            }
                            studentVoList.clear();
                            index ++;
                        }
                    }
                }
            }
        }
        return row;
    }

    /**
     * 获取每种课程选择人数
     * @return
     */
    @Override
    public List<Map<String, String>> getNumber(Long curriculaId) {
        return divisionClassesMapper.getNumber(curriculaId);
    }

    /**
     * 二次分班规则
     * @param list
     * @return
     */
    @Override
    public int insertDivisionClassesEc(List<SchoolDivisionClassesVo> list) {
        int row = 0;
        for (SchoolDivisionClassesVo classesVo : list) {
            if (StringUtils.isEmpty(classesVo.getDivisionClassesRule())){
                throw new ServiceException("请选择分班规则");
            }
            if (null == classesVo.getClassesNumber() || null == classesVo.getPeopleNumber()){
                throw new ServiceException("班级数量或每班人数不能为空");
            }
            if (classesVo.getClassesNumber() == 0 || classesVo.getPeopleNumber() == 0){
                throw new ServiceException("班级数量或每班人数不能为0");
            }
            if (classesVo.getCoursePeopleNumber() < classesVo.getClassesNumber()){
                throw new ServiceException("输入的班级数量大于该课程总人数");
            }
            if (classesVo.getClassesNumber() * classesVo.getPeopleNumber() > classesVo.getCoursePeopleNumber() || classesVo.getClassesNumber() * classesVo.getPeopleNumber() < classesVo.getCoursePeopleNumber()){
                throw new ServiceException("输入的班级数量和每班人数不符");
            }
            if (classesVo.getPeopleNumber() > classesVo.getCoursePeopleNumber()){
                throw new ServiceException("输入的每班人数大于该课程总人数");
            }
            //创建班级
            //输入的班级数量
            int classesNumber = classesVo.getClassesNumber();
            String className = "";
            switch (classesVo.getCourse()){
                case "1" :
                    className = "物政化";
                    break;
                case "2":
                    className = "物政生";
                    break;
                case "3":
                    className = "物政地";
                    break;
                case "4":
                    className = "物政历";
                    break;
                case "5":
                    className = "物历化";
                    break;
                case "6":
                    className = "物历生";
                    break;
                case "7":
                    className = "物地化";
                    break;
                case "8":
                    className = "物地生";
                    break;
                case "9":
                    className = "物化生";
                    break;
                case "10":
                    className = "物历地";
                    break;
                case "11":
                    className = "化政地";
                    break;
                case "12":
                    className = "化政历";
                    break;
                case "13":
                    className = "化政生";
                    break;
                case "14":
                    className = "化历地";
                    break;
                case "15":
                    className = "化历生";
                    break;
                case "16":
                    className = "化地生";
                    break;
                case "17":
                    className = "生政地";
                    break;
                case "18":
                    className = "生历地";
                    break;
                case "19":
                    className = "生政历";
                    break;
                case "20":
                    className = "政历地";
                    break;
            }
            //新增班级
            SchoolDivisionClasses schoolDivisionClasses = new SchoolDivisionClasses();
            schoolDivisionClasses.setCurriculaId(classesVo.getCurriculaId());
            schoolDivisionClasses.setCourse(classesVo.getCourse());
            schoolDivisionClasses.setDivisionClassesRule(classesVo.getDivisionClassesRule());
            schoolDivisionClasses.setDivisionClassesFrequency(classesVo.getDivisionClassesFrequency());
            schoolDivisionClasses.setCreateBy(SecurityUtils.getLoginUser().getUser().getUserName());
            schoolDivisionClasses.setCreateTime(DateUtils.getNowDate());
            for (int i = 1; i <= classesNumber; i++) {
                schoolDivisionClasses.setDivisionClassesName(className + i + "班");
                row += divisionClassesMapper.insert(schoolDivisionClasses);
            }

            //查询首次分班对应的班级
            LambdaQueryWrapper<SchoolDivisionClasses> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SchoolDivisionClasses::getCurriculaId,classesVo.getCurriculaId())
                    .eq(SchoolDivisionClasses::getCourse,classesVo.getCourse())
                    .eq(SchoolDivisionClasses::getDivisionClassesFrequency,"2")
                    .eq(SchoolDivisionClasses::getDelFlag,"0")
                    .orderByAsc(SchoolDivisionClasses::getDivisionClassesName);
            List<SchoolDivisionClasses> divisionClasses = divisionClassesMapper.selectList(wrapper);

            CurriculaStudentVo curriculaStudentVo = new CurriculaStudentVo();
            curriculaStudentVo.setCurriculaId(classesVo.getCurriculaId());
            curriculaStudentVo.setSelectedCourse(classesVo.getCourse());
            curriculaStudentVo.setCourseType("2");
            List<CurriculaStudentVo> curriculaStudentVoList = curriculaStudentService.selectCurriculaStudentListXjQm(curriculaStudentVo);

            //判断此次分班是平行分班还是分层分班
            if (classesVo.getDivisionClassesRule().equals("1")){
                //平行分班
                //根据成绩进行排名 从高到低
                List<CurriculaStudentVo> curriculaStudentVos = curriculaStudentVoList.stream().sorted(Comparator.comparing(CurriculaStudentVo::getCourseScore).reversed()).collect(Collectors.toList());

                //生成不重复随机数
                Random random = new Random();
                List<Integer> list1 = new ArrayList<>();
                while (true){
                    int index = random.nextInt(divisionClasses.size());
                    if (!list1.contains(index)){
                        list1.add(index);
                    }
                    if (list1.size() == divisionClasses.size()){
                        break;
                    }
                }
                List<CurriculaStudentVo> studentVoList = new ArrayList<>();
                //新增成绩好的学生与分班班级关系
                for (int i = 0; i < divisionClasses.size(); i++) {
                    SchoolDivisionStudent schoolDivisionStudent = new SchoolDivisionStudent();
                    schoolDivisionStudent.setDivisionClassesId(divisionClasses.get(list1.get(i)).getId());
                    CurriculaStudentVo curriculaStudentVo1 = curriculaStudentVos.get(i);
                    schoolDivisionStudent.setStudentId(curriculaStudentVo1.getStudentId());
                    schoolDivisionStudent.setFbcs("2");
                    divisionStudentMapper.insert(schoolDivisionStudent);
                    studentVoList.add(curriculaStudentVo1);
                }
                for (CurriculaStudentVo studentVo : studentVoList) {
                    curriculaStudentVos.remove(studentVo);
                }

                //随机新增剩余同学与分班班级关系
                for (int i = 0; i < divisionClasses.size(); i++) {

                    //随机生成每班人数减1个随机数
                    Random random1 = new Random();
                    List<Integer> people = new ArrayList<>();
                    if (classesVo.getPeopleNumber() - 1 != 0){
                        while (true){
                            int index = random1.nextInt(classesVo.getPeopleNumber() - 1);
                            if (!people.contains(index)){
                                people.add(index);
                            }
                            if (people.size() == classesVo.getPeopleNumber() - 1){
                                break;
                            }
                        }
                    }

                    for (int j = 0; j < classesVo.getPeopleNumber() - 1; j++) {
                        SchoolDivisionStudent schoolDivisionStudent = new SchoolDivisionStudent();
                        schoolDivisionStudent.setDivisionClassesId(divisionClasses.get(i).getId());
                        CurriculaStudentVo curriculaStudentVo1 = curriculaStudentVos.get(people.get(j));
                        schoolDivisionStudent.setStudentId(curriculaStudentVo1.getStudentId());
                        schoolDivisionStudent.setFbcs("2");
                        divisionStudentMapper.insert(schoolDivisionStudent);
                    }
                }
            }else {
                //分层分班
                //根据成绩进行排名 从高到低
                List<CurriculaStudentVo> curriculaStudentVos = curriculaStudentVoList.stream().sorted(Comparator.comparing(CurriculaStudentVo::getCourseScore).reversed()).collect(Collectors.toList());

                int index = 0;

                for (SchoolDivisionClasses schoolDivisionClasses1 : divisionClasses) {
                    SchoolDivisionStudent schoolDivisionStudent = new SchoolDivisionStudent();
                    //分班班级id
                    Long id = schoolDivisionClasses1.getId();
                    schoolDivisionStudent.setDivisionClassesId(id);
                    schoolDivisionStudent.setFbcs("2");

                    List<CurriculaStudentVo> studentVoList = new ArrayList<>();

                    //判断学生人数能不能整除输入的每班人数
                    if (curriculaStudentVos.size() % classesVo.getPeopleNumber() == 0){
                        for (int i = 0; i < classesVo.getPeopleNumber(); i++) {
                            CurriculaStudentVo studentVo = curriculaStudentVos.get(i);
                            schoolDivisionStudent.setStudentId(studentVo.getStudentId());
                            divisionStudentMapper.insert(schoolDivisionStudent);
                            studentVoList.add(studentVo);
                        }
                        for (CurriculaStudentVo studentVo : studentVoList) {
                            curriculaStudentVos.remove(studentVo);
                        }
                        studentVoList.clear();
                    }else {
                        int index1 = curriculaStudentVos.size() / classesVo.getPeopleNumber();
                        if (index == index1){
                            for (int i = 0; i < curriculaStudentVos.size() % classesVo.getPeopleNumber(); i++) {
                                CurriculaStudentVo studentVo = curriculaStudentVos.get(i);
                                schoolDivisionStudent.setStudentId(studentVo.getStudentId());
                                divisionStudentMapper.insert(schoolDivisionStudent);
                                studentVoList.add(studentVo);
                            }
                            for (CurriculaStudentVo studentVo : studentVoList) {
                                curriculaStudentVos.remove(studentVo);
                            }
                            studentVoList.clear();
                        }else {
                            for (int j = 0; j < classesVo.getPeopleNumber(); j++) {
                                CurriculaStudentVo studentVo = curriculaStudentVos.get(j);
                                schoolDivisionStudent.setStudentId(studentVo.getStudentId());
                                divisionStudentMapper.insert(schoolDivisionStudent);
                                studentVoList.add(studentVo);
                            }
                            for (CurriculaStudentVo studentVo : studentVoList) {
                                curriculaStudentVos.remove(studentVo);
                            }
                            studentVoList.clear();
                            index ++;
                        }
                    }
                }
            }
        }
        return row;
    }
}
