package com.ym.mec.biz.service.impl;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import com.ym.mec.biz.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.alibaba.fastjson.JSON;
import com.ym.mec.biz.dal.dao.ClassGroupDao;
import com.ym.mec.biz.dal.dao.ClassGroupStudentMapperDao;
import com.ym.mec.biz.dal.dao.CourseScheduleDao;
import com.ym.mec.biz.dal.dao.CourseScheduleStudentPaymentDao;
import com.ym.mec.biz.dal.dao.CourseScheduleTeacherSalaryDao;
import com.ym.mec.biz.dal.dao.MusicGroupDao;
import com.ym.mec.biz.dal.dao.OrganizationCourseUnitPriceSettingsDao;
import com.ym.mec.biz.dal.dao.StudentDao;
import com.ym.mec.biz.dal.dto.ClassGroupStudentInfoDto;
import com.ym.mec.biz.dal.entity.ClassGroup;
import com.ym.mec.biz.dal.entity.ClassGroupRelation;
import com.ym.mec.biz.dal.entity.ClassGroupStudentMapper;
import com.ym.mec.biz.dal.entity.ClassGroupTeacherMapper;
import com.ym.mec.biz.dal.entity.CourseSchedule;
import com.ym.mec.biz.dal.entity.CourseScheduleStudentPayment;
import com.ym.mec.biz.dal.entity.CourseScheduleTeacherSalary;
import com.ym.mec.biz.dal.entity.MusicGroup;
import com.ym.mec.biz.dal.entity.StudentRegistration;
import com.ym.mec.biz.dal.entity.TeacherDefaultMusicGroupSalary;
import com.ym.mec.biz.dal.enums.ClassGroupStudentStatusEnum;
import com.ym.mec.biz.dal.enums.ClassGroupTypeEnum;
import com.ym.mec.biz.dal.enums.CourseStatusEnum;
import com.ym.mec.biz.dal.enums.GroupType;
import com.ym.mec.biz.dal.enums.MusicGroupStatusEnum;
import com.ym.mec.biz.dal.enums.YesOrNoEnum;
import com.ym.mec.common.dal.BaseDAO;
import com.ym.mec.common.entity.ImGroupMember;
import com.ym.mec.common.entity.ImGroupModel;
import com.ym.mec.common.exception.BizException;
import com.ym.mec.common.service.impl.BaseServiceImpl;
import com.ym.mec.util.collection.MapUtil;
import com.ym.mec.util.date.DateUtil;
import com.ym.mec.util.http.HttpUtil;

@Service
public class ClassGroupStudentMapperServiceImpl extends BaseServiceImpl<Long, ClassGroupStudentMapper> implements ClassGroupStudentMapperService {

    @Autowired
    private ClassGroupStudentMapperDao classGroupStudentMapperDao;

    @Autowired
    private CourseScheduleService courseScheduleService;
    @Autowired
    StudentRegistrationService studentRegistrationService;
    @Autowired
    private CourseScheduleStudentPaymentService courseScheduleStudentPaymentService;
    @Autowired
    private ClassGroupService classGroupService;
    @Autowired
    private ClassGroupRelationService classGroupRelationService;
    @Autowired
    private ImGroupMemberService imGroupMemberService;
    @Autowired
    private CourseScheduleTeacherSalaryDao courseScheduleTeacherSalaryDao;
    @Autowired
    private ClassGroupTeacherMapperService classGroupTeacherMapperService;
    @Autowired
    private CourseScheduleTeacherSalaryService courseScheduleTeacherSalaryService;
    @Autowired
    private TeacherDefaultMusicGroupSalaryService teacherDefaultMusicGroupSalaryService;
    @Autowired
    private StudentDao studentDao;
    @Autowired
    private CourseScheduleDao courseScheduleDao;
    @Autowired
    private OrganizationCourseUnitPriceSettingsDao organizationCourseUnitPriceSettingsDao;
    @Autowired
    private ClassGroupDao classGroupDao;
    @Autowired
    private MusicGroupDao musicGroupDao;

    @Autowired
    private CourseScheduleStudentPaymentDao courseScheduleStudentPaymentDao;

    @Autowired
    private ImUserFriendService imUserFriendService;

    private static String holidayUrl = "http://tool.bitefu.net/jiari/?d=";

    @Override
    public BaseDAO<Long, ClassGroupStudentMapper> getDAO() {
        return classGroupStudentMapperDao;
    }

    @Override
    public ClassGroupStudentMapper findClassStudentMapperByUserIdAndClassGroupId(Integer userId, Integer classGroupId, String status) {
        return classGroupStudentMapperDao.findClassStudentMapperByUserIdAndClassGroupId(userId, classGroupId, status);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delClassGroupStudent(Integer userId, Integer classGroupId, Boolean quitMusicGroup) {
        ClassGroup classGroup = classGroupService.get(classGroupId);
        Integer studentNum = classGroupStudentMapperDao.countClassGroupNormalStudentNum(classGroupId);
        /*if (!quitMusicGroup && classGroup.getType().equals(ClassGroupTypeEnum.HIGH_ONLINE) && studentNum <= 3) {
            throw new BizException(classGroup.getName()+"（网络基础训练课班级）人数不能少于3,请调整");
        }*/

        ClassGroupStudentMapper classStudentMapper = findClassStudentMapperByUserIdAndClassGroupId(userId, classGroupId, "NORMAL");
        if (classStudentMapper == null) {
            throw new BizException("班级学生不存在");
        }
        //1、删除班级学生对应班级关系
        classStudentMapper.setStatus(ClassGroupStudentStatusEnum.QUIT);
        update(classStudentMapper);
        StudentRegistration student = studentRegistrationService.findStudentByClassGroupIdAndUserId(userId, classGroupId);
        if (student != null) {
            student.setClassGroupId(0);
            studentRegistrationService.update(student);
        }

        //2、班级人数调整
        classGroupService.updateClassStudentNum(classGroupId);

        //3、删除学生对应班级的课程
        List<CourseSchedule> courseScheduleList = courseScheduleService.findNoStartCoursesByClassGroupId(classGroupId);
        if (courseScheduleList.size() > 0) {

            List<Long> tempMergedCourseIdList = courseScheduleList.stream().map(CourseSchedule::getId).collect(Collectors.toList());
            if (tempMergedCourseIdList != null && tempMergedCourseIdList.size() > 0) {
                courseScheduleStudentPaymentDao.deleteStudentCourseSchedule(userId, tempMergedCourseIdList);
            }
        }

        //4、调整未上课课酬
        List<ClassGroupTeacherMapper> classGroupTeachers = classGroupTeacherMapperService.getClassGroupTeachers(classGroupId);
        if ((classGroup.getType().equals(ClassGroupTypeEnum.HIGH_ONLINE) || classGroup.getType().equals(ClassGroupTypeEnum.HIGH)) && courseScheduleList.size() > 0) {
            studentNum -= 1;
            Date nowDate = new Date();
            List<CourseScheduleTeacherSalary> courseScheduleTeacherSalaryList = new ArrayList<>();
            List<Long> courseScheduleIds = courseScheduleList.stream().map(CourseSchedule::getId).collect(Collectors.toList());
            courseScheduleTeacherSalaryDao.batchDeleteByCourseScheduleIds(courseScheduleIds);
            for (CourseSchedule courseSchedule : courseScheduleList) {
                for (ClassGroupTeacherMapper classGroupTeacher : classGroupTeachers) {
                    List<TeacherDefaultMusicGroupSalary> teacherSalaryList = teacherDefaultMusicGroupSalaryService.getTeacherSalaryByUserIdAndType(classGroupTeacher.getUserId(), ClassGroupTypeEnum.HIGH_ONLINE.getCode(), null);
                    if (teacherSalaryList == null || teacherSalaryList.size() == 0) {
                        throw new BizException("请设置老师线上网管课课酬");
                    }
                    Map<CourseSchedule.CourseScheduleType, TeacherDefaultMusicGroupSalary> collect = teacherSalaryList.stream().collect(Collectors.toMap(TeacherDefaultMusicGroupSalary::getCourseScheduleType, teacherDefaultMusicGroupSalary -> teacherDefaultMusicGroupSalary));
                    TeacherDefaultMusicGroupSalary teacherDefaultMusicGroupSalary = collect.get(CourseSchedule.CourseScheduleType.HIGH_ONLINE);
                    if (studentNum > 5) {
                        studentNum = 5;
                    }
                    BigDecimal salary = JSON.parseObject(teacherDefaultMusicGroupSalary.getSalaryRuleJson()).getBigDecimal(studentNum.toString());

                    CourseScheduleTeacherSalary courseScheduleTeacherSalary = new CourseScheduleTeacherSalary();
                    courseScheduleTeacherSalary.setCourseScheduleId(courseSchedule.getId());
                    courseScheduleTeacherSalary.setGroupType(courseSchedule.getGroupType());
                    courseScheduleTeacherSalary.setMusicGroupId(courseSchedule.getMusicGroupId());
                    courseScheduleTeacherSalary.setTeacherRole(classGroupTeacher.getTeacherRole());
                    courseScheduleTeacherSalary.setUserId(classGroupTeacher.getUserId());
                    courseScheduleTeacherSalary.setExpectSalary(salary);
                    courseScheduleTeacherSalary.setClassGroupId(classGroup.getId());
                    courseScheduleTeacherSalary.setCreateTime(nowDate);
                    courseScheduleTeacherSalary.setUpdateTime(nowDate);
                    courseScheduleTeacherSalaryList.add(courseScheduleTeacherSalary);
                }
            }
            courseScheduleTeacherSalaryService.batchInsert(courseScheduleTeacherSalaryList);
        }

        //5、学生退出班级群组
        imGroupMemberService.quit(classGroup.getId().longValue(), userId);
        return true;
    }

    @Override
    public List<StudentRegistration> findClassStudentList(Integer classGroupId, ClassGroupStudentStatusEnum status) {
        return classGroupStudentMapperDao.findClassStudentList(classGroupId, status);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean adjustClassGroup(Integer userId, Integer oldClassGroupId, Integer classGroupId) throws Exception {
        ClassGroupStudentMapper classStudentMapper = findClassStudentMapperByUserIdAndClassGroupId(userId, oldClassGroupId, "NORMAL");
        if (classStudentMapper == null) {
            throw new BizException("原班级学生不存在");
        }
        Date date = new Date();
        //1、更新学生对应班级关系
        classStudentMapper.setClassGroupId(classGroupId);
        update(classStudentMapper);
        //班级人数调整
        classGroupService.updateClassStudentNum(oldClassGroupId);
        classGroupService.updateClassStudentNum(classGroupId, 1);

        //2、删除学生对应原班级未开始课程
        List<CourseSchedule> courseScheduleList = courseScheduleService.findNoStartCoursesByClassGroupId(oldClassGroupId);
        courseScheduleStudentPaymentService.deleteStudentCourseSchedule(userId, courseScheduleList);

        //3、学生加入新班级未开始课程
        courseScheduleList = courseScheduleService.findNoStartCoursesByClassGroupId(classGroupId);

        BigDecimal coursePrice = new BigDecimal("0");
        List<CourseScheduleStudentPayment> courseScheduleStudentPayments = new ArrayList<>();
        for (CourseSchedule courseSchedule : courseScheduleList) {
            CourseScheduleStudentPayment courseScheduleStudentPayment = new CourseScheduleStudentPayment();
            courseScheduleStudentPayment.setGroupType(courseSchedule.getGroupType());
            courseScheduleStudentPayment.setMusicGroupId(courseSchedule.getMusicGroupId());
            courseScheduleStudentPayment.setCourseScheduleId(courseSchedule.getId());
            courseScheduleStudentPayment.setUserId(userId);
            courseScheduleStudentPayment.setExpectPrice(coursePrice);
            courseScheduleStudentPayment.setClassGroupId(classGroupId);
            courseScheduleStudentPayment.setCreateTime(date);
            courseScheduleStudentPayment.setUpdateTime(date);
            courseScheduleStudentPayments.add(courseScheduleStudentPayment);
        }
        if (courseScheduleStudentPayments.size() == 0) {
            return true;
        }

        courseScheduleStudentPaymentService.batchInsert(courseScheduleStudentPayments);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addStudents(Integer classGroupId, String userIdsStr, GroupType groupType) throws Exception {
        ClassGroup classGroup = classGroupService.get(classGroupId);
        if (classGroup == null) {
            throw new BizException("添加学员的班级不存在");
        }
        Date nowDate = new Date();
        HashSet<String> userIdStrSet = new HashSet<>(Arrays.asList(userIdsStr.split(",")));

        Integer studentNum = classGroupStudentMapperDao.countClassGroupNormalStudentNum(classGroupId);
        if (classGroup.getType().equals(ClassGroupTypeEnum.HIGH_ONLINE) &&
                ((studentNum + userIdStrSet.size()) < 3 || (studentNum + userIdStrSet.size()) > 5)) {
            throw new BizException("网络基础训练课班级人数不能小于3大于5");
        }

        //1、班级关系添加
        List<ClassGroupStudentMapper> classGroupStudentMappers = new ArrayList<>();
        Map<Integer,String> userRoleMap = new HashMap<Integer, String>();

        ClassGroupRelation classGroupRelation = classGroupRelationService.findClassGroupRelation(classGroupId);

        Iterator<String> iterator = userIdStrSet.iterator();
        while (iterator.hasNext()) {
            Integer userId = Integer.parseInt(iterator.next());
            List<ClassGroupStudentMapper> highClassGroupHasUser = classGroupStudentMapperDao.findHighClassGroupHasUser(classGroup.getMusicGroupId(), userId, classGroup.getType());
            if (!classGroup.getType().equals(ClassGroupTypeEnum.SNAP) && highClassGroupHasUser != null && highClassGroupHasUser.size() > 0) {
                iterator.remove();
                continue;
            }

            ClassGroupStudentMapper classGroupStudentMapper = new ClassGroupStudentMapper();
            classGroupStudentMapper.setMusicGroupId(classGroup.getMusicGroupId());
            classGroupStudentMapper.setClassGroupId(classGroupId);
            classGroupStudentMapper.setUserId(userId);
            classGroupStudentMapper.setCreateTime(nowDate);
            classGroupStudentMapper.setStatus(ClassGroupStudentStatusEnum.NORMAL);
            classGroupStudentMapper.setGroupType(GroupType.MUSIC);
            classGroupStudentMappers.add(classGroupStudentMapper);

            if (classGroup.getType().equals(ClassGroupTypeEnum.NORMAL)) {
                StudentRegistration studentRegistration = studentRegistrationService.queryByUserIdAndMusicGroupId(userId, classGroup.getMusicGroupId());
                studentRegistration.setClassGroupId(classGroupId);
                studentRegistrationService.update(studentRegistration);
            }
            userRoleMap.put(userId, "");
        }
        if (classGroupStudentMappers.size() > 0) {
            classGroupStudentMapperDao.classGroupStudentsInsert(classGroupStudentMappers);
        }

        //2、班级人数调整
        classGroupService.updateClassStudentNum(classGroupId, userIdStrSet.size());

        //3、学生加入新班级未开始课程
        List<CourseSchedule> courseScheduleList = courseScheduleService.findNoStartCoursesByClassGroupId(classGroupId);

        List<CourseScheduleStudentPayment> courseScheduleStudentPayments = new ArrayList<>();
        for (CourseSchedule courseSchedule : courseScheduleList) {
            for (String userIdStr : userIdStrSet) {
                CourseScheduleStudentPayment courseScheduleStudentPayment = new CourseScheduleStudentPayment();
                courseScheduleStudentPayment.setGroupType(classGroup.getGroupType());
                courseScheduleStudentPayment.setMusicGroupId(classGroup.getMusicGroupId());
                courseScheduleStudentPayment.setCourseScheduleId(courseSchedule.getId());
                courseScheduleStudentPayment.setUserId(Integer.parseInt(userIdStr));
                courseScheduleStudentPayment.setExpectPrice(BigDecimal.ZERO);
                courseScheduleStudentPayment.setClassGroupId(classGroupId);
                courseScheduleStudentPayment.setCreateTime(nowDate);
                courseScheduleStudentPayment.setUpdateTime(nowDate);
                courseScheduleStudentPayments.add(courseScheduleStudentPayment);
            }
        }

        if (courseScheduleStudentPayments.size() > 0) {
            courseScheduleStudentPaymentService.batchInsert(courseScheduleStudentPayments);
        }
        //4、调整未上课课酬
        List<ClassGroupTeacherMapper> classGroupTeachers = classGroupTeacherMapperService.getClassGroupTeachers(classGroupId);
        if (classGroup.getType().equals(ClassGroupTypeEnum.HIGH_ONLINE) && courseScheduleList.size() > 0) {
            studentNum += userIdStrSet.size();
            List<CourseScheduleTeacherSalary> courseScheduleTeacherSalaryList = new ArrayList<>();
            List<Long> courseScheduleIds = courseScheduleList.stream().map(CourseSchedule::getId).collect(Collectors.toList());
            courseScheduleTeacherSalaryDao.batchDeleteByCourseScheduleIds(courseScheduleIds);
            for (CourseSchedule courseSchedule : courseScheduleList) {
                for (ClassGroupTeacherMapper classGroupTeacher : classGroupTeachers) {
                    List<TeacherDefaultMusicGroupSalary> teacherSalaryList = teacherDefaultMusicGroupSalaryService.getTeacherSalaryByUserIdAndType(classGroupTeacher.getUserId(), ClassGroupTypeEnum.HIGH_ONLINE.getCode(), null);
                    if (teacherSalaryList == null || teacherSalaryList.size() == 0) {
                        throw new BizException("请设置老师线上网管课课酬");
                    }
                    Map<CourseSchedule.CourseScheduleType, TeacherDefaultMusicGroupSalary> collect = teacherSalaryList.stream().collect(Collectors.toMap(TeacherDefaultMusicGroupSalary::getCourseScheduleType, teacherDefaultMusicGroupSalary -> teacherDefaultMusicGroupSalary));
                    TeacherDefaultMusicGroupSalary teacherDefaultMusicGroupSalary = collect.get(courseSchedule.getType());
                    if (studentNum > 5) {
                        studentNum = 5;
                    }
                    BigDecimal salary = JSON.parseObject(teacherDefaultMusicGroupSalary.getSalaryRuleJson()).getBigDecimal(studentNum.toString());

                    CourseScheduleTeacherSalary courseScheduleTeacherSalary = new CourseScheduleTeacherSalary();
                    courseScheduleTeacherSalary.setCourseScheduleId(courseSchedule.getId());
                    courseScheduleTeacherSalary.setGroupType(courseSchedule.getGroupType());
                    courseScheduleTeacherSalary.setMusicGroupId(courseSchedule.getMusicGroupId());
                    courseScheduleTeacherSalary.setTeacherRole(classGroupTeacher.getTeacherRole());
                    courseScheduleTeacherSalary.setUserId(classGroupTeacher.getUserId());
                    courseScheduleTeacherSalary.setExpectSalary(salary);
                    courseScheduleTeacherSalary.setClassGroupId(classGroup.getId());
                    courseScheduleTeacherSalary.setCreateTime(nowDate);
                    courseScheduleTeacherSalary.setUpdateTime(nowDate);
                    courseScheduleTeacherSalaryList.add(courseScheduleTeacherSalary);
                }
            }
            courseScheduleTeacherSalaryService.batchInsert(courseScheduleTeacherSalaryList);

            List<Integer> studentIds = userIdStrSet.stream().map(e -> Integer.parseInt(e)).collect(Collectors.toList());
            studentDao.updateStudentServiceTag(null, studentIds, YesOrNoEnum.YES.getCode());
        }

        //乐团在合奏班
        if (classGroupRelation != null) {
            addStudents(classGroupRelation.getClassGroupId(), userIdsStr, GroupType.MUSIC);
        }

        //5、添加进IM群组
        imGroupMemberService.join(classGroup.getId().longValue(), userRoleMap);

        return true;
    }

    @Override
    public Object queryHoliday(String year) throws IOException {
        return HttpUtil.get(holidayUrl + year, null);
    }

    @Override
    public List<ClassGroupStudentMapper> findMusicGroupClassGroupByType(String musicGroupId, ClassGroupTypeEnum type) {
        return classGroupStudentMapperDao.findMusicGroupClassGroupByType(musicGroupId, type);
    }

    @Override
    public void classGroupStudentsInsert(List<ClassGroupStudentMapper> classGroupStudentMappers) {
        classGroupStudentMapperDao.classGroupStudentsInsert(classGroupStudentMappers);
    }

    @Override
    public List<ClassGroupStudentInfoDto> findStudentByGroupOrClassGroup(String groupId, Integer classGroupId, GroupType groupType) {
        return classGroupStudentMapperDao.findByGroupOrClassGroup(groupId, groupType, classGroupId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
    public void updateClassGroupStudents(Long classGroupId, Set<Integer> studentIds) {
        ClassGroup classGroup = classGroupDao.lockClassGroup(classGroupId.intValue());
        if (Objects.isNull(classGroup)) {
            throw new BizException("班级信息错误");
        }

        if (ClassGroupTypeEnum.MUSIC_NETWORK.equals(classGroup.getType())) {
            String subjectName = classGroup.getName().split("•")[0];
            List<String> studentNames = studentDao.getStudentNames(new ArrayList<>(studentIds));
            classGroup.setName(subjectName + "•" + studentNames);
        }

        List<ClassGroupStudentMapper> classGroupStudents = classGroupStudentMapperDao.findAllByClassGroup(classGroupId);

        Set<Integer> allStudentIds = new HashSet<>();
        Set<Integer> oldStudentIds = new HashSet<>();
        Set<Integer> oldNormalStudentIds = new HashSet<>();
        Set<Integer> addStudentIds;
        Set<Integer> removeStudentIds;

        if (!CollectionUtils.isEmpty(studentIds)) {
            allStudentIds = studentIds;
        }

        if (!CollectionUtils.isEmpty(classGroupStudents)) {
            oldStudentIds = classGroupStudents.stream().map(ClassGroupStudentMapper::getUserId).collect(Collectors.toSet());
            oldNormalStudentIds = classGroupStudents.stream().filter(s -> ClassGroupStudentStatusEnum.NORMAL.equals(s.getStatus())).map(ClassGroupStudentMapper::getUserId).collect(Collectors.toSet());
        }
        MusicGroup musicGroup = musicGroupDao.get(classGroup.getMusicGroupId());
        //线上基础技能班，原始分班人数不能小于3人大于6人
        if (classGroup.getType().equals(ClassGroupTypeEnum.HIGH_ONLINE)) {

            if (studentIds.size() < 3 && musicGroup.getStatus().equals(MusicGroupStatusEnum.PREPARE)) {
                throw new BizException("线上基础技能班人数不能少于3人");
            }
            if (studentIds.size() < 3 && !musicGroup.getStatus().equals(MusicGroupStatusEnum.PREPARE) && oldNormalStudentIds.size() <= 0) {
                throw new BizException("线上基础技能班人数不能少于3人");
            }
            if (studentIds.size() > 6) {
                throw new BizException("线上基础技能班人数不能多于6人");
            }
        }

        Set<Integer> repeatStudentIds = allStudentIds.stream().filter(oldNormalStudentIds::contains).collect(Collectors.toSet());
        addStudentIds = allStudentIds.stream().filter(id -> !repeatStudentIds.contains(id)).collect(Collectors.toSet());
        removeStudentIds = oldNormalStudentIds.stream().filter(id -> !repeatStudentIds.contains(id)).collect(Collectors.toSet());

        List<ClassGroupStudentMapper> needUpdateClassGroupStudents = new ArrayList<>();

        for (ClassGroupStudentMapper classGroupStudent : classGroupStudents) {
            if (addStudentIds.contains(classGroupStudent.getUserId()) && !classGroupStudent.getStatus().equals(ClassGroupStudentStatusEnum.NORMAL)) {
                classGroupStudent.setStatus(ClassGroupStudentStatusEnum.NORMAL);
            } else if (removeStudentIds.contains(classGroupStudent.getUserId()) && !classGroupStudent.getStatus().equals(ClassGroupStudentStatusEnum.QUIT)) {
                classGroupStudent.setStatus(ClassGroupStudentStatusEnum.QUIT);
            } else {
                continue;
            }
            needUpdateClassGroupStudents.add(classGroupStudent);
        }

        if (!CollectionUtils.isEmpty(needUpdateClassGroupStudents)) {
            classGroupStudentMapperDao.batchUpdate(needUpdateClassGroupStudents);
        }

        Date now = new Date();
        List<ClassGroupStudentMapper> classGroupStudentMappers = new ArrayList<>();
        for (Integer addStudentId : addStudentIds) {
            if (oldStudentIds.contains(addStudentId)) {
                continue;
            }
            ClassGroupStudentMapper classGroupStudentMapper = new ClassGroupStudentMapper();
            classGroupStudentMapper.setMusicGroupId(classGroup.getMusicGroupId());
            classGroupStudentMapper.setClassGroupId(classGroupId.intValue());
            classGroupStudentMapper.setUserId(addStudentId);
            classGroupStudentMapper.setCreateTime(now);
            classGroupStudentMapper.setStatus(ClassGroupStudentStatusEnum.NORMAL);
            classGroupStudentMapper.setGroupType(GroupType.MUSIC);
            classGroupStudentMappers.add(classGroupStudentMapper);
        }

        if (classGroupStudentMappers.size() > 0) {
            classGroupStudentMapperDao.classGroupStudentsInsert(classGroupStudentMappers);
        }

        classGroupService.updateClassStudentNum(classGroupId.intValue(), allStudentIds.size());

        List<CourseSchedule> classGroupNotStartCourse = courseScheduleDao.findCoursesByClassGroupId(classGroupId.intValue(), CourseStatusEnum.NOT_START);
        if (CollectionUtils.isEmpty(classGroupNotStartCourse)) {
            return;
        }

        if (ClassGroupTypeEnum.MUSIC_NETWORK.equals(classGroup.getType())) {
            for (CourseSchedule courseSchedule : classGroupNotStartCourse) {
                courseSchedule.setName(classGroup.getName());
            }
            courseScheduleDao.batchUpdate(classGroupNotStartCourse);
        }

        List<Long> courseIds = classGroupNotStartCourse.stream().map(CourseSchedule::getId).collect(Collectors.toList());

        //4、调整未上课课酬
        List<ClassGroupTeacherMapper> classGroupTeachers = classGroupTeacherMapperService.getClassGroupTeachers(classGroupId.intValue());
        if ((classGroup.getType().equals(ClassGroupTypeEnum.HIGH_ONLINE) || classGroup.getType().equals(ClassGroupTypeEnum.HIGH)) && classGroupNotStartCourse.size() > 0) {
            Date nowDate = new Date();
            List<CourseScheduleTeacherSalary> courseScheduleTeacherSalaryList = new ArrayList<>();
            List<Long> courseScheduleIds = classGroupNotStartCourse.stream().map(CourseSchedule::getId).collect(Collectors.toList());
            courseScheduleTeacherSalaryDao.batchDeleteByCourseScheduleIds(courseScheduleIds);
            for (CourseSchedule courseSchedule : classGroupNotStartCourse) {
                for (ClassGroupTeacherMapper classGroupTeacher : classGroupTeachers) {
                    List<TeacherDefaultMusicGroupSalary> teacherSalaryList = teacherDefaultMusicGroupSalaryService.getTeacherSalaryByUserIdAndType(classGroupTeacher.getUserId(), ClassGroupTypeEnum.HIGH_ONLINE.getCode(), null);
                    if (teacherSalaryList == null || teacherSalaryList.size() == 0) {
                        throw new BizException("请设置老师线上网管课课酬");
                    }
                    Map<CourseSchedule.CourseScheduleType, TeacherDefaultMusicGroupSalary> collect = teacherSalaryList.stream().collect(Collectors.toMap(TeacherDefaultMusicGroupSalary::getCourseScheduleType, teacherDefaultMusicGroupSalary -> teacherDefaultMusicGroupSalary));
                    TeacherDefaultMusicGroupSalary teacherDefaultMusicGroupSalary = collect.get(CourseSchedule.CourseScheduleType.HIGH_ONLINE);

                    int studentNum = studentIds.size();
                    if (studentNum > 5) {
                        studentNum = 5;
                    }

                    BigDecimal salary = JSON.parseObject(teacherDefaultMusicGroupSalary.getSalaryRuleJson()).getBigDecimal(studentNum + "");

                    CourseScheduleTeacherSalary courseScheduleTeacherSalary = new CourseScheduleTeacherSalary();
                    courseScheduleTeacherSalary.setCourseScheduleId(courseSchedule.getId());
                    courseScheduleTeacherSalary.setGroupType(courseSchedule.getGroupType());
                    courseScheduleTeacherSalary.setMusicGroupId(courseSchedule.getMusicGroupId());
                    courseScheduleTeacherSalary.setTeacherRole(classGroupTeacher.getTeacherRole());
                    courseScheduleTeacherSalary.setUserId(classGroupTeacher.getUserId());
                    courseScheduleTeacherSalary.setExpectSalary(salary);
                    courseScheduleTeacherSalary.setClassGroupId(classGroup.getId());
                    courseScheduleTeacherSalary.setCreateTime(nowDate);
                    courseScheduleTeacherSalary.setUpdateTime(nowDate);
                    courseScheduleTeacherSalaryList.add(courseScheduleTeacherSalary);
                }
            }
            courseScheduleTeacherSalaryService.batchInsert(courseScheduleTeacherSalaryList);
        }

        if (!CollectionUtils.isEmpty(removeStudentIds)) {
            courseScheduleDao.deleteMusicGroupCourseSchedulesWithStudents(courseIds, new ArrayList<>(removeStudentIds));
            if(musicGroup.getStatus() == MusicGroupStatusEnum.PROGRESS){
                //5、学生退出班级群组
                imGroupMemberService.quit(classGroup.getId().longValue(), new ArrayList<Integer>(addStudentIds));
            }
        }

        if (!CollectionUtils.isEmpty(addStudentIds)) {
            courseScheduleStudentPaymentService.createForMusicGroup(classGroup.getMusicGroupId(), classGroupNotStartCourse, new ArrayList<>(addStudentIds));
            if(musicGroup.getStatus() == MusicGroupStatusEnum.PROGRESS){
                Map<Integer,String> userRoleMap = new HashMap<>();
                for (Integer addStudentId : addStudentIds) {
                    userRoleMap.put(addStudentId, "");
                }
                //5、添加进IM群组
                imGroupMemberService.join(classGroup.getId().longValue(), userRoleMap);
            }
        }
        if(musicGroup.getStatus() == MusicGroupStatusEnum.PROGRESS){
            imUserFriendService.refreshClassImUserFriend(classGroup.getId());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateClassGroupStudents1(Long classGroupId, List<Integer> studentIds,List<Long> allLockCourseIds,String batchNo,BigDecimal masterTotalPrice) {
        ClassGroup classGroup = classGroupDao.lockClassGroup(classGroupId.intValue());
        if (Objects.isNull(classGroup)) {
            throw new BizException("班级信息错误");
        }
        List<CourseScheduleStudentPayment> courseScheduleStudentPayments = new ArrayList<>();
        //获取冻结的课程列表
        List<CourseSchedule> classGroupNotStartCourse = courseScheduleDao.findCoursesByClassGroupIdAndCourseIds(classGroupId,allLockCourseIds);

        Date now = new Date();
        List<ClassGroupStudentMapper> classGroupStudentMappers = new ArrayList<>();

        BigDecimal divide = masterTotalPrice.divide(new BigDecimal(classGroupNotStartCourse.size()), 2, BigDecimal.ROUND_HALF_UP);
        BigDecimal decimal = divide.multiply(new BigDecimal(classGroupNotStartCourse.size()));

        //生成班级关联
        for (Integer studentId : studentIds) {
            ClassGroupStudentMapper classGroupStudent = classGroupStudentMapperDao.findClassGroupStudent(classGroupId.intValue(), studentId);
            if(classGroupStudent != null){
                classGroupStudent.setStatus(ClassGroupStudentStatusEnum.NORMAL);
                classGroupStudentMapperDao.update(classGroupStudent);
            }else {
                ClassGroupStudentMapper classGroupStudentMapper = new ClassGroupStudentMapper();
                classGroupStudentMapper.setMusicGroupId(classGroup.getMusicGroupId());
                classGroupStudentMapper.setClassGroupId(classGroupId.intValue());
                classGroupStudentMapper.setUserId(studentId);
                classGroupStudentMapper.setCreateTime(now);
                classGroupStudentMapper.setStatus(ClassGroupStudentStatusEnum.NORMAL);
                classGroupStudentMapper.setGroupType(GroupType.MUSIC);
                classGroupStudentMappers.add(classGroupStudentMapper);
            }
            //生成课程关联
            for (int i = 0; i < classGroupNotStartCourse.size(); i++) {
                CourseSchedule courseSchedule = classGroupNotStartCourse.get(i);
                CourseScheduleStudentPayment cssp = new CourseScheduleStudentPayment();
                cssp.setGroupType(courseSchedule.getGroupType());
                cssp.setMusicGroupId(courseSchedule.getMusicGroupId());
                cssp.setCourseScheduleId(courseSchedule.getId());
                cssp.setClassGroupId(courseSchedule.getClassGroupId());
                cssp.setBatchNo(batchNo);
                cssp.setUserId(studentId);
                if(i == 0){
                    cssp.setOriginalPrice(divide.add(masterTotalPrice.subtract(decimal)));
                    cssp.setExpectPrice(divide.add(masterTotalPrice.subtract(decimal)));
                }else {
                    cssp.setOriginalPrice(divide);
                    cssp.setExpectPrice(divide);
                }
                cssp.setActualPrice(BigDecimal.ZERO);
                courseScheduleStudentPayments.add(cssp);
            }
        }
        if (classGroupStudentMappers.size() > 0) {
            classGroupStudentMapperDao.classGroupStudentsInsert(classGroupStudentMappers);
        }
        if (courseScheduleStudentPayments.size() > 0) {
            courseScheduleStudentPaymentDao.batchInsert(courseScheduleStudentPayments);
        }
        //修改班级人数
        classGroupService.updateClassStudentNum(classGroupId.intValue(), classGroup.getStudentNum() + studentIds.size());

        //添加进IM群组
        Map<Integer,String> userRoleMap = new HashMap<Integer, String>();
        for (Integer studentId : studentIds) {
        	userRoleMap.put(studentId, null);
        }
        imGroupMemberService.join(classGroupId.longValue(), userRoleMap);
        imUserFriendService.refreshClassImUserFriend(classGroupId.intValue());
    }
}
