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

import java.math.BigDecimal;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.ym.mec.auth.api.client.SysUserFeignService;
import com.ym.mec.auth.api.entity.SysUser;
import com.ym.mec.biz.dal.dao.ClassGroupDao;
import com.ym.mec.biz.dal.dao.ClassGroupStudentMapperDao;
import com.ym.mec.biz.dal.dao.CourseHomeworkDao;
import com.ym.mec.biz.dal.dao.CourseScheduleDao;
import com.ym.mec.biz.dal.dao.CourseScheduleStatisticsDao;
import com.ym.mec.biz.dal.dao.CourseScheduleStudentPaymentDao;
import com.ym.mec.biz.dal.dao.ExtracurricularExercisesReplyDao;
import com.ym.mec.biz.dal.dao.StudentAttendanceDao;
import com.ym.mec.biz.dal.dao.StudentDao;
import com.ym.mec.biz.dal.dao.StudentExtracurricularExercisesSituationDao;
import com.ym.mec.biz.dal.dao.StudentRegistrationDao;
import com.ym.mec.biz.dal.dao.SubjectDao;
import com.ym.mec.biz.dal.dao.TeacherDao;
import com.ym.mec.biz.dal.dao.TeacherRemindDao;
import com.ym.mec.biz.dal.dto.MusicGroupExtracurricularSummaryDto;
import com.ym.mec.biz.dal.dto.SimpleUserDto;
import com.ym.mec.biz.dal.dto.StudentExercisesSituationDto;
import com.ym.mec.biz.dal.dto.StudentServiceDetailDto;
import com.ym.mec.biz.dal.dto.TeacherExercisesServiceDto;
import com.ym.mec.biz.dal.dto.TeacherServeDto;
import com.ym.mec.biz.dal.dto.TeacherServeExtraDto;
import com.ym.mec.biz.dal.dto.TeacherServeHomeworkDto;
import com.ym.mec.biz.dal.dto.TeacherServeHomeworkPojo;
import com.ym.mec.biz.dal.entity.ClassGroup;
import com.ym.mec.biz.dal.entity.CourseHomework;
import com.ym.mec.biz.dal.entity.CourseSchedule;
import com.ym.mec.biz.dal.entity.Student;
import com.ym.mec.biz.dal.entity.StudentExtracurricularExercisesSituation;
import com.ym.mec.biz.dal.entity.Subject;
import com.ym.mec.biz.dal.entity.TeacherRemind;
import com.ym.mec.biz.dal.enums.GroupType;
import com.ym.mec.biz.dal.enums.MessageTypeEnum;
import com.ym.mec.biz.dal.enums.TeacherRemindTypeEnum;
import com.ym.mec.biz.dal.page.ExtraExercilseQueryInfo;
import com.ym.mec.biz.dal.page.StudentExerciseMusicGroupQueryInfo;
import com.ym.mec.biz.dal.page.StudentExercisesSituationQueryInfo;
import com.ym.mec.biz.dal.page.StudentServiceDetailQueryInfo;
import com.ym.mec.biz.dal.page.TeacherServeHomeworkQueryInfo;
import com.ym.mec.biz.dal.page.TeacherServeQueryInfo;
import com.ym.mec.biz.service.StudentExtracurricularExercisesSituationService;
import com.ym.mec.biz.service.SysMessageService;
import com.ym.mec.common.constant.CommonConstants;
import com.ym.mec.common.dal.BaseDAO;
import com.ym.mec.common.exception.BizException;
import com.ym.mec.common.page.PageInfo;
import com.ym.mec.common.service.impl.BaseServiceImpl;
import com.ym.mec.thirdparty.message.MessageSenderPluginContext;
import com.ym.mec.util.collection.MapUtil;
import com.ym.mec.util.date.DateUtil;

@Service
public class StudentExtracurricularExercisesSituationServiceImpl extends BaseServiceImpl<Long, StudentExtracurricularExercisesSituation> implements StudentExtracurricularExercisesSituationService {
	
	@Autowired
	private StudentExtracurricularExercisesSituationDao studentExtracurricularExercisesSituationDao;
	@Autowired
	private ExtracurricularExercisesReplyDao extracurricularExercisesReplyDao;
	@Autowired
	private CourseScheduleDao courseScheduleDao;
	@Autowired
	private TeacherDao teacherDao;
	@Autowired
	private ClassGroupStudentMapperDao classGroupStudentMapperDao;
	@Autowired
	private StudentRegistrationDao studentRegistrationDao;
	@Autowired
	private TeacherRemindDao teacherRemindDao;
	@Autowired
	private SysMessageService sysMessageService;
	@Autowired
	private StudentDao studentDao;
	@Autowired
	private SubjectDao subjectDao;
	@Autowired
	private CourseHomeworkDao courseHomeworkDao;
	@Autowired
	private ClassGroupDao classGroupDao;
	@Autowired
	private StudentAttendanceDao studentAttendanceDao;
	@Autowired
	private CourseScheduleStudentPaymentDao courseScheduleStudentPaymentDao;
	@Autowired
	private SysUserFeignService sysUserFeignService;
	@Autowired
	private CourseScheduleStatisticsDao courseScheduleStatisticsDao;

	@Override
	public BaseDAO<Long, StudentExtracurricularExercisesSituation> getDAO() {
		return studentExtracurricularExercisesSituationDao;
	}

	@Override
	public PageInfo<MusicGroupExtracurricularSummaryDto> queryStudentExerciseMusicGroupList(StudentExerciseMusicGroupQueryInfo queryInfo) {
		PageInfo<MusicGroupExtracurricularSummaryDto> pageInfo = new PageInfo<MusicGroupExtracurricularSummaryDto>(queryInfo.getPage(), queryInfo.getRows());
		Map<String, Object> params = new HashMap<String, Object>();
		MapUtil.populateMap(params, queryInfo);
		
		List<MusicGroupExtracurricularSummaryDto> dataList = null;
		int count = studentExtracurricularExercisesSituationDao.queryStudentExerciseMusicGroupListCount(params);
		if (count > 0) {
			pageInfo.setTotal(count);
			params.put("offset", pageInfo.getOffset());
			dataList = studentExtracurricularExercisesSituationDao.queryStudentExerciseMusicGroupList(params);
		}
		if (count == 0) {
			dataList = new ArrayList<MusicGroupExtracurricularSummaryDto>();
		}
		pageInfo.setRows(dataList);
		return pageInfo;
	}

	@Override
	public PageInfo<StudentExercisesSituationDto> findStudentExtracurricularExercisesSituations(StudentExercisesSituationQueryInfo queryInfo) {
		PageInfo<StudentExercisesSituationDto> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
		Map<String, Object> params = new HashMap<>();
		MapUtil.populateMap(params, queryInfo);

		List<StudentExercisesSituationDto> dataList = null;
		int count = studentExtracurricularExercisesSituationDao.countExercisesSituations(params);
		if (count > 0) {
			pageInfo.setTotal(count);
			params.put("offset", pageInfo.getOffset());
			dataList = studentExtracurricularExercisesSituationDao.findExercisesSituations(params);
			List<Integer> studentIds = dataList.stream().map(StudentExtracurricularExercisesSituation::getStudentId).collect(Collectors.toList());
			List<Map<Integer, Long>> studentVipCoursesMaps = courseScheduleDao.countStudentVipCoursesWithDate(studentIds, queryInfo.getMonday(), queryInfo.getSunday(), GroupType.VIP);
			Map<Integer, Long> studentVipCourseMap = MapUtil.convertIntegerMap(studentVipCoursesMaps);

			List<Map<Integer, Long>> studentPracticeCoursesMaps = courseScheduleDao.countStudentPayPracticeCoursesWithDate(studentIds, queryInfo.getMonday(), queryInfo.getSunday());
			Map<Integer, Long> studentPracticeCourseMap = MapUtil.convertIntegerMap(studentPracticeCoursesMaps);

			/*List<StudentEduTeacherDto> studentEducationalTeachers = classGroupStudentMapperDao.getStudentEducationalTeachers(studentIds);
			Map<Integer, List<StudentEduTeacherDto>> studentEduTeachersMap = studentEducationalTeachers.stream().collect(Collectors.groupingBy(StudentEduTeacherDto::getStudentId));
*/
			/*List<UserGroupDto> allUserGroups = studentRegistrationDao.getUserGroups(studentIds);
			Map<Integer, List<UserGroupDto>> userGroupsMap = new HashMap<>();
			if(!CollectionUtils.isEmpty(allUserGroups)){
				userGroupsMap = allUserGroups.stream().collect(Collectors.groupingBy(UserGroupDto::getUserId));
			}*/

			for (StudentExercisesSituationDto exercisesSituationDto : dataList) {
				Long vipCourses=studentVipCourseMap.get(exercisesSituationDto.getStudentId());
				exercisesSituationDto.setExistVipCourse(Objects.isNull(vipCourses)?0:vipCourses.intValue());
				Long practiceCourses=studentPracticeCourseMap.get(exercisesSituationDto.getStudentId());
				exercisesSituationDto.setExistPracticeCourse(Objects.isNull(practiceCourses)?0:practiceCourses.intValue());
//				exercisesSituationDto.setExpectExercisesNum((int) until+1);
				/*List<UserGroupDto> userGroupDtos = userGroupsMap.get(exercisesSituationDto.getStudentId());
				if(!CollectionUtils.isEmpty(userGroupDtos)){
					exercisesSituationDto.setGroupNames(userGroupDtos.stream().filter(ug->StringUtils.isNotBlank(ug.getGroupName())).map(UserGroupDto::getGroupName).sorted().collect(Collectors.joining(",")));
				}*/
				/*List<StudentEduTeacherDto> studentEduTeachers = studentEduTeachersMap.get(exercisesSituationDto.getStudentId());
				if(!CollectionUtils.isEmpty(studentEduTeachers)){
					List<StudentEduTeacherDto> t1 = studentEduTeachers.stream().filter(set -> set.getGroupType().equals(GroupType.VIP.getCode())||set.getGroupType().equals(GroupType.PRACTICE.getCode())).collect(Collectors.toList());
					if(!CollectionUtils.isEmpty(t1)){
						for (StudentEduTeacherDto studentEduTeacherDto : t1) {
							if(StringUtils.isNotBlank(studentEduTeacherDto.getEducationalTeacherName())){
								exercisesSituationDto.setEducationalTeacherId(studentEduTeacherDto.getEducationalTeacherId());
								exercisesSituationDto.setEducationalTeacherName(studentEduTeacherDto.getEducationalTeacherName());
								break;
							}
						}
					}
					if(StringUtils.isNoneBlank(exercisesSituationDto.getEducationalTeacherName())){
						continue;
					}
					List<StudentEduTeacherDto> t2 = studentEduTeachers.stream().filter(set -> set.getGroupType().equals(GroupType.MUSIC.getCode())).collect(Collectors.toList());
					if(!CollectionUtils.isEmpty(t2)){
						for (StudentEduTeacherDto studentEduTeacherDto : t2) {
							if(StringUtils.isNotBlank(studentEduTeacherDto.getEducationalTeacherName())){
								exercisesSituationDto.setEducationalTeacherId(studentEduTeacherDto.getEducationalTeacherId());
								exercisesSituationDto.setEducationalTeacherName(studentEduTeacherDto.getEducationalTeacherName());
								break;
							}
						}
					}
				}*/
			}
		}
		if (count == 0) {
			dataList = new ArrayList<>();
		}
		pageInfo.setRows(dataList);
		return pageInfo;
	}

	@Override
	public PageInfo<StudentExercisesSituationDto> findServiceStudentSituations(StudentExercisesSituationQueryInfo queryInfo) {
		PageInfo<StudentExercisesSituationDto> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
		Map<String, Object> params = new HashMap<>();
		MapUtil.populateMap(params, queryInfo);

		List<StudentExercisesSituationDto> dataList = null;
		int count = studentExtracurricularExercisesSituationDao.countExercisesSituations(params);
		if (count > 0) {
			pageInfo.setTotal(count);
			params.put("offset", pageInfo.getOffset());
			dataList = studentExtracurricularExercisesSituationDao.findExercisesSituations(params);
			Map<Integer, Long> studentVipCourseMap=new HashMap<>();
			if(Objects.isNull(queryInfo.getExistVipCourse())){
				List<Integer> studentIds = dataList.stream().map(StudentExtracurricularExercisesSituation::getStudentId).collect(Collectors.toList());
				List<Map<Integer, Long>> studentVipCoursesMaps = courseScheduleDao.countStudentVipCoursesWithDate(studentIds, queryInfo.getMonday(), queryInfo.getSunday(),GroupType.VIP);
				studentVipCourseMap = MapUtil.convertIntegerMap(studentVipCoursesMaps);
			}
			for (StudentExercisesSituationDto exercisesSituationDto : dataList) {
				if(Objects.isNull(queryInfo.getExistVipCourse())){
					Long vipCourses=studentVipCourseMap.get(exercisesSituationDto.getStudentId());
					if(Objects.isNull(vipCourses)||vipCourses<=0){
						exercisesSituationDto.setExistVipCourse(0);
					}else{
						exercisesSituationDto.setExistVipCourse(1);
					}
				}
			}
		}
		if (count == 0) {
			dataList = new ArrayList<>();
		}
		pageInfo.setRows(dataList);
		return pageInfo;
	}

	@Override
	public PageInfo<TeacherServeDto> queryTeacherServeInfo(TeacherServeQueryInfo queryInfo) {
		PageInfo<TeacherServeDto> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
		Map<String, Object> params = new HashMap<>();
		MapUtil.populateMap(params, queryInfo);
		if(StringUtils.isNotBlank(queryInfo.getOrganId())){
			List<Integer> organIds = Arrays.stream(queryInfo.getOrganId().split(",")).map(e -> Integer.valueOf(e)).collect(Collectors.toList());
			params.put("organIds",organIds);
		}
		List<TeacherServeDto> dataList = null;
		int count = studentExtracurricularExercisesSituationDao.countTeacherServeInfo(params);
		if (count > 0) {
			pageInfo.setTotal(count);
			params.put("offset", pageInfo.getOffset());
			dataList = studentExtracurricularExercisesSituationDao.queryTeacherServeInfo(params);
			List<Integer> teacherIds = dataList.stream().map(TeacherServeDto::getTeacherId).collect(Collectors.toList());
			List<TeacherRemind> teacherReminds = new ArrayList<>();
			if(!CollectionUtils.isEmpty(teacherIds)){
				teacherReminds = teacherRemindDao.findTeachersRemindWithType(TeacherRemindTypeEnum.SERVICE, teacherIds, queryInfo.getMonday(), queryInfo.getSunday());
			}
			Map<String, Map<Integer, List<TeacherRemind>>> mondayTeacherRemindMap = new HashMap<>();
			if(!CollectionUtils.isEmpty(teacherReminds)){
				mondayTeacherRemindMap = teacherReminds.stream().collect(Collectors.groupingBy(e -> DateUtil.dateToString(e.getMonday(), "yyyy-MM-dd"), Collectors.groupingBy(TeacherRemind::getTeacherId)));
			}
			List<StudentExtracurricularExercisesSituation> teacherServeWithDate = studentExtracurricularExercisesSituationDao.findTeacherServeWithDate(queryInfo.getMonday(), queryInfo.getSunday(), teacherIds, null);
			Map<Integer, List<StudentExtracurricularExercisesSituation>> teacherServeMap = teacherServeWithDate.stream().collect(Collectors.groupingBy(StudentExtracurricularExercisesSituation::getTeacherId));
			for (TeacherServeDto teacherServeDto : dataList) {
				teacherServeDto.setHomeworkStuNum(teacherServeDto.getExpectExercisesNum() - teacherServeDto.getExerciseNum());
				List<StudentExtracurricularExercisesSituation> tss = teacherServeMap.get(teacherServeDto.getTeacherId());
				Set<Long> courseIds = new HashSet<>();
				for (StudentExtracurricularExercisesSituation ts : tss) {
					if(teacherServeDto.getMonday().compareTo(ts.getMonday())!=0){
						continue;
					}
					if(StringUtils.isBlank(ts.getCourseIds())){
						continue;
					}
					Set<Long> ids = Arrays.stream(ts.getCourseIds().split(",")).map(s -> Long.valueOf(s)).collect(Collectors.toSet());
					courseIds.addAll(ids);
				}
				teacherServeDto.setHomeworkNum(courseIds.size());
				String mondayStr = DateUtil.dateToString(teacherServeDto.getMonday(), "yyyy-MM-dd");
				if(!mondayTeacherRemindMap.containsKey(mondayStr)){
					continue;
				}
				Map<Integer, List<TeacherRemind>> teacherRemindMap = mondayTeacherRemindMap.get(mondayStr);
				if(!teacherRemindMap.containsKey(teacherServeDto.getTeacherId())){
					continue;
				}
				TeacherRemind lastTeacherRemind = teacherRemindMap.get(teacherServeDto.getTeacherId()).stream().max(Comparator.comparing(TeacherRemind::getCreateTime)).get();
				teacherServeDto.setOperatorName(lastTeacherRemind.getOperatorName());
				teacherServeDto.setRemindDate(lastTeacherRemind.getCreateTime());
			}
		}
		if (count == 0) {
			dataList = new ArrayList<>();
		}
		pageInfo.setRows(dataList);
		return pageInfo;
	}

	@Override
	public List<Map<String, Object>> findServiceStudentDetail(StudentServiceDetailQueryInfo queryInfo) {
		PageInfo<StudentServiceDetailDto> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
		Map<String, Object> params = new HashMap<>();
		MapUtil.populateMap(params, queryInfo);

		List<StudentServiceDetailDto> dataList = null;
		int count = extracurricularExercisesReplyDao.countStudentHomeworkDetailsInTimeZone(params);
		if (count > 0) {
			pageInfo.setTotal(count);
			params.put("offset", pageInfo.getOffset());
			dataList = extracurricularExercisesReplyDao.findStudentHomeworkDetailsInTimeZone(params);
			Map<String, List<StudentServiceDetailDto>> weekHomeworks=new HashMap<>();
			for (StudentServiceDetailDto studentServiceDetailDto : dataList) {
				if(Objects.isNull(studentServiceDetailDto.getCourseStartTime())){
					continue;
				}
				LocalDate homeworkCreateTime = LocalDateTime.ofInstant(studentServiceDetailDto.getCourseStartTime().toInstant(), DateUtil.zoneId).toLocalDate();
				String mondayStr = homeworkCreateTime.with(DateUtil.weekFields.dayOfWeek(), DayOfWeek.MONDAY.getValue()).toString();
				if(!weekHomeworks.containsKey(mondayStr)){
					weekHomeworks.put(mondayStr, new ArrayList<>());
				}
				weekHomeworks.get(mondayStr).add(studentServiceDetailDto);
			}
			List<Map<String, Object>> results=new ArrayList<>();
			for (Map.Entry<String, List<StudentServiceDetailDto>> stringListEntry : weekHomeworks.entrySet()) {
				Map<String, Object> result=new HashMap<>();
				result.put("monday", stringListEntry.getKey());
				result.put("data", stringListEntry.getValue());
				results.add(result);
			}
			return results;
		}else{
			return null;
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void teacherServeRemindPush(List<TeacherServeDto> teacherServes, Integer operatorId, String operatorName) {
		if(CollectionUtils.isEmpty(teacherServes)){
			return;
		}
		List<TeacherRemind> reminds = new ArrayList<>();
		for (TeacherServeDto teacherServe : teacherServes) {
			if(Objects.isNull(teacherServe.getMonday())||Objects.isNull(teacherServe.getSunday())||Objects.isNull(teacherServe.getTeacherId())){
				continue;
			}
			String mondayStr = DateUtil.dateToString(teacherServe.getMonday(), "yyyy-MM-dd");
			List<StudentExtracurricularExercisesSituation> serves = studentExtracurricularExercisesSituationDao.findWeekServiceWithStudents(mondayStr, teacherServe.getTeacherId(), null);
			if(CollectionUtils.isEmpty(serves)){
				continue;
			}
			TeacherRemind remind = new TeacherRemind();
			remind.setOperatorId(operatorId);
			remind.setOperatorName(operatorName);
			remind.setMonday(teacherServe.getMonday());
			remind.setTeacherId(teacherServe.getTeacherId());
			remind.setType(TeacherRemindTypeEnum.SERVICE);
			remind.setContent("作业布置提醒");
			reminds.add(remind);

			Map<Integer, String> userMap = new HashMap<>();
			userMap.put(teacherServe.getTeacherId(), teacherServe.getTeacherId().toString());
			sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.TEACHER_PUSH_SERVE,
					userMap, null, 0, null, "TEACHER", teacherServe.getHomeworkNum(), teacherServe.getExerciseNum());
		}
		if(!CollectionUtils.isEmpty(reminds)){
			teacherRemindDao.batchInsert(reminds);
		}
	}

	@Override
	public PageInfo<TeacherServeHomeworkDto> queryTeacherServeHomeworkDetail(TeacherServeHomeworkQueryInfo queryInfo) {
		if(Objects.isNull(queryInfo.getMonday())||Objects.isNull(queryInfo.getSunday())){
			throw new BizException("请指定课程时间");
		}
		if(Objects.isNull(queryInfo.getTeacherId())){
			throw new BizException("请指定教师");
		}
		PageInfo<TeacherServeHomeworkDto> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
		String mondayStr = DateUtil.dateToString(queryInfo.getMonday(), "yyyy-MM-dd");
		List<StudentExtracurricularExercisesSituation> serves = studentExtracurricularExercisesSituationDao.findWeekServiceWithStudents(mondayStr, queryInfo.getTeacherId(), null);
		if(CollectionUtils.isEmpty(serves)){
			return pageInfo;
		}
		List<StudentExtracurricularExercisesSituation> homeworkServes = serves.stream().filter(s -> "HOMEWORK".equals(s.getServeType())).collect(Collectors.toList());
		if(CollectionUtils.isEmpty(homeworkServes)){
			return pageInfo;
		}
		List<Long> courseIdsArr = new ArrayList<>();
		for (StudentExtracurricularExercisesSituation homeworkServe : homeworkServes) {
			if(StringUtils.isBlank(homeworkServe.getCourseIds())){
				continue;
			}
			List<Long> ids = Arrays.stream(homeworkServe.getCourseIds().split(",")).map(id -> Long.valueOf(id)).collect(Collectors.toList());
			courseIdsArr.addAll(ids);
		}
		if(CollectionUtils.isEmpty(courseIdsArr)){
			return pageInfo;
		}

		Map<Long, Long> courseNumMap = courseIdsArr.stream().collect(Collectors.groupingBy(id -> id, Collectors.counting()));
		Set<Long> courseIds = new HashSet<>(courseIdsArr);

		Map<String, Object> params = new HashMap<>();
		MapUtil.populateMap(params, queryInfo);
		params.put("courseIds", courseIds);

		List<CourseHomework> courseHomeworks = courseHomeworkDao.findByCourseSchedules(new ArrayList<>(courseIds));
		Map<Long, Long> courseHomeworkMap = new HashMap<>();
		if(!CollectionUtils.isEmpty(courseHomeworks)){
			courseHomeworkMap = courseHomeworks.stream().collect(Collectors.groupingBy(CourseHomework::getCourseScheduleId, Collectors.counting()));
		}
		List<TeacherServeHomeworkDto> dataList = new ArrayList<>();
		int count = courseScheduleDao.countByCourseScheduleIds(params);
		if (count > 0) {
			pageInfo.setTotal(count);
			params.put("offset", pageInfo.getOffset());
			List<CourseSchedule> courseSchedules = courseScheduleDao.queryByCourseScheduleIds(params);
			Map<Integer, ClassGroup> idClassGroupMap = new HashMap<>();
			List<Integer> classGroupIds = courseSchedules.stream().map(CourseSchedule::getClassGroupId).collect(Collectors.toList());
			if(!CollectionUtils.isEmpty(classGroupIds)){
				List<ClassGroup> classGroups = classGroupDao.findByClassGroupIds(classGroupIds, null);
				idClassGroupMap = classGroups.stream().collect(Collectors.toMap(ClassGroup::getId, c -> c, (c1, c2) -> c1));
			}
			List<Integer> subjectIds = new ArrayList<>();
			for (CourseSchedule courseSchedule : courseSchedules) {
				if(idClassGroupMap.containsKey(courseSchedule.getClassGroupId())&&StringUtils.isNotBlank(idClassGroupMap.get(courseSchedule.getClassGroupId()).getSubjectIdList())){
					List<Integer> ids = Arrays.stream(idClassGroupMap.get(courseSchedule.getClassGroupId()).getSubjectIdList().split(",")).map(id -> Integer.valueOf(id)).collect(Collectors.toList());
					subjectIds.addAll(ids);
				}
				TeacherServeHomeworkDto tshd = new TeacherServeHomeworkDto();
				BeanUtils.copyProperties(courseSchedule,tshd);
				tshd.setStudentNum(courseNumMap.get(courseSchedule.getId()).intValue());
				if(courseHomeworkMap.containsKey(courseSchedule.getId())){
					tshd.setHomeworkExist(1);
				}
				dataList.add(tshd);
			}
			List<Subject> subjects = new ArrayList<>();
			if(!CollectionUtils.isEmpty(subjectIds)){
				subjects = subjectDao.findBySubjectIds(new ArrayList<>(subjectIds));
			}
			for (TeacherServeHomeworkDto teacherServeHomeworkDto : dataList) {
				if(idClassGroupMap.containsKey(teacherServeHomeworkDto.getClassGroupId())){
					ClassGroup classGroup = idClassGroupMap.get(teacherServeHomeworkDto.getClassGroupId());
					if(StringUtils.isNotBlank(classGroup.getSubjectIdList())){
						Set<Integer> sids = Arrays.stream(classGroup.getSubjectIdList().split(",")).map(id -> Integer.valueOf(id)).collect(Collectors.toSet());
						List<String> subjectNames = subjects.stream().filter(s -> sids.contains(s.getId())).map(Subject::getName).collect(Collectors.toList());
						teacherServeHomeworkDto.setSubjectName(StringUtils.join(subjectNames, ","));
					}
				}
			}
		}
		if (count == 0) {
			dataList = new ArrayList<>();
		}
		pageInfo.setRows(dataList);
		return pageInfo;
	}

	@Override
	public PageInfo<TeacherServeHomeworkPojo> queryTeacherServeHomeworkDetail1(TeacherServeHomeworkQueryInfo queryInfo) {
//		if(Objects.isNull(queryInfo.getMonth())){
//			throw new BizException("请指定课程时间");
//		}
		PageInfo<TeacherServeHomeworkPojo> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
		//获取时间段内有服务指标的课程(课后作业)
		Date firstDayOfMonth;
		Date lastDayOfMonth;
		if(Objects.isNull(queryInfo.getStartTime())){
			firstDayOfMonth = DateUtil.getFirstDayOfMonth(queryInfo.getMonth());
			lastDayOfMonth = DateUtil.getLastDayOfMonth(queryInfo.getMonth());
		}else {
			firstDayOfMonth = queryInfo.getStartTime();
			lastDayOfMonth = queryInfo.getEndTime();
		}
		List<Long> courseIds = studentExtracurricularExercisesSituationDao.queryCourseIdByClassDate(firstDayOfMonth,lastDayOfMonth,queryInfo.getTeacherId());
		if(courseIds == null || courseIds.size() == 0){
			return pageInfo;
		}
		Map<String, Object> params = new HashMap<>();
		MapUtil.populateMap(params, queryInfo);
		params.put("courseIds", courseIds);

		List<CourseHomework> courseHomeworks = courseHomeworkDao.findByCourseSchedules(new ArrayList<>(courseIds));
		if(!CollectionUtils.isEmpty(courseHomeworks)){
			Set<Long> collect = courseHomeworks.stream().map(e -> e.getCourseScheduleId()).collect(Collectors.toSet());
			courseIds.removeAll(collect);
		}
		if(courseIds.size() == 0){
			return pageInfo;
		}
		Map<Long,Long> memberNumMap = MapUtil.convertIntegerMap(studentDao.countCourseStudentMemberNum(courseIds));
		Map<Long,String> studentSubjectMap = MapUtil.convertMybatisMap(studentDao.countCourseStudentSubjectName(courseIds));
		Map<Long, Long> studentNumMap = MapUtil.convertIntegerMap(courseScheduleStudentPaymentDao.countCourseStudentNum(courseIds));
		Map<Integer, Long> studentNumCourseMap = MapUtil.convertIntegerMap(studentAttendanceDao.countStudentAttendancesByCourses(courseIds));

		List<TeacherServeHomeworkPojo> homeworkPojos;
		int count = courseScheduleDao.countHomeworkPojoByCourseScheduleIds(params);
		if (count > 0) {
			pageInfo.setTotal(count);
			params.put("offset", pageInfo.getOffset());
			homeworkPojos = courseScheduleDao.queryHomeworkPojoByCourseScheduleIds(params);
			pageInfo.setRows(homeworkPojos);
			for (TeacherServeHomeworkPojo homeworkPojo : homeworkPojos) {
				Long studentNum = studentNumCourseMap.get(homeworkPojo.getCourseScheduleId().intValue());
				if (Objects.nonNull(studentNum)) {
					homeworkPojo.setStudentAttendanceIsFirstTime(studentNum > 0 ? 0 : 1);
				} else {
					homeworkPojo.setStudentAttendanceIsFirstTime(1);
				}
				Long aLong = memberNumMap.get(homeworkPojo.getCourseScheduleId());
				homeworkPojo.setMemberNum(aLong==null?0:aLong.intValue());
				Long aLong1 = studentNumMap.get(homeworkPojo.getCourseScheduleId());
				homeworkPojo.setStudentNum(aLong1==null?0:aLong1.intValue());
				homeworkPojo.setSubjectName(studentSubjectMap.get(homeworkPojo.getCourseScheduleId()));
			}
		}
		return pageInfo;
	}

	@Override
	public PageInfo<TeacherServeExtraDto> queryTeacherServeExtraDetail(TeacherServeHomeworkQueryInfo queryInfo) {
		if(Objects.isNull(queryInfo.getMonday())||Objects.isNull(queryInfo.getSunday())||Objects.isNull(queryInfo.getTeacherId())){
			throw new BizException("请指定教师");
		}
		PageInfo<TeacherServeExtraDto> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
		String mondayStr = DateUtil.dateToString(queryInfo.getMonday(), "yyyy-MM-dd");
		List<StudentExtracurricularExercisesSituation> serves = studentExtracurricularExercisesSituationDao.findWeekServiceWithStudents(mondayStr, queryInfo.getTeacherId(), null);
		if(CollectionUtils.isEmpty(serves)){
			return pageInfo;
		}
		List<StudentExtracurricularExercisesSituation> homeworkServes = serves.stream().filter(s -> "EXERCISE".equals(s.getServeType())).collect(Collectors.toList());
		if(CollectionUtils.isEmpty(homeworkServes)){
			return pageInfo;
		}

		Set<Integer> studentIds = homeworkServes.stream().map(StudentExtracurricularExercisesSituation::getStudentId).collect(Collectors.toSet());
		Map<Integer, List<StudentExtracurricularExercisesSituation>> studentServeMap = homeworkServes.stream().collect(Collectors.groupingBy(StudentExtracurricularExercisesSituation::getStudentId));

		Map<String, Object> params = new HashMap<>();
		MapUtil.populateMap(params, queryInfo);
		params.put("studentIds", studentIds);

		List<TeacherServeExtraDto> dataList = new ArrayList<>();
		int count = studentDao.countByIds(params);
		if (count > 0) {
			pageInfo.setTotal(count);
			params.put("offset", pageInfo.getOffset());
			List<Student> students = studentDao.queryByIds(params);
			List<SimpleUserDto> usersSimpleInfo = teacherDao.getUsersSimpleInfo(new ArrayList<>(studentIds));
			Map<Integer, String> idNameMap = new HashMap<>();
			if(!CollectionUtils.isEmpty(usersSimpleInfo)){
				idNameMap = usersSimpleInfo.stream().collect(Collectors.toMap(SimpleUserDto::getUserId, s -> s.getNickName(), (s1, s2) -> s1));
			}
			Set<Integer> subjectIds = new HashSet<>();
			for (Student student : students) {
				if(StringUtils.isNotBlank(student.getSubjectIdList())){
					Set<Integer> ids = Arrays.stream(student.getSubjectIdList().split(",")).map(id -> Integer.valueOf(id)).collect(Collectors.toSet());
					subjectIds.addAll(ids);
				}
				TeacherServeExtraDto tsed = new TeacherServeExtraDto();
				BeanUtils.copyProperties(student,tsed);
				if(studentServeMap.containsKey(student.getUserId())){
					List<StudentExtracurricularExercisesSituation> studentServes = studentServeMap.get(student.getUserId());
					int num = studentServes.stream().mapToInt(StudentExtracurricularExercisesSituation::getActualExercisesNum).reduce(0, Integer::sum);
					if(num>0){
						tsed.setHomeworkExist(1);
					}
				}
				dataList.add(tsed);
			}
			List<Subject> subjects = new ArrayList<>();
			if(!CollectionUtils.isEmpty(subjectIds)){
				subjects = subjectDao.findBySubjectIds(new ArrayList<>(subjectIds));
			}
			for (TeacherServeExtraDto teacherServeExtraDto : dataList) {
				if(idNameMap.containsKey(teacherServeExtraDto.getUserId())){
					teacherServeExtraDto.setUsername(idNameMap.get(teacherServeExtraDto.getUserId()));
				}
				if(StringUtils.isNotBlank(teacherServeExtraDto.getSubjectIdList())){
					Set<Integer> sids = Arrays.stream(teacherServeExtraDto.getSubjectIdList().split(",")).map(id -> Integer.valueOf(id)).collect(Collectors.toSet());
					List<String> subjectNames = subjects.stream().filter(s -> sids.contains(s.getId())).map(Subject::getName).collect(Collectors.toList());
					teacherServeExtraDto.setSubjectNames(StringUtils.join(subjectNames, ","));
				}
			}
		}
		if (count == 0) {
			dataList = new ArrayList<>();
		}
		pageInfo.setRows(dataList);
		return pageInfo;
	}

	@Override
	public int countWaitCreateHomeworkNum() {
		SysUser sysUser = sysUserFeignService.queryUserInfo();
		if (sysUser == null) {
			throw new BizException("用户信息获取失败");
		}
		int exerciseNum = studentExtracurricularExercisesSituationDao.countWaitCreateHomeworkNum(sysUser.getId(), "EXERCISE");
		if(exerciseNum > 0){
			return exerciseNum;
		}
		return studentExtracurricularExercisesSituationDao.countWaitCreateHomeworkNum1(sysUser.getId());
	}

	@Override
	public List<TeacherServeDto> queryTeacherPerformanceIndicator(TeacherServeQueryInfo queryInfo) {
		Map<String, Object> params = new HashMap<>();
		MapUtil.populateMap(params, queryInfo);
		if(StringUtils.isNotBlank(queryInfo.getOrganId())){
			List<Integer> organIds = Arrays.stream(queryInfo.getOrganId().split(",")).map(e -> Integer.valueOf(e)).collect(Collectors.toList());
			params.put("organIds",organIds);
		}
		List<TeacherServeDto> dataList = null;
		dataList = studentExtracurricularExercisesSituationDao.queryTeacherPerformanceIndicator(params);
		
		if(dataList.size() == 0){
			return dataList;
		}
		
		List<Integer> teacherIds = dataList.stream().map(TeacherServeDto::getTeacherId).collect(Collectors.toList());
		List<StudentExtracurricularExercisesSituation> teacherServeWithDate = studentExtracurricularExercisesSituationDao.findTeacherServeWithDate(queryInfo.getMonday(), queryInfo.getSunday(), teacherIds, null);
		Map<Integer, List<StudentExtracurricularExercisesSituation>> teacherServeMap = teacherServeWithDate.stream().collect(Collectors.groupingBy(StudentExtracurricularExercisesSituation::getTeacherId));
		for (TeacherServeDto teacherServeDto : dataList) {
			List<StudentExtracurricularExercisesSituation> tss = teacherServeMap.get(teacherServeDto.getTeacherId());
			if(tss != null){
				Set<Long> courseIds = new HashSet<>();
				for (StudentExtracurricularExercisesSituation ts : tss) {
					if(teacherServeDto.getMonday().compareTo(ts.getMonday())!=0){
						continue;
					}
					if(StringUtils.isBlank(ts.getCourseIds())){
						continue;
					}
					Set<Long> ids = Arrays.stream(ts.getCourseIds().split(",")).map(s -> Long.valueOf(s)).collect(Collectors.toSet());
					courseIds.addAll(ids);
				}
				teacherServeDto.setHomeworkNum(courseIds.size());
			}
		}
		return dataList;
	}


	@Override
	@Transactional(rollbackFor = Exception.class)
	public void batchInsert(List<StudentExtracurricularExercisesSituation> situations) {
		if (CollectionUtils.isEmpty(situations)){
			return;
		}
		studentExtracurricularExercisesSituationDao.batchInsert(situations);
		String collect = situations.stream().map(e -> e.getCourseIds()).filter(e -> StringUtils.isNotEmpty(e)).distinct().collect(Collectors.joining(","));
		if(StringUtils.isNotEmpty(collect)){
			//更新课程服务指标
			courseScheduleStatisticsDao.updateCourseService(collect,1);
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void deleteByMonday(String monday,List<Integer> studentIds) {
		this.delSituations(studentExtracurricularExercisesSituationDao.selectByMonday(monday, studentIds));
		studentExtracurricularExercisesSituationDao.deleteByMonday(monday,studentIds);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void deleteByStudent(Integer studentId, String monday) {
		this.delSituations(studentExtracurricularExercisesSituationDao.selectByStudent(studentId, monday));
		studentExtracurricularExercisesSituationDao.deleteByStudent(studentId,monday);
	}

	@Override
	public TeacherExercisesServiceDto getStatistics(ExtraExercilseQueryInfo queryInfo) {
		TeacherExercisesServiceDto serviceDto = new TeacherExercisesServiceDto();
		List<Integer> teacherIds = new ArrayList();
		teacherIds.add(queryInfo.getTeacherId());
		List<StudentExtracurricularExercisesSituation> teacherServeWithDate =
				studentExtracurricularExercisesSituationDao.findTeacherServeWithDate(queryInfo.getStartTime(), queryInfo.getEndTime(), teacherIds, null);
		if(!CollectionUtils.isEmpty(teacherServeWithDate)){
			//预计训练次数
			double expectExercisesNum = teacherServeWithDate.stream().mapToDouble(e -> e.getExpectExercisesNum()).sum();
			//实际训练次数
			double actualExercisesNum = teacherServeWithDate.stream().mapToInt(e -> e.getActualExercisesNum()).sum();
			//布置率
			BigDecimal oneHundred = new BigDecimal(100);
			if(expectExercisesNum > 0d){
				BigDecimal submitRate = new BigDecimal(actualExercisesNum).divide(new BigDecimal(expectExercisesNum), CommonConstants.DECIMAL_FINAL_PLACE, BigDecimal.ROUND_HALF_UP).multiply(oneHundred).setScale(0);
				serviceDto.setExpectExercisesRate(submitRate + "%");
			}
			//训练提交次数
			double exercisesReplyNum = teacherServeWithDate.stream().mapToInt(e -> e.getExercisesReplyNum()).sum();
			//提交率
			if(actualExercisesNum > 0d){
				BigDecimal submitRate = new BigDecimal(exercisesReplyNum).divide(new BigDecimal(actualExercisesNum), CommonConstants.DECIMAL_FINAL_PLACE, BigDecimal.ROUND_HALF_UP).multiply(oneHundred).setScale(0);
				serviceDto.setExercisesReplyRate(submitRate + "%");
			}
			//点评次数
			double exercisesMessageNum = teacherServeWithDate.stream().mapToInt(e -> e.getExercisesMessageNum()).sum();
			//点评率
			if(exercisesReplyNum > 0d){
				BigDecimal submitRate = new BigDecimal(exercisesMessageNum).divide(new BigDecimal(exercisesReplyNum), CommonConstants.DECIMAL_FINAL_PLACE, BigDecimal.ROUND_HALF_UP).multiply(oneHundred).setScale(0);
				serviceDto.setExercisesMessageRate(submitRate + "%");
			}
		}
		return serviceDto;
	}

	@Transactional(rollbackFor = Exception.class)
	public void delSituations(List<StudentExtracurricularExercisesSituation> situations){
		if (CollectionUtils.isEmpty(situations)){
			return;
		}
//		List<Long> collect1 = situations.stream().map(e -> e.getId()).collect(Collectors.toList());
//		studentExtracurricularExercisesSituationDao.batchDelete(collect1);
		String collect = situations.stream().map(e -> e.getCourseIds()).filter(e -> StringUtils.isNotEmpty(e)).distinct().collect(Collectors.joining(","));
		if(StringUtils.isNotEmpty(collect)){
			//更新课程服务指标
			courseScheduleStatisticsDao.updateCourseService(collect,0);
		}
	}
}