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

import com.alibaba.fastjson.JSON;
import com.ym.mec.biz.dal.dao.*;
import com.ym.mec.biz.dal.dto.ClassGroupTeachersDto;
import com.ym.mec.biz.dal.entity.*;
import com.ym.mec.biz.dal.enums.*;
import com.ym.mec.biz.service.*;
import com.ym.mec.common.constant.CommonConstants;
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.im.ImFeignService;
import com.ym.mec.util.collection.MapUtil;
import com.ym.mec.util.date.DateUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

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

@Service
public class ClassGroupTeacherMapperServiceImpl extends BaseServiceImpl<Long, ClassGroupTeacherMapper> implements ClassGroupTeacherMapperService {

    @Autowired
    private ClassGroupTeacherMapperDao classGroupTeacherMapperDao;
    @Autowired
    private CourseScheduleService courseScheduleService;
    @Autowired
    private CourseScheduleTeacherSalaryDao courseScheduleTeacherSalaryDao;
    @Autowired
    private CourseScheduleTeacherSalaryService courseScheduleTeacherSalaryService;
    @Autowired
    private TeacherDefaultMusicGroupSalaryDao teacherDefaultMusicGroupSalaryDao;
    @Autowired
    private SysConfigDao sysConfigDao;
    @Autowired
    private ImFeignService imFeignService;
    @Autowired
    private ClassGroupService classGroupService;
    @Autowired
    private MusicGroupService musicGroupService;
    @Autowired
    private TeacherAttendanceDao teacherAttendanceDao;
    @Autowired
    private CourseScheduleDao courseScheduleDao;
    @Autowired
    private TeacherDao teacherDao;
    @Autowired
    private ClassGroupStudentMapperDao classGroupStudentMapperDao;

    @Override
    public BaseDAO<Long, ClassGroupTeacherMapper> getDAO() {
        return classGroupTeacherMapperDao;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int classGroupTeachersInsert(List<ClassGroupTeacherMapper> classGroupTeacherMapperList) {

        String classGroupIds = classGroupTeacherMapperList.stream().map(classGroupTeacherMapper -> classGroupTeacherMapper.getClassGroupId().toString()).collect(Collectors.joining(","));
        //老师加入群组
        List<ImGroupMember> imGroupMemberList = new ArrayList<>();
        List<ClassGroup> classGroups = classGroupService.findClassGroupByIds(classGroupIds);

        List<ClassGroupTeacherMapper> oldClassGroupTeacherMapper = classGroupTeacherMapperDao.getClassGroupTeacherMapper(classGroupTeacherMapperList, GroupType.MUSIC);

        for (ClassGroup classGroup : classGroups) {
            imGroupMemberList.clear();
            //原设置的老师删除群组
            for (ClassGroupTeacherMapper classGroupTeacherMapper : oldClassGroupTeacherMapper) {
                if (!classGroup.getId().equals(classGroupTeacherMapper.getClassGroupId())) continue;
                imGroupMemberList.add(new ImGroupMember(classGroupTeacherMapper.getUserId().toString()));
            }
            if (imGroupMemberList.size() > 0) {
                ImGroupMember[] imGroupMembers = imGroupMemberList.toArray(new ImGroupMember[imGroupMemberList.size()]);
                imFeignService.groupQuit(new ImGroupModel(classGroup.getId().toString(), imGroupMembers, classGroup.getName()));
            }
            // 新设置的老师加入群组
            imGroupMemberList.clear();
            for (ClassGroupTeacherMapper classGroupTeacherMapper : classGroupTeacherMapperList) {
                if (!classGroup.getId().equals(classGroupTeacherMapper.getClassGroupId())) continue;
                classGroupTeacherMapper.setMusicGroupId(classGroup.getMusicGroupId());
                classGroupTeacherMapper.setGroupType(classGroup.getGroupType());
                imGroupMemberList.add(new ImGroupMember(classGroupTeacherMapper.getUserId().toString()));
            }
            ImGroupMember[] imGroupMembers = imGroupMemberList.toArray(new ImGroupMember[imGroupMemberList.size()]);
            imFeignService.groupJoin(new ImGroupModel(classGroup.getId().toString(), imGroupMembers, classGroup.getName()));
        }
        classGroupTeacherMapperDao.delMusicGroupTeacherMapper(classGroupTeacherMapperList);

        return classGroupTeacherMapperDao.classGroupTeachersInsert(classGroupTeacherMapperList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int classGroupTeachersInsert(List<ClassGroupTeacherMapper> classGroupTeacherMapperList, boolean checkCourser) {
        String classGroupIds = classGroupTeacherMapperList.stream().map(classGroupTeacherMapper -> classGroupTeacherMapper.getClassGroupId().toString()).collect(Collectors.joining(","));
        //老师加入群组
        List<ImGroupMember> imGroupMemberList = new ArrayList<>();
        List<ClassGroup> classGroups = classGroupService.findClassGroupByIds(classGroupIds);

        List<ClassGroupTeacherMapper> oldClassGroupTeacherMapper = classGroupTeacherMapperDao.getClassGroupTeacherMapper(classGroupTeacherMapperList, GroupType.MUSIC);

        Set<String> oldTeacher = new HashSet<>();
        Set<String> newTeacher = new HashSet<>();
        for (ClassGroup classGroup : classGroups) {
            imGroupMemberList.clear();
            //原设置的老师删除群组
            for (ClassGroupTeacherMapper classGroupTeacherMapper : oldClassGroupTeacherMapper) {
                if (!classGroup.getId().equals(classGroupTeacherMapper.getClassGroupId())) continue;
                imGroupMemberList.add(new ImGroupMember(classGroupTeacherMapper.getUserId().toString()));
                oldTeacher.add(classGroupTeacherMapper.getClassGroupId() + classGroupTeacherMapper.getTeacherRole().getCode() + classGroupTeacherMapper.getUserId());
            }
            if (imGroupMemberList.size() > 0) {
                ImGroupMember[] imGroupMembers = imGroupMemberList.toArray(new ImGroupMember[imGroupMemberList.size()]);
                imFeignService.groupQuit(new ImGroupModel(classGroup.getId().toString(), imGroupMembers, classGroup.getName()));
            }
            // 新设置的老师加入群组
            imGroupMemberList.clear();
            for (ClassGroupTeacherMapper classGroupTeacherMapper : classGroupTeacherMapperList) {
                if (!classGroup.getId().equals(classGroupTeacherMapper.getClassGroupId())) continue;
                classGroupTeacherMapper.setMusicGroupId(classGroup.getMusicGroupId());
                classGroupTeacherMapper.setGroupType(classGroup.getGroupType());
                imGroupMemberList.add(new ImGroupMember(classGroupTeacherMapper.getUserId().toString()));
                newTeacher.add(classGroupTeacherMapper.getClassGroupId() + classGroupTeacherMapper.getTeacherRole().getCode() + classGroupTeacherMapper.getUserId());
            }
            ImGroupMember[] imGroupMembers = imGroupMemberList.toArray(new ImGroupMember[imGroupMemberList.size()]);
            imFeignService.groupJoin(new ImGroupModel(classGroup.getId().toString(), imGroupMembers, classGroup.getName()));
        }
        classGroupTeacherMapperDao.delMusicGroupTeacherMapper(classGroupTeacherMapperList);

        //老师不相同删除老师未开始的课程
        if (checkCourser && (oldTeacher.size() != newTeacher.size() || !newTeacher.containsAll(oldTeacher))) {
            String musicGroupId = classGroupTeacherMapperList.get(0).getMusicGroupId();
            List<CourseSchedule> musicGroupCourseSchedules = courseScheduleDao.findMusicGroupCourseSchedules(musicGroupId, GroupType.MUSIC.getCode(), CourseStatusEnum.NOT_START.getCode());
            if (musicGroupCourseSchedules != null && musicGroupCourseSchedules.size() > 0) {
                courseScheduleService.batchDeleteMusicGroupNotStartCourse(musicGroupId, GroupType.MUSIC);
            }
        }

        return classGroupTeacherMapperDao.classGroupTeachersInsert(classGroupTeacherMapperList);
    }


    @Override
    public List<ClassGroupTeacherMapper> findClassGroupTeachers(List<ClassGroupTeachersDto> ClassGroupList) {
        Set<Integer> collect = ClassGroupList.stream().map(ClassGroupTeachersDto::getId).collect(Collectors.toSet());
        return classGroupTeacherMapperDao.findClassGroupTeachers(StringUtils.join(collect, ","));
    }

    public boolean classGroupTeacherMapperUpdate(List<ClassGroupTeacherMapper> classGroupTeacherMapperList) {
        Date date = new Date();
        Date entryDate = DateUtil.stringToDate(sysConfigDao.findByParamName(SysConfigService.TEACHER_ENTRY_DATE).getParanValue(), "yyyy-MM-dd");
        List<Integer> classGroupIds = classGroupTeacherMapperList.stream().map(classGroupTeacherMapper -> classGroupTeacherMapper.getClassGroupId()).collect(Collectors.toList());

        List<CourseSchedule> classGroupNoStartCourseSchedules = courseScheduleService.findClassGroupNoStartCourseSchedules(classGroupIds, GroupType.MUSIC);

        if (classGroupNoStartCourseSchedules == null || classGroupNoStartCourseSchedules.size() == 0) {
            return true;
        }

        //老师默认的课酬
        List<Integer> teacherUserIds = classGroupTeacherMapperList.stream().map(teacher -> teacher.getUserId()).collect(Collectors.toList());
        List<TeacherDefaultMusicGroupSalary> teacherSalaryList = teacherDefaultMusicGroupSalaryDao.findByTeacher(teacherUserIds);
        Map<String, TeacherDefaultMusicGroupSalary> teacherDefaultSalary = new HashMap<>();
        if (teacherSalaryList.size() > 0) {
            teacherDefaultSalary = teacherSalaryList.stream().collect(Collectors.toMap(teacherDefaultMusicGroupSalary -> teacherDefaultMusicGroupSalary.getCourseScheduleType().getCode() + teacherDefaultMusicGroupSalary.getUserId(), teacherDefaultMusicGroupSalary -> teacherDefaultMusicGroupSalary));
        }
        List<CourseScheduleTeacherSalary> courseScheduleTeacherSalaryList = new ArrayList<>();
        String musicGroupId = classGroupTeacherMapperList.get(0).getMusicGroupId();
        MusicGroup musicGroup = musicGroupService.get(musicGroupId);

        //所有教师列表
        List<Teacher> teachers = teacherDao.findByTeacherIds(teacherUserIds);
        Map<Integer, Teacher> teacherMap = teachers.stream()
                .collect(Collectors.toMap(Teacher::getId, teacher -> teacher));

        //删除未开始的课程老师课酬，和签到
        List<Long> courseScheduleIds = classGroupNoStartCourseSchedules.stream().map(CourseSchedule::getId).collect(Collectors.toList());
        courseScheduleTeacherSalaryDao.batchDeleteByCourseScheduleIds(courseScheduleIds);
        teacherAttendanceDao.batchDeleteByCourseSchedules(courseScheduleIds);

        for (CourseSchedule classGroupNoStartCourseSchedule : classGroupNoStartCourseSchedules) {
            //课时长度
            int duration = DateUtil.minutesBetween(classGroupNoStartCourseSchedule.getStartClassTime(), classGroupNoStartCourseSchedule.getEndClassTime());
            for (ClassGroupTeacherMapper classGroupTeacherMapper : classGroupTeacherMapperList) {
                if (!classGroupTeacherMapper.getClassGroupId().equals(classGroupNoStartCourseSchedule.getClassGroupId())) {
                    continue;
                }
                BigDecimal salary;
                List<TeacherDefaultMusicGroupSalary> teacherDefaultMusicGroupSalaryList = classGroupTeacherMapper.getTeacherDefaultMusicGroupSalaryList();

                Map<CourseSchedule.CourseScheduleType, TeacherDefaultMusicGroupSalary> collect = teacherDefaultMusicGroupSalaryList.stream().collect(Collectors.toMap(TeacherDefaultMusicGroupSalary::getCourseScheduleType, teacherDefaultMusicGroupSalary -> teacherDefaultMusicGroupSalary));

                TeacherDefaultMusicGroupSalary teacherDefaultMusicGroupSalary = collect.get(classGroupNoStartCourseSchedule.getType());
                if (teacherDefaultMusicGroupSalary == null) {
                    teacherDefaultMusicGroupSalary = teacherDefaultSalary.get(classGroupNoStartCourseSchedule.getType().getCode() + classGroupTeacherMapper.getUserId());
                }
                if (teacherDefaultMusicGroupSalary == null) {
                    Teacher teacher = teacherMap.get(classGroupTeacherMapper.getUserId());
                    throw new BizException("请设置"+teacher.getRealName()+"老师"+classGroupNoStartCourseSchedule.getType().getMsg()+"默认课酬");
                }

                //对应基准课酬
                BigDecimal baseSalary = new BigDecimal(0), classTimeDuty = new BigDecimal(0);

                Teacher teacher = teacherMap.get(classGroupTeacherMapper.getUserId());
                SalarySettlementTypeEnum settlementType = musicGroup.getSettlementType();
                if (Objects.nonNull(teacher.getEntryDate())
                        && (teacher.getEntryDate().after(entryDate) || teacher.getEntryDate().getTime() == entryDate.getTime())) {
                    settlementType = SalarySettlementTypeEnum.GRADIENT_SALARY;
                }


                //2.0课酬
                if (settlementType.equals(SalarySettlementTypeEnum.TEACHER_DEFAULT)) {
                    //课程时长与结算单位时长占比
                    classTimeDuty = new BigDecimal(duration).divide(new BigDecimal(30), CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN);
                    baseSalary = classGroupTeacherMapper.getTeacherRole().equals(TeachTypeEnum.BISHOP) ? teacherDefaultMusicGroupSalary.getMainTeacher30MinSalary() : teacherDefaultMusicGroupSalary.getAssistantTeacher30MinSalary();
                }
                //3.0课酬
                if (settlementType.equals(SalarySettlementTypeEnum.GRADIENT_SALARY)) {
                    //课程时长与结算单位时长占比
                    classTimeDuty = new BigDecimal(duration).divide(new BigDecimal(90), CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN);
                    baseSalary = classGroupTeacherMapper.getTeacherRole().equals(TeachTypeEnum.BISHOP) ? teacherDefaultMusicGroupSalary.getMainTeacher90MinSalary() : teacherDefaultMusicGroupSalary.getAssistantTeacher90MinSalary();
                }

                //课堂课课酬改为按分钟数计算，并且时长占比向下取整
                if (musicGroup.isClassroomLessons() || classGroupNoStartCourseSchedule.getType().equals(CourseSchedule.CourseScheduleType.CLASSROOM)){
                    baseSalary = classGroupTeacherMapper.getTeacherRole().equals(TeachTypeEnum.BISHOP) ? teacherDefaultMusicGroupSalary.getMainTeacher30MinSalary() : teacherDefaultMusicGroupSalary.getAssistantTeacher30MinSalary();
                    classTimeDuty = new BigDecimal(duration).divide(new BigDecimal(40), BigDecimal.ZERO.intValue(), BigDecimal.ROUND_DOWN);
                }

                salary = baseSalary.multiply(classTimeDuty).setScale(CommonConstants.DECIMAL_FINAL_PLACE, BigDecimal.ROUND_HALF_UP);

                //课堂课课酬
//                if (musicGroup.isClassroomLessons() || classGroupNoStartCourseSchedule.getType().equals(CourseSchedule.CourseScheduleType.CLASSROOM)) {
//                    salary = classGroupTeacherMapper.getTeacherRole().equals(TeachTypeEnum.BISHOP) ? teacherDefaultMusicGroupSalary.getMainTeacher30MinSalary() : teacherDefaultMusicGroupSalary.getAssistantTeacher30MinSalary();
//                }
                //基础技能提高课
                if (classGroupNoStartCourseSchedule.getType().equals(CourseSchedule.CourseScheduleType.HIGH)) {
                    salary = classGroupTeacherMapper.getTeacherRole().equals(TeachTypeEnum.BISHOP) ? teacherDefaultMusicGroupSalary.getMainTeacher30MinSalary() : teacherDefaultMusicGroupSalary.getAssistantTeacher30MinSalary();
                    if (settlementType.equals(SalarySettlementTypeEnum.GRADIENT_SALARY)) {
                        salary = classGroupTeacherMapper.getTeacherRole().equals(TeachTypeEnum.BISHOP) ? teacherDefaultMusicGroupSalary.getMainTeacher90MinSalary() : teacherDefaultMusicGroupSalary.getAssistantTeacher90MinSalary();
                    }
                }
				if (classGroupNoStartCourseSchedule.getType().equals(CourseSchedule.CourseScheduleType.HIGH_ONLINE)
						|| classGroupNoStartCourseSchedule.getType().equals(CourseSchedule.CourseScheduleType.MUSIC_NETWORK)) {
					if (StringUtils.isBlank(teacherDefaultMusicGroupSalary.getSalaryRuleJson())) {
						throw new BizException("请设置老师默认课酬");
					}
				}
                //线上小班课
                if (classGroupNoStartCourseSchedule.getType().equals(CourseSchedule.CourseScheduleType.HIGH_ONLINE)) {
                    Integer studentNum = classGroupStudentMapperDao.countClassGroupNormalStudentNum(classGroupTeacherMapper.getClassGroupId());
                    if (studentNum < 3 || studentNum > 5) {
                        ClassGroup classGroup = classGroupService.get(classGroupTeacherMapper.getClassGroupId());
                        String numWaring = studentNum < 3 ? "人数不能小于3," : "人数不能大于5,";
                        throw new BizException(classGroup.getName() + numWaring + "请调整");
                    }
                    salary = JSON.parseObject(teacherDefaultMusicGroupSalary.getSalaryRuleJson()).getBigDecimal(studentNum.toString());
                }

                if (classGroupNoStartCourseSchedule.getType().equals(CourseSchedule.CourseScheduleType.MUSIC_NETWORK)) {
                    salary = JSON.parseObject(teacherDefaultMusicGroupSalary.getSalaryRuleJson()).getBigDecimal("1");
                }

                //课程与老师薪水表
                CourseScheduleTeacherSalary courseScheduleTeacherSalary = new CourseScheduleTeacherSalary();
                courseScheduleTeacherSalary.setCourseScheduleId(classGroupNoStartCourseSchedule.getId());
                courseScheduleTeacherSalary.setGroupType(classGroupNoStartCourseSchedule.getGroupType());
                courseScheduleTeacherSalary.setMusicGroupId(classGroupNoStartCourseSchedule.getMusicGroupId());
                courseScheduleTeacherSalary.setTeacherRole(classGroupTeacherMapper.getTeacherRole());
                courseScheduleTeacherSalary.setUserId(classGroupTeacherMapper.getUserId());
                courseScheduleTeacherSalary.setExpectSalary(salary);
                courseScheduleTeacherSalary.setCreateTime(date);
                courseScheduleTeacherSalary.setUpdateTime(date);
                courseScheduleTeacherSalary.setClassGroupId(classGroupTeacherMapper.getClassGroupId());
                courseScheduleTeacherSalaryList.add(courseScheduleTeacherSalary);
            }
        }
        courseScheduleTeacherSalaryService.batchInsert(courseScheduleTeacherSalaryList);
        return true;
    }

    @Override
    public void createMusicGroupTeacherMapper(List<CourseSchedule> courseSchedules, String musicGroupId) {
        Date date = new Date();
        MusicGroup musicGroup = musicGroupService.get(musicGroupId);
        Date entryDate = DateUtil.stringToDate(sysConfigDao.findByParamName(SysConfigService.TEACHER_ENTRY_DATE).getParanValue(), "yyyy-MM-dd");
        List<Integer> teacherUserIds = courseSchedules.stream()
                .map(CourseSchedule::getActualTeacherId)
                .collect(Collectors.toList());
        //所有教师列表
        List<Teacher> teachers = teacherDao.findByTeacherIds(teacherUserIds);
        Map<Integer, Teacher> teacherMap = teachers.stream()
                .collect(Collectors.toMap(Teacher::getId, teacher -> teacher));

        //老师默认的课酬
//        Map<String, TeacherDefaultMusicGroupSalary> teacherDefaultSalary = new HashMap<>();
        for (CourseSchedule classGroupNoStartCourseSchedule : courseSchedules) {
            List<CourseScheduleTeacherSalary> courseScheduleTeacherSalaryList = new ArrayList<>();
            List<TeacherAttendance> teacherAttendances = new ArrayList<>();

            //课时长度
            int duration = DateUtil.minutesBetween(classGroupNoStartCourseSchedule.getStartClassTime(), classGroupNoStartCourseSchedule.getEndClassTime());
            List<ClassGroupTeacherMapper> byClassGroup = classGroupTeacherMapperDao.findByClassGroup(classGroupNoStartCourseSchedule.getClassGroupId());
            for (ClassGroupTeacherMapper classGroupTeacherMapper : byClassGroup) {
                if (!classGroupTeacherMapper.getClassGroupId().equals(classGroupNoStartCourseSchedule.getClassGroupId())) {
                    continue;
                }
                BigDecimal salary = new BigDecimal("0");

                TeacherDefaultMusicGroupSalary teacherDefaultMusicGroupSalary = teacherDefaultMusicGroupSalaryDao.findByTeacherAndCourseType(classGroupTeacherMapper.getUserId(),
                        classGroupNoStartCourseSchedule.getType().getCode());

                if (teacherDefaultMusicGroupSalary == null) {
                    throw new BizException("请先设置老师课酬");
                }

                //对应基准课酬
                BigDecimal baseSalary = new BigDecimal(0), classTimeDuty = new BigDecimal(0);

                Teacher teacher = teacherMap.get(classGroupTeacherMapper.getUserId());
                SalarySettlementTypeEnum settlementType = musicGroup.getSettlementType();
                if (Objects.nonNull(teacher.getEntryDate())
                        && (teacher.getEntryDate().after(entryDate) || teacher.getEntryDate().getTime() == entryDate.getTime())) {
                    settlementType = SalarySettlementTypeEnum.GRADIENT_SALARY;
                }


                //2.0课酬
                if (settlementType.equals(SalarySettlementTypeEnum.TEACHER_DEFAULT)) {
                    //课程时长与结算单位时长占比
                    classTimeDuty = new BigDecimal(duration).divide(new BigDecimal(30), CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN);
                    baseSalary = classGroupTeacherMapper.getTeacherRole().equals(TeachTypeEnum.BISHOP) ? teacherDefaultMusicGroupSalary.getMainTeacher30MinSalary() : teacherDefaultMusicGroupSalary.getAssistantTeacher30MinSalary();
                }
                //3.0课酬
                if (settlementType.equals(SalarySettlementTypeEnum.GRADIENT_SALARY)) {
                    //课程时长与结算单位时长占比
                    classTimeDuty = new BigDecimal(duration).divide(new BigDecimal(90), CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN);
                    baseSalary = classGroupTeacherMapper.getTeacherRole().equals(TeachTypeEnum.BISHOP) ? teacherDefaultMusicGroupSalary.getMainTeacher90MinSalary() : teacherDefaultMusicGroupSalary.getAssistantTeacher90MinSalary();
                }

                //课堂课课酬改为按分钟数计算，并且时长占比向下取整
                if (musicGroup.isClassroomLessons() || classGroupNoStartCourseSchedule.getType().equals(CourseSchedule.CourseScheduleType.CLASSROOM)){
                    baseSalary = classGroupTeacherMapper.getTeacherRole().equals(TeachTypeEnum.BISHOP) ? teacherDefaultMusicGroupSalary.getMainTeacher30MinSalary() : teacherDefaultMusicGroupSalary.getAssistantTeacher30MinSalary();
                    classTimeDuty = new BigDecimal(duration).divide(new BigDecimal(40), BigDecimal.ZERO.intValue(), BigDecimal.ROUND_DOWN);
                }

                //课堂课课酬
//                if (musicGroup.isClassroomLessons()) {
//                    salary = classGroupTeacherMapper.getTeacherRole().equals(TeachTypeEnum.BISHOP) ? teacherDefaultMusicGroupSalary.getMainTeacher30MinSalary() : teacherDefaultMusicGroupSalary.getAssistantTeacher30MinSalary();
//                }
                //基础技能提高课
                if (classGroupNoStartCourseSchedule.getType().equals(CourseSchedule.CourseScheduleType.HIGH)) {
                    salary = classGroupTeacherMapper.getTeacherRole().equals(TeachTypeEnum.BISHOP) ? teacherDefaultMusicGroupSalary.getMainTeacher30MinSalary() : teacherDefaultMusicGroupSalary.getAssistantTeacher30MinSalary();
                    if (settlementType.equals(SalarySettlementTypeEnum.GRADIENT_SALARY)) {
                        salary = classGroupTeacherMapper.getTeacherRole().equals(TeachTypeEnum.BISHOP) ? teacherDefaultMusicGroupSalary.getMainTeacher90MinSalary() : teacherDefaultMusicGroupSalary.getAssistantTeacher90MinSalary();
                    }
                }
                //线上小班课
                if (classGroupNoStartCourseSchedule.getType().equals(CourseSchedule.CourseScheduleType.HIGH_ONLINE)) {
                    Integer studentNum = classGroupStudentMapperDao.countClassGroupNormalStudentNum(classGroupTeacherMapper.getClassGroupId());
                    if (studentNum < 3 || studentNum > 5) {
                        ClassGroup classGroup = classGroupService.get(classGroupTeacherMapper.getClassGroupId());
                        String numWaring = studentNum < 3 ? "人数不能小于3," : "人数不能大于5,";
                        throw new BizException(classGroup.getName() + numWaring + "请调整");
                    }
                    salary = JSON.parseObject(teacherDefaultMusicGroupSalary.getSalaryRuleJson()).getBigDecimal(studentNum.toString());
                }

                if (classGroupNoStartCourseSchedule.getType().equals(CourseSchedule.CourseScheduleType.MUSIC_NETWORK)) {
                    salary = JSON.parseObject(teacherDefaultMusicGroupSalary.getSalaryRuleJson()).getBigDecimal("1");
                }

                //课程与老师薪水表
                CourseScheduleTeacherSalary courseScheduleTeacherSalary = new CourseScheduleTeacherSalary();
                courseScheduleTeacherSalary.setCourseScheduleId(classGroupNoStartCourseSchedule.getId());
                courseScheduleTeacherSalary.setGroupType(classGroupNoStartCourseSchedule.getGroupType());
                courseScheduleTeacherSalary.setMusicGroupId(classGroupNoStartCourseSchedule.getMusicGroupId());
                courseScheduleTeacherSalary.setTeacherRole(classGroupTeacherMapper.getTeacherRole());
                courseScheduleTeacherSalary.setUserId(classGroupTeacherMapper.getUserId());
                courseScheduleTeacherSalary.setExpectSalary(salary);
                courseScheduleTeacherSalary.setCreateTime(date);
                courseScheduleTeacherSalary.setUpdateTime(date);
                courseScheduleTeacherSalary.setClassGroupId(classGroupTeacherMapper.getClassGroupId());
                courseScheduleTeacherSalaryList.add(courseScheduleTeacherSalary);

                TeacherAttendance teacherAttendance = new TeacherAttendance();
                teacherAttendance.setMusicGroupId(courseScheduleTeacherSalary.getMusicGroupId());
                teacherAttendance.setTeacherId(classGroupTeacherMapper.getUserId());
                teacherAttendance.setClassGroupId(classGroupTeacherMapper.getClassGroupId());
                teacherAttendance.setGroupType(courseScheduleTeacherSalary.getGroupType());
                teacherAttendance.setCourseScheduleId(courseScheduleTeacherSalary.getCourseScheduleId());
                teacherAttendance.setCreateTime(date);
                teacherAttendances.add(teacherAttendance);
            }
            courseScheduleTeacherSalaryDao.batchInsert(courseScheduleTeacherSalaryList);
            teacherAttendanceDao.batchInsert(teacherAttendances);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createCourseScheduleTeacherSalary(List<CourseSchedule> courseSchedules, Map<Long, CourseSchedule> oldCourseSchedules) {
        List<CourseScheduleTeacherSalary> courseScheduleTeacherSalaryList = new ArrayList<>();
        Date entryDate = DateUtil.stringToDate(sysConfigDao.findByParamName(SysConfigService.TEACHER_ENTRY_DATE).getParanValue(), "yyyy-MM-dd");

        //课程编号列表
        List<Long> courseScheduleIds = courseSchedules.stream().map(CourseSchedule::getId).collect(Collectors.toList());
        //主教老师列表
        List<Integer> allTeacherIds = courseSchedules.stream().map(courseSchedule -> courseSchedule.getActualTeacherId().intValue()).collect(Collectors.toList());
        //助教老师列表
        List<Integer> teachingTeacherIds = new ArrayList<>();
        courseSchedules.forEach(courseSchedule -> {
            if (Objects.nonNull(courseSchedule.getTeachingTeacherIdList())) {
                teachingTeacherIds.addAll(courseSchedule.getTeachingTeacherIdList());
            }
        });
        allTeacherIds.addAll(teachingTeacherIds);
        //所有老师列表
        allTeacherIds = allTeacherIds.stream().distinct().collect(Collectors.toList());

        //所有教师列表
        List<Teacher> teachers = teacherDao.findByTeacherIds(allTeacherIds);
        Map<Integer, Teacher> teacherMap = teachers.stream()
                .collect(Collectors.toMap(Teacher::getId, teacher -> teacher));

        //所有老师默认乐团课酬
        List<TeacherDefaultMusicGroupSalary> teacherDefaultMusicGroupSalaries = teacherDefaultMusicGroupSalaryDao.findByTeacher(allTeacherIds);
        Map<CourseSchedule.CourseScheduleType, List<TeacherDefaultMusicGroupSalary>> teacherDefaultMusicGroupSalariesGroupByCourseType = teacherDefaultMusicGroupSalaries.stream().collect(Collectors.groupingBy(TeacherDefaultMusicGroupSalary::getCourseScheduleType));

        //获取课程对应教学点补贴
        List<Map<Long, BigDecimal>> courseSubsidyByCourses = courseScheduleTeacherSalaryDao.findCourseSubsidyByCourses(courseScheduleIds);
        Map<Integer, BigDecimal> courseSubsidyMap = MapUtil.convertIntegerMap(courseSubsidyByCourses);

        //课程对应乐团结算方式集合
        List<Map<String, String>> musicGroupSettlementTypeByCourse = courseScheduleTeacherSalaryDao.findMusicGroupSettlementTypeByCourse(courseScheduleIds);
        Map<String, String> musicGroupSettlementsMap = MapUtil.convertMybatisMap(musicGroupSettlementTypeByCourse);

        for (CourseSchedule courseSchedule : courseSchedules) {
            if (Objects.isNull(courseSchedule.getType())) {
                courseSchedule.setType(oldCourseSchedules.get(courseSchedule.getId()).getType());
            }

            //获取结算方式
            String settlementType = musicGroupSettlementsMap.get(courseSchedule.getId());
            if (StringUtils.isBlank(settlementType)) {
                throw new BizException("存在未指定结算方式的课程");
            }

            //根据课程类型获取对应的默认课酬设置列表
            List<TeacherDefaultMusicGroupSalary> teacherDefaultMusicGroupSalariesWithCourseType = teacherDefaultMusicGroupSalariesGroupByCourseType.get(courseSchedule.getType());
            if (CollectionUtils.isEmpty(teacherDefaultMusicGroupSalariesWithCourseType)) {
                throw new BizException("存在未指定结算方式的课程类型");
            }

            //根据教师编号将对应结算方式下的默认课酬设置分组
            Map<Integer, TeacherDefaultMusicGroupSalary> teacherDefaultMusicGroupSalariesGroupByTeacherId = teacherDefaultMusicGroupSalariesWithCourseType.stream().collect(Collectors.toMap(TeacherDefaultMusicGroupSalary::getUserId, teacherDefaultMusicGroupSalary -> teacherDefaultMusicGroupSalary));

            if (!courseSchedule.isBishopTeacherSalaryNotCreate()) {
                Teacher teacher = teacherMap.get(courseSchedule.getActualTeacherId());
                if (Objects.nonNull(teacher.getEntryDate())
                        && (teacher.getEntryDate().after(entryDate) || teacher.getEntryDate().getTime() == entryDate.getTime())) {
                    settlementType = SalarySettlementTypeEnum.GRADIENT_SALARY.getCode();
                }

                //根据课程获取主教的默认课酬设置列表
                TeacherDefaultMusicGroupSalary teacherDefaultMusicGroupSalaryWithTeacherId = teacherDefaultMusicGroupSalariesGroupByTeacherId.get(courseSchedule.getActualTeacherId());
                courseScheduleTeacherSalaryList.add(countMusicGroupTeacherSalary(
                        courseSchedule,
                        TeachTypeEnum.BISHOP,
                        settlementType,
                        courseSubsidyMap.get(courseSchedule.getId()),
                        courseSchedule.getActualTeacherId().intValue(),
                        teacherDefaultMusicGroupSalaryWithTeacherId));
            }

            //计算助教课程薪酬
            //助教编号列表
            List<Integer> teachingTeacherIdList = courseSchedule.getTeachingTeacherIdList();
            if (CollectionUtils.isEmpty(teachingTeacherIdList)) {
                return;
            }
            for (Integer teacherId : teachingTeacherIdList) {
                if (Objects.isNull(teacherId)) {
                    return;
                }
                Teacher teacher = teacherMap.get(teacherId);
                if (Objects.nonNull(teacher.getEntryDate())
                        && (teacher.getEntryDate().after(entryDate) || teacher.getEntryDate().getTime() == entryDate.getTime())) {
                    settlementType = SalarySettlementTypeEnum.GRADIENT_SALARY.getCode();
                }
                TeacherDefaultMusicGroupSalary teacherDefaultMusicGroupSalaryWithTeacherId = teacherDefaultMusicGroupSalariesGroupByTeacherId.get(teacherId);
                courseScheduleTeacherSalaryList.add(countMusicGroupTeacherSalary(
                        courseSchedule,
                        TeachTypeEnum.TEACHING,
                        settlementType,
                        courseSubsidyMap.get(courseSchedule.getId()),
                        teacherId,
                        teacherDefaultMusicGroupSalaryWithTeacherId));
            }
        }
        if (!CollectionUtils.isEmpty(courseScheduleTeacherSalaryList)) {
            courseScheduleTeacherSalaryService.batchInsert(courseScheduleTeacherSalaryList);
        }
    }

    @Override
    public void initCourseScheduleTeacherSalary(List<CourseSchedule> courseSchedules, List<ClassGroupTeacherMapper> classGroupTeacherMapperList) {
        List<Long> courseScheduleIds = courseSchedules.stream().map(CourseSchedule::getId).collect(Collectors.toList());
        courseScheduleTeacherSalaryDao.batchDeleteByCourseScheduleIds(courseScheduleIds);
        List<CourseScheduleTeacherSalary> courseScheduleTeacherSalaryList = new ArrayList<>();
        Date date=new Date();
        for (CourseSchedule classGroupNoStartCourseSchedule : courseSchedules) {
            for (ClassGroupTeacherMapper classGroupTeacherMapper : classGroupTeacherMapperList) {
                //课程与老师薪水表
                CourseScheduleTeacherSalary courseScheduleTeacherSalary = new CourseScheduleTeacherSalary();
                courseScheduleTeacherSalary.setCourseScheduleId(classGroupNoStartCourseSchedule.getId());
                courseScheduleTeacherSalary.setGroupType(classGroupNoStartCourseSchedule.getGroupType());
                courseScheduleTeacherSalary.setMusicGroupId(classGroupNoStartCourseSchedule.getMusicGroupId());
                courseScheduleTeacherSalary.setTeacherRole(classGroupTeacherMapper.getTeacherRole());
                courseScheduleTeacherSalary.setUserId(classGroupTeacherMapper.getUserId());
                courseScheduleTeacherSalary.setExpectSalary(BigDecimal.ZERO);
                courseScheduleTeacherSalary.setCreateTime(date);
                courseScheduleTeacherSalary.setUpdateTime(date);
                courseScheduleTeacherSalary.setClassGroupId(classGroupTeacherMapper.getClassGroupId());
                courseScheduleTeacherSalaryList.add(courseScheduleTeacherSalary);
            }
        }
        courseScheduleTeacherSalaryService.batchInsert(courseScheduleTeacherSalaryList);
    }

    /**
     * @param courseSchedule:                              课程信息
     * @param teachType:                                   教师类型
     * @param settlementType:                              结算方式
     * @param subsidy:                                     补贴
     * @param teacherId:                                   教师编号
     * @param teacherDefaultMusicGroupSalaryWithTeacherId: 教师课酬
     * @return com.ym.mec.biz.dal.entity.CourseScheduleTeacherSalary
     * @describe 计算教师课酬
     * @author Joburgess
     * @date 2019/10/24
     */
    private CourseScheduleTeacherSalary countMusicGroupTeacherSalary(CourseSchedule courseSchedule,
                                                                     TeachTypeEnum teachType,
                                                                     String settlementType,
                                                                     BigDecimal subsidy,
                                                                     Integer teacherId,
                                                                     TeacherDefaultMusicGroupSalary teacherDefaultMusicGroupSalaryWithTeacherId) {
        if (Objects.isNull(teacherDefaultMusicGroupSalaryWithTeacherId)) {
            throw new BizException("存在未设置默认课酬的教师");
        }
        //教师课酬
        BigDecimal teacherSalary = new BigDecimal(0);

        //课时长度
        int duration = DateUtil.minutesBetween(courseSchedule.getStartClassTime(), courseSchedule.getEndClassTime());

        BigDecimal teacherDefaultSalary = BigDecimal.ZERO;
        BigDecimal baseTime = BigDecimal.ZERO;

        //如果结算方式是教师默认课酬
        if (settlementType.equals(SalarySettlementTypeEnum.TEACHER_DEFAULT.getCode())) {
             baseTime = new BigDecimal(30);
            teacherDefaultSalary = teachType == TeachTypeEnum.BISHOP ? teacherDefaultMusicGroupSalaryWithTeacherId.getMainTeacher30MinSalary() : teacherDefaultMusicGroupSalaryWithTeacherId.getAssistantTeacher30MinSalary();
        } else if (settlementType.equals(SalarySettlementTypeEnum.GRADIENT_SALARY.getCode())) {
            teacherDefaultSalary = teachType == TeachTypeEnum.BISHOP ? teacherDefaultMusicGroupSalaryWithTeacherId.getMainTeacher90MinSalary() : teacherDefaultMusicGroupSalaryWithTeacherId.getAssistantTeacher90MinSalary();
            baseTime = new BigDecimal(90);
        }
        if (courseSchedule.getType().equals(CourseSchedule.CourseScheduleType.HIGH)) {
            baseTime = new BigDecimal(45);
        }else if (courseSchedule.getType().equals(CourseSchedule.CourseScheduleType.CLASSROOM)) {
            baseTime = new BigDecimal(40);
            teacherDefaultSalary = teachType == TeachTypeEnum.BISHOP ? teacherDefaultMusicGroupSalaryWithTeacherId.getMainTeacher30MinSalary() : teacherDefaultMusicGroupSalaryWithTeacherId.getAssistantTeacher30MinSalary();
        }
        //课程时长与结算单位时长占比
        BigDecimal classTimeDuty = new BigDecimal(duration).divide(baseTime, CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN);

        //课堂课课酬改为按分钟数计算，并且时长占比向下取整
        if (courseSchedule.getType().equals(CourseSchedule.CourseScheduleType.CLASSROOM)){
            teacherDefaultSalary = teachType.equals(TeachTypeEnum.BISHOP) ? teacherDefaultMusicGroupSalaryWithTeacherId.getMainTeacher30MinSalary() : teacherDefaultMusicGroupSalaryWithTeacherId.getAssistantTeacher30MinSalary();
            classTimeDuty = new BigDecimal(duration).divide(new BigDecimal(40), BigDecimal.ZERO.intValue(), BigDecimal.ROUND_DOWN);
        }
        teacherSalary = teacherDefaultSalary.multiply(classTimeDuty).setScale(2, BigDecimal.ROUND_HALF_UP);

        //课堂课课酬
//        if (courseSchedule.getType().equals(CourseSchedule.CourseScheduleType.CLASSROOM)) {
//            teacherSalary = teachType.equals(TeachTypeEnum.BISHOP) ? teacherDefaultMusicGroupSalaryWithTeacherId.getMainTeacher30MinSalary() : teacherDefaultMusicGroupSalaryWithTeacherId.getAssistantTeacher30MinSalary();
//        }
        //基础技能提高课
        if (courseSchedule.getType().equals(CourseSchedule.CourseScheduleType.HIGH)) {
            teacherSalary = teachType.equals(TeachTypeEnum.BISHOP) ? teacherDefaultMusicGroupSalaryWithTeacherId.getMainTeacher30MinSalary() : teacherDefaultMusicGroupSalaryWithTeacherId.getAssistantTeacher30MinSalary();
            if (settlementType.equals(SalarySettlementTypeEnum.GRADIENT_SALARY)) {
                teacherSalary = teachType.equals(TeachTypeEnum.BISHOP) ? teacherDefaultMusicGroupSalaryWithTeacherId.getMainTeacher90MinSalary() : teacherDefaultMusicGroupSalaryWithTeacherId.getAssistantTeacher90MinSalary();
            }
        }
        //线上小班课
        if (courseSchedule.getType().equals(CourseSchedule.CourseScheduleType.HIGH_ONLINE)) {
            Integer studentNum = classGroupStudentMapperDao.countClassGroupNormalStudentNum(courseSchedule.getClassGroupId());
            if (studentNum < 3 || studentNum > 5) {
                ClassGroup classGroup = classGroupService.get(courseSchedule.getClassGroupId());
                String numWaring = studentNum < 3 ? "人数不能小于3," : "人数不能大于5,";
                throw new BizException(classGroup.getName() + numWaring + "请调整");
            }
            teacherSalary = JSON.parseObject(teacherDefaultMusicGroupSalaryWithTeacherId.getSalaryRuleJson()).getBigDecimal(studentNum.toString());
        }

        if (courseSchedule.getType().equals(CourseSchedule.CourseScheduleType.MUSIC_NETWORK)) {
            teacherSalary = JSON.parseObject(teacherDefaultMusicGroupSalaryWithTeacherId.getSalaryRuleJson()).getBigDecimal("1");
        }

        CourseScheduleTeacherSalary courseScheduleTeacherSalary = new CourseScheduleTeacherSalary(
                courseSchedule.getId(),
                teachType,
                teacherId,
                teacherSalary,
                subsidy,
                courseSchedule.getClassGroupId());
        courseScheduleTeacherSalary.setGroupType(courseSchedule.getGroupType());
        courseScheduleTeacherSalary.setMusicGroupId(courseSchedule.getMusicGroupId());
        return courseScheduleTeacherSalary;
    }

    public List<ClassGroupTeacherMapper> getClassGroupTeachers(Integer classGroupId) {
        return classGroupTeacherMapperDao.findClassGroupTeachers(classGroupId.toString());
    }

    public ClassGroupTeacherMapper getClassGroupTeachersRole(Integer classGroupId,String teacherRole) {
        return classGroupTeacherMapperDao.getClassGroupTeachersRole(classGroupId,teacherRole);
    }

    @Override
    public void updateTeacher(String groupId, Integer teacherId, String groupType) {
        classGroupTeacherMapperDao.updateTeacher(groupId, teacherId, groupType);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchUpdateTeacherByClassId(List<Integer> classGroupIds, Integer oldTeacherId, Integer newTeacherId) {
        classGroupTeacherMapperDao.batchUpdateTeacherByClassId(classGroupIds,oldTeacherId,newTeacherId);
    }
}
