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 ImGroupMemberService imGroupMemberService;
    @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<Integer> userIdList = new ArrayList<>();
        List<ClassGroup> classGroups = classGroupService.findClassGroupByIds(classGroupIds);

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

        for (ClassGroup classGroup : classGroups) {
            userIdList.clear();
            //原设置的老师删除群组
            for (ClassGroupTeacherMapper classGroupTeacherMapper : oldClassGroupTeacherMapper) {
                if (!classGroup.getId().equals(classGroupTeacherMapper.getClassGroupId())) continue;
                userIdList.add(classGroupTeacherMapper.getUserId());
            }
            if (userIdList.size() > 0) {
                imGroupMemberService.quit(classGroup.getId().longValue(), userIdList);
            }
            // 新设置的老师加入群组
            userIdList.clear();
            for (ClassGroupTeacherMapper classGroupTeacherMapper : classGroupTeacherMapperList) {
                if (!classGroup.getId().equals(classGroupTeacherMapper.getClassGroupId())) continue;
                classGroupTeacherMapper.setMusicGroupId(classGroup.getMusicGroupId());
                classGroupTeacherMapper.setGroupType(classGroup.getGroupType());
                userIdList.add(classGroupTeacherMapper.getUserId());
            }
            if (userIdList.size() > 0) {
            	Map<Integer, String> userRoleMap = new HashMap<Integer, String>();
            	for(Integer userId : userIdList){
            		userRoleMap.put(userId, "指导老师");
            	}
                imGroupMemberService.join(classGroup.getId().longValue(), userRoleMap);
            }
        }
        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<Integer> userIdList = new ArrayList<Integer>();
        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) {
        	userIdList.clear();
            //原设置的老师删除群组
            for (ClassGroupTeacherMapper classGroupTeacherMapper : oldClassGroupTeacherMapper) {
                if (!classGroup.getId().equals(classGroupTeacherMapper.getClassGroupId())) continue;
                userIdList.add(classGroupTeacherMapper.getUserId());
                oldTeacher.add(classGroupTeacherMapper.getClassGroupId() + classGroupTeacherMapper.getTeacherRole().getCode() + classGroupTeacherMapper.getUserId());
            }
            if (userIdList.size() > 0) {
                imGroupMemberService.quit(classGroup.getId().longValue(), userIdList);
            }
            // 新设置的老师加入群组
            userIdList.clear();
            for (ClassGroupTeacherMapper classGroupTeacherMapper : classGroupTeacherMapperList) {
                if (!classGroup.getId().equals(classGroupTeacherMapper.getClassGroupId())) continue;
                classGroupTeacherMapper.setMusicGroupId(classGroup.getMusicGroupId());
                classGroupTeacherMapper.setGroupType(classGroup.getGroupType());
                userIdList.add(classGroupTeacherMapper.getUserId());
                newTeacher.add(classGroupTeacherMapper.getClassGroupId() + classGroupTeacherMapper.getTeacherRole().getCode() + classGroupTeacherMapper.getUserId());
            }
            if (userIdList.size() > 0) {
            	Map<Integer, String> userRoleMap = new HashMap<Integer, String>();
            	for(Integer userId : userIdList){
            		userRoleMap.put(userId, "指导老师");
            	}
                imGroupMemberService.join(classGroup.getId().longValue(), userRoleMap);
            }
        }
        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();
        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<CourseScheduleTeacherSalary> courseScheduleTeacherSalaryList = new ArrayList<>();
        String musicGroupId = classGroupTeacherMapperList.get(0).getMusicGroupId();
        MusicGroup musicGroup = musicGroupService.get(musicGroupId);

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

        for (CourseSchedule classGroupNoStartCourseSchedule : classGroupNoStartCourseSchedules) {
            for (ClassGroupTeacherMapper classGroupTeacherMapper : classGroupTeacherMapperList) {
                if (!classGroupTeacherMapper.getClassGroupId().equals(classGroupNoStartCourseSchedule.getClassGroupId())) {
                    continue;
                }

                //课程与老师薪水表
                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.setCreateTime(date);
                courseScheduleTeacherSalary.setUpdateTime(date);
                courseScheduleTeacherSalary.setClassGroupId(classGroupTeacherMapper.getClassGroupId());
                courseScheduleTeacherSalaryService.createMusicGroupCourseTeacherSalary(musicGroup, classGroupNoStartCourseSchedule, courseScheduleTeacherSalary);
                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);

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

            List<ClassGroupTeacherMapper> byClassGroup = classGroupTeacherMapperDao.findByClassGroup(classGroupNoStartCourseSchedule.getClassGroupId());
            for (ClassGroupTeacherMapper classGroupTeacherMapper : byClassGroup) {
                if (!classGroupTeacherMapper.getClassGroupId().equals(classGroupNoStartCourseSchedule.getClassGroupId())) {
                    continue;
                }

                //课程与老师薪水表
                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.setCreateTime(date);
                courseScheduleTeacherSalary.setUpdateTime(date);
                courseScheduleTeacherSalary.setClassGroupId(classGroupTeacherMapper.getClassGroupId());
                courseScheduleTeacherSalaryService.createMusicGroupCourseTeacherSalary(musicGroup, classGroupNoStartCourseSchedule, courseScheduleTeacherSalary);
                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<>();

        //课程编号列表
        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<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("存在未指定结算方式的课程类型");
            }

            if (!courseSchedule.isBishopTeacherSalaryNotCreate()) {
                CourseScheduleTeacherSalary courseScheduleTeacherSalary = new CourseScheduleTeacherSalary();
                courseScheduleTeacherSalary.setGroupType(courseSchedule.getGroupType());
                courseScheduleTeacherSalary.setMusicGroupId(courseSchedule.getMusicGroupId());
                courseScheduleTeacherSalary.setClassGroupId(courseSchedule.getClassGroupId());
                courseScheduleTeacherSalary.setCourseScheduleId(courseSchedule.getId());
                courseScheduleTeacherSalary.setTeacherRole(TeachTypeEnum.BISHOP);
                courseScheduleTeacherSalary.setUserId(courseSchedule.getActualTeacherId());
                courseScheduleTeacherSalary.setSubsidy(courseSubsidyMap.get(courseSchedule.getId()));
                courseScheduleTeacherSalaryService.createMusicGroupCourseTeacherSalary(null, courseSchedule, courseScheduleTeacherSalary);
                courseScheduleTeacherSalaryList.add(courseScheduleTeacherSalary);
            }

            //计算助教课程薪酬
            //助教编号列表
            List<Integer> teachingTeacherIdList = courseSchedule.getTeachingTeacherIdList();
            if (CollectionUtils.isEmpty(teachingTeacherIdList)) {
                return;
            }
            for (Integer teacherId : teachingTeacherIdList) {
                if (Objects.isNull(teacherId)) {
                    return;
                }
                CourseScheduleTeacherSalary courseScheduleTeacherSalary = new CourseScheduleTeacherSalary();
                courseScheduleTeacherSalary.setGroupType(courseSchedule.getGroupType());
                courseScheduleTeacherSalary.setMusicGroupId(courseSchedule.getMusicGroupId());
                courseScheduleTeacherSalary.setClassGroupId(courseSchedule.getClassGroupId());
                courseScheduleTeacherSalary.setCourseScheduleId(courseSchedule.getId());
                courseScheduleTeacherSalary.setTeacherRole(TeachTypeEnum.TEACHING);
                courseScheduleTeacherSalary.setUserId(teacherId);
                courseScheduleTeacherSalary.setSubsidy(courseSubsidyMap.get(courseSchedule.getId()));
                courseScheduleTeacherSalaryService.createMusicGroupCourseTeacherSalary(null, courseSchedule, courseScheduleTeacherSalary);
                courseScheduleTeacherSalaryList.add(courseScheduleTeacherSalary);
            }
        }
        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);
    }

    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);
    }
}
