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

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

import com.ym.mec.biz.dal.dao.*;
import com.ym.mec.biz.dal.dto.*;
import com.ym.mec.biz.dal.entity.*;
import com.ym.mec.biz.dal.enums.GroupType;
import com.ym.mec.biz.dal.enums.ImSendTypeEnum;
import com.ym.mec.biz.service.*;
import com.ym.mec.common.entity.ImPrivateMessage;
import com.ym.mec.common.entity.ImTxtMessage;
import com.ym.mec.im.ImFeignService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.ym.mec.auth.api.entity.SysUser;
import com.ym.mec.biz.dal.enums.MessageTypeEnum;
import com.ym.mec.biz.dal.enums.YesOrNoEnum;
import com.ym.mec.biz.dal.page.CourseReview4EduQueryInfo;
import com.ym.mec.biz.dal.page.CourseReviewQueryInfo;
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.redis.service.RedisCache;
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 CourseReviewServiceImpl extends BaseServiceImpl<Integer, CourseScheduleReview> implements CourseReviewService {


    @Autowired
    private CourseScheduleReviewDao courseScheduleReviewDao;

    @Autowired
    private SubjectDao subjectDao;

    @Autowired
    private OrganizationDao organizationDao;

    @Autowired
    private CourseScheduleDao courseScheduleDao;

    @Autowired
    private PracticeGroupDao practiceGroupDao;

    @Autowired
    private ClassGroupService classGroupService;

    @Autowired
    private CourseHomeworkService courseHomeworkService;

    @Autowired
    private CourseScheduleStudentPaymentDao courseScheduleStudentPaymentDao;

    @Autowired
    private StudentCourseHomeworkDao studentCourseHomeworkDao;

    @Autowired
    private CourseHomeworkDao courseHomeworkDao;

    @Autowired
    private SysMessageService sysMessageService;

    @Autowired
    private ImFeignService imFeignService;

    @Autowired
    private TeacherDao teacherDao;

    @Autowired
    private StudentDao studentDao;

    @Autowired
    private CourseScheduleComplaintsDao courseScheduleComplaintsDao;

    @Autowired
    private SysConfigDao sysConfigDao;

    @Autowired
    private VipGroupDao vipGroupDao;

    @Autowired
    private StudentServeService studentServeService;

    @Override
    public BaseDAO<Integer, CourseScheduleReview> getDAO() {
        return courseScheduleReviewDao;
    }


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

        List<CourseReviewDto> dataList = null;
        int count = courseScheduleReviewDao.countPracticeGroupReviews(params);
        if (count > 0) {
            pageInfo.setTotal(count);
            params.put("offset", pageInfo.getOffset());
            dataList = courseScheduleReviewDao.getPracticeGroupReviewList(params);
            if (dataList != null && dataList.size() > 0) {
                List<Integer> subjectIds = dataList.stream().map(CourseReviewDto::getSubjectId).distinct().collect(Collectors.toList());
                Set<Integer> organIds = dataList.stream().map(CourseReviewDto::getOrganId).collect(Collectors.toSet());
                //声部名称列表
                Map<Long, String> subjectNames = MapUtil.convertMybatisMap(subjectDao.findBySubjecIds(StringUtils.join(subjectIds, ",")));
                Map<Integer, String> organNames = MapUtil.convertMybatisMap(organizationDao.findOrganNameMapList(organIds));
                dataList.forEach(e -> {
                    e.setSubjectName(subjectNames.get(e.getSubjectId().intValue()));
                    e.setOrganName(organNames.get(e.getOrganId()));
                });
            }
        }
        if (count == 0) {
            dataList = new ArrayList<>();
        }
        pageInfo.setRows(dataList);
        return pageInfo;
    }

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

        List<CourseScheduleReview> dataList = null;
        int count = courseScheduleReviewDao.countPracticeGroupReviews4Edu(params);
        if (count > 0) {
            pageInfo.setTotal(count);
            params.put("offset", pageInfo.getOffset());
            dataList = courseScheduleReviewDao.getPracticeGroupReview4EduList(params);
        }
        if (count == 0) {
            dataList = new ArrayList<>();
        }
        pageInfo.setRows(dataList);
        return pageInfo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
    public CourseScheduleReview addPracticeGroupReview(CourseScheduleReview courseScheduleReview) {
        Integer courseScheduleId = courseScheduleReview.getCourseScheduleId();
        if (courseScheduleId == null || courseScheduleId <= 0) {
            throw new BizException("课程id必须大于0");
        }
        Date date = new Date();
        CourseSchedule courseSchedule = courseScheduleDao.get(courseScheduleId.longValue());
        if (courseSchedule == null) {
            throw new BizException("课程不存在");
        }

        studentDao.lockUser(courseScheduleReview.getTeacherId());

        Integer studentId = null;
        Integer educationalTeacherId = null;

        if (courseSchedule.getType().equals(CourseSchedule.CourseScheduleType.PRACTICE)) {
            PracticeGroup practiceGroup = practiceGroupDao.get(Long.parseLong(courseSchedule.getMusicGroupId()));
            studentId = practiceGroup.getStudentId();
            educationalTeacherId = practiceGroup.getEducationalTeacherId();
        } else if (courseSchedule.getType().equals(CourseSchedule.CourseScheduleType.VIP)) {
            VipGroup vipGroup = vipGroupDao.get(Long.parseLong(courseSchedule.getMusicGroupId()));
            educationalTeacherId = vipGroup.getEducationalTeacherId();
        }
        CourseScheduleReview hasReview = courseScheduleReviewDao.findByCourseScheduleAndStudent(courseScheduleId.longValue(), studentId);
        if (hasReview != null) {
            throw new BizException("评论已提交,请勿重复提交");
        }
        courseScheduleReview.setClassGroupId(courseSchedule.getClassGroupId());
        courseScheduleReview.setEducationalTeacherId(educationalTeacherId);
        courseScheduleReview.setStudentId(studentId);
        courseScheduleReview.setCreateTime(date);
        courseScheduleReview.setUpdateTime(date);
        long num = courseScheduleReviewDao.insert(courseScheduleReview);
        if (num <= 0) {
            throw new BizException("评论提交失败，请重试");
        }

        CourseHomework existHomework = courseHomeworkDao.findByCourseSchedule(courseScheduleId.longValue());

        if (StringUtils.isNotBlank(courseScheduleReview.getHomeWork())) {
            //新增课堂作业
            CourseHomework courseHomework = new CourseHomework();
            List<CourseScheduleStudentPayment> courseScheduleStudentPayments = courseScheduleStudentPaymentDao.findByCourseSchedule(courseSchedule.getId());

            if (Objects.nonNull(existHomework)) {
                courseHomework.setId(existHomework.getId());
                courseHomework.setContent(courseScheduleReview.getHomeWork());
                courseHomework.setExpiryDate(DateUtil.addDays(date, 7));
                courseHomeworkService.update(courseHomework);
            } else {
                courseHomework.setContent(courseScheduleReview.getHomeWork());
                courseHomework.setCourseScheduleId(courseSchedule.getId());
                courseHomework.setMusicGroupId(courseSchedule.getMusicGroupId());
                courseHomework.setGroupType(courseSchedule.getGroupType());
                courseHomework.setClassGroupId(courseSchedule.getClassGroupId());
                courseHomework.setExpiryDate(DateUtil.addDays(date, 3));
                courseHomework.setExpectNum(CollectionUtils.isEmpty(courseScheduleStudentPayments) ? 0 : courseScheduleStudentPayments.size());
                courseHomeworkService.insert(courseHomework);
            }

            if (!CollectionUtils.isEmpty(courseScheduleStudentPayments)) {
//                    List<StudentCourseHomework> studentCourseHomeworks = new ArrayList<>();
                Teacher teacher = teacherDao.get(courseScheduleReview.getTeacherId());
                String dateStr = DateUtil.dateToString(DateUtil.addDays(date, 3), "MM月dd日");
                for (CourseScheduleStudentPayment courseScheduleStudentPayment : courseScheduleStudentPayments) {
                    StudentCourseHomework studentCourseHomework = new StudentCourseHomework();
                    if (Objects.isNull(existHomework)) {
                        studentCourseHomework.setCourseHomeworkId(courseHomework.getId());
                        studentCourseHomework.setUserId(courseScheduleStudentPayment.getUserId());
                        studentCourseHomework.setCourseScheduleId(courseSchedule.getId());
                        studentCourseHomework.setCreateTime(date);
                        studentCourseHomework.setUpdateTime(date);
                        studentCourseHomework.setStatus(YesOrNoEnum.NO);
                        studentCourseHomework.setIsView(YesOrNoEnum.NO);
                        studentCourseHomework.setIsReplied(YesOrNoEnum.NO);
                        studentCourseHomework.setIsRepliedTimely(0);
                        studentCourseHomeworkDao.insert(studentCourseHomework);
                    } else {
                        studentCourseHomework = studentCourseHomeworkDao.findByStudentAndCourseHomewok(existHomework.getId(), courseScheduleStudentPayment.getUserId());
                    }

                    Map<Integer, String> userMap = new HashMap<>();
                    userMap.put(courseScheduleStudentPayment.getUserId(), courseScheduleStudentPayment.getUserId().toString());
                    String notifyUrl = "?courseScheduleID=" + courseSchedule.getId() + "&studentCourseHomeworkId=" + studentCourseHomework.getId() + "&extra=0";
                    String extra = "dayaedu" + notifyUrl + "&userId=" + courseScheduleStudentPayment.getUserId();
                    if (courseScheduleReview.getMsgType() != ImSendTypeEnum.TXT) {
                        sysMessageService.batchSendImMessage(MessageTypeEnum.IM_HOMEWORK_REMIND_DETAIL, courseScheduleReview.getTeacherId().toString(), extra,
                                new String[]{courseScheduleStudentPayment.getUserId().toString()},
                                null, courseSchedule.getName(), dateStr, courseHomework.getContent());
                    } else {
                        sysMessageService.batchSendImMessage(MessageTypeEnum.IM_HOMEWORK_REMIND, courseScheduleReview.getTeacherId().toString(), extra,
                                new String[]{courseScheduleStudentPayment.getUserId().toString()},
                                null, courseSchedule.getName(), dateStr, courseHomework.getContent());
                    }
                    sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.HOMEWORK_REMIND,
                            userMap, null, 0, 3 + notifyUrl, "STUDENT", teacher.getRealName(), courseSchedule.getName(), dateStr);
                }
            }
        }

        return courseScheduleReview;
    }

    @Override
    public ReviewInfoDto getReviewInfo(Integer id) {
        CourseScheduleReview courseScheduleReview = courseScheduleReviewDao.get(id);
        if (courseScheduleReview == null) {
            throw new BizException("评价不存在");
        }
        CourseHomework homework = courseHomeworkDao.findByCourseSchedule(courseScheduleReview.getCourseScheduleId().longValue());
        if (homework != null) {
            courseScheduleReview.setHomeWork(homework.getContent());
        }
        TeacherClassHeadInfo teacherClassGroupInfo = getCourseInfoHead(courseScheduleReview.getCourseScheduleId());
        courseScheduleReview.setTeacherName(teacherClassGroupInfo.getBishopTeacher());

        if (courseScheduleReview.getEducationalTeacherId() != null && !courseScheduleReview.getEducationalTeacherId().equals(0)) {
            SysUser user = teacherDao.getUser(courseScheduleReview.getEducationalTeacherId());
            courseScheduleReview.setEduTeacherName(user.getRealName());
        }

        ReviewInfoDto reviewInfoDto = new ReviewInfoDto();
        reviewInfoDto.setCourseScheduleReview(courseScheduleReview);
        reviewInfoDto.setTeacherClassHeadInfo(teacherClassGroupInfo);
        Long studentId = null;
        if (courseScheduleReview.getStudentId() != null) {
            studentId = courseScheduleReview.getStudentId().longValue();
        }
        //学生评价
        CourseScheduleComplaintsDto courseScheduleComplaint = courseScheduleComplaintsDao.findByUserIdAndCourseId(studentId, courseScheduleReview.getCourseScheduleId().longValue());
        if (courseScheduleComplaint != null) {
            List<CourseScheduleComplaintsDto> courseScheduleComplaints = new ArrayList<>();
            courseScheduleComplaints.add(courseScheduleComplaint);
            if (courseScheduleReview.getStudentId() == null || courseScheduleReview.getStudentId().equals(0)) {
                courseScheduleComplaints = courseScheduleComplaintsDao.findCourseIdComplaints(courseScheduleReview.getCourseScheduleId().longValue());
            }
            reviewInfoDto.setCourseScheduleComplaints(courseScheduleComplaints);
        }
        return reviewInfoDto;
    }

    @Override
    public TeacherClassHeadInfo getCourseInfoHead(Integer id) {
        CourseSchedule courseSchedule = courseScheduleDao.get(id.longValue());
        ClassGroup classGroup = classGroupService.get(courseSchedule.getClassGroupId());
        TeacherClassHeadInfo teacherClassGroupInfo = classGroupService.findTeacherClassGroupInfoByCourseId(id);
        teacherClassGroupInfo.setClassDate(DateUtil.dateToString(courseSchedule.getClassDate(), "yyyy年MM月dd日"));
        teacherClassGroupInfo.setStartClassTime(DateUtil.dateToString(courseSchedule.getStartClassTime(), "HH:mm"));
        teacherClassGroupInfo.setEndClassTime(DateUtil.dateToString(courseSchedule.getEndClassTime(), "HH:mm"));
        teacherClassGroupInfo.setClassGroupName(classGroup.getName());
        teacherClassGroupInfo.setCourseScheduleType(courseSchedule.getType());
        return teacherClassGroupInfo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CourseScheduleReview updateReview(CourseScheduleReview courseScheduleReview) {
        if (courseScheduleReview.getId() == null || courseScheduleReview.getId() <= 0) {
            throw new BizException("评论id为空");
        }
        CourseScheduleReview review = courseScheduleReviewDao.get(courseScheduleReview.getId());
        if (review == null) {
            throw new BizException("评论不存在");
        }
        courseScheduleReviewDao.update(courseScheduleReview);

        if (StringUtils.isNotBlank(courseScheduleReview.getHomeWork())) {
            Date date = new Date();
            CourseSchedule courseSchedule = courseScheduleDao.get(review.getCourseScheduleId().longValue());
            CourseHomework homework = courseHomeworkDao.findByCourseSchedule(review.getCourseScheduleId().longValue());
            if (Objects.isNull(homework)) {
                if (StringUtils.isNotBlank(courseScheduleReview.getHomeWork())) {
                    //新增课堂作业
                    CourseHomework courseHomework = new CourseHomework();
                    courseHomework.setContent(courseScheduleReview.getHomeWork());
                    courseHomework.setCourseScheduleId(courseSchedule.getId());
                    courseHomework.setMusicGroupId(courseSchedule.getMusicGroupId());
                    courseHomework.setGroupType(courseSchedule.getGroupType());
                    courseHomework.setClassGroupId(courseSchedule.getClassGroupId());
                    courseHomework.setExpiryDate(DateUtil.addDays(date, 7));
                    List<CourseScheduleStudentPayment> courseScheduleStudentPayments = courseScheduleStudentPaymentDao.findByCourseSchedule(courseSchedule.getId());

                    courseHomework.setExpectNum(CollectionUtils.isEmpty(courseScheduleStudentPayments) ? 0 : courseScheduleStudentPayments.size());
                    courseHomeworkService.insert(courseHomework);

                    if (!CollectionUtils.isEmpty(courseScheduleStudentPayments)) {
                        List<StudentCourseHomework> studentCourseHomeworks = new ArrayList<>();
                        for (CourseScheduleStudentPayment courseScheduleStudentPayment : courseScheduleStudentPayments) {
                            StudentCourseHomework studentCourseHomework = new StudentCourseHomework();
                            studentCourseHomework.setCourseHomeworkId(courseHomework.getId());
                            studentCourseHomework.setUserId(courseScheduleStudentPayment.getUserId());
                            studentCourseHomework.setCourseScheduleId(courseSchedule.getId());
                            studentCourseHomework.setStatus(YesOrNoEnum.NO);
                            studentCourseHomework.setIsView(YesOrNoEnum.NO);
                            studentCourseHomework.setIsReplied(YesOrNoEnum.NO);
                            studentCourseHomeworks.add(studentCourseHomework);
                        }
                        studentCourseHomeworkDao.batchInsertStudentCourseHomeworkRecord(studentCourseHomeworks);
                    }
                }
            } else if (Objects.isNull(homework.getContent()) || !homework.getContent().equals(courseScheduleReview.getHomeWork())) {
                homework.setContent(courseScheduleReview.getHomeWork());
                courseHomeworkDao.update(homework);
            }
        }

        return courseScheduleReview;
    }

    public void pushNeedReview2Teacher() {
        CourseReviewQueryInfo courseReviewQueryInfo = new CourseReviewQueryInfo();
        courseReviewQueryInfo.setHasReview(0);
        courseReviewQueryInfo.setRows(10000);
        PageInfo<CourseReviewDto> practiceGroupReviews = findPracticeGroupReviews(courseReviewQueryInfo);

        if (practiceGroupReviews.getTotal() <= 0) {
            return;
        }
        Map<Integer, List<CourseReviewDto>> teacherNeedReview = practiceGroupReviews.getRows().stream().collect(Collectors.groupingBy(CourseReviewDto::getTeacherId));

        String teacherBaseUrl = sysConfigDao.findConfigValue(SysConfigService.TEACHER_BASE_URL);

        String pushUrl = teacherBaseUrl + "/#/manageEvaluation";
        Map<Integer, String> userMap = new HashMap<>();
        for (Map.Entry<Integer, List<CourseReviewDto>> integerListEntry : teacherNeedReview.entrySet()) {
            userMap.put(integerListEntry.getKey(), integerListEntry.getKey().toString());
        }

        sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.NEED_POST_STUDY_REPORT,
                userMap, null, 0, "8?" + pushUrl, "TEACHER");

    }

    @Override
    public List<CourseReviewDto> getClassOverCourse(Long classGroupId) {
        List<CourseReviewDto> coursesList = courseScheduleReviewDao.findByClassGroupId(classGroupId);

        Map<Integer, List<CourseScheduleReview>> courseReviewsMap = new HashMap<>();
        Map<Long, List<CourseScheduleComplaints>> courseComplaintsMap = new HashMap<>();
        if (coursesList.size() > 0) {
            List<Long> courseIds = coursesList.stream().map(courseReviewDto -> courseReviewDto.getId().longValue()).collect(Collectors.toList());
            List<CourseScheduleReview> reviews = courseScheduleReviewDao.findByCourseSchedules(courseIds);
            courseReviewsMap = reviews.stream().collect(Collectors.groupingBy(CourseScheduleReview::getCourseScheduleId));
            List<CourseScheduleComplaints> studentReviewsList = courseScheduleComplaintsDao.findComplaintsByCourseScheduleIds(courseIds);
            courseComplaintsMap = studentReviewsList.stream().collect(Collectors.groupingBy(CourseScheduleComplaints::getCourseScheduleId));
        }
        for (CourseReviewDto course : coursesList) {
            if (courseReviewsMap.containsKey(course.getId())) {
                List<CourseScheduleReview> reviews = courseReviewsMap.get(course.getId());
                course.setReviewId(reviews.get(0).getId());
            }
            if (courseComplaintsMap.containsKey(course.getId().longValue())) {
                List<CourseScheduleComplaints> courseScheduleComplaints = courseComplaintsMap.get(course.getId().longValue());
                course.setStudentReview(courseScheduleComplaints.get(0).getScore().intValue());
            }

            Date startTime = DateUtil.stringToDate(course.getClassDateStr() + " " + course.getStartClassTimeStr());
            Date endTime = DateUtil.stringToDate(course.getClassDateStr() + " " + course.getEndClassTimeStr());
            int duration = DateUtil.minutesBetween(startTime, endTime);
            course.setCourseDuration(duration);
            course.setStartClassTimeStr(course.getStartClassTimeStr().substring(0, 5));
            course.setEndClassTimeStr(course.getEndClassTimeStr().substring(0, 5));
        }
        return coursesList;
    }

    @Override
    public ReviewInfoDto getStuAndTeaReview(Long courseId) {
        CourseSchedule courseSchedule = courseScheduleDao.get(courseId);
        if (courseSchedule == null) {
            throw new BizException("课程不存在");
        }
        //头部信息
        TeacherClassHeadInfo teacherClassGroupInfo = getCourseInfoHead(courseId.intValue());
        ReviewInfoDto reviewInfoDto = new ReviewInfoDto();
        reviewInfoDto.setTeacherClassHeadInfo(teacherClassGroupInfo);
        //学生评价
        List<CourseScheduleComplaintsDto> CourseScheduleComplaints = courseScheduleComplaintsDao.findByCourseScheduleId(courseId);
        if (CourseScheduleComplaints.size() > 0) {
            reviewInfoDto.setCourseScheduleComplaints(CourseScheduleComplaints);
        }
        //老师评价
        List<CourseScheduleReview> teacherReviews = courseScheduleReviewDao.findByCourseScheduleId(courseId);
        if (teacherReviews.size() > 0) {
            reviewInfoDto.setCourseScheduleReviewList(teacherReviews);
            Set<Integer> review4StudentIds = teacherReviews.stream().map(CourseScheduleReview::getStudentId).collect(Collectors.toSet());
            reviewInfoDto.setReview4StudentIds(review4StudentIds);
            reviewInfoDto.setTeachingMaterial(teacherReviews.get(0).getTeachingMaterial());
        }
        //班级学生
        List<SysUser> students = courseScheduleReviewDao.findStudentByClassGroupId(courseSchedule.getClassGroupId().longValue());
        if (students.size() > 0) {
            reviewInfoDto.setStudents(students);
        }
        return reviewInfoDto;
    }

    @Override
    public List<CourseScheduleReview> batchAdd(Integer teacherId, List<CourseScheduleReview> courseScheduleReviewList) {
        if (courseScheduleReviewList == null || courseScheduleReviewList.size() <= 0) {
            throw new BizException("提交内容不能为空");
        }
        Integer courseScheduleId = courseScheduleReviewList.get(0).getCourseScheduleId();
        if (courseScheduleId == null || courseScheduleId <= 0) {
            throw new BizException("课程id不能为空");
        }
        CourseSchedule courseSchedule = courseScheduleDao.get(courseScheduleId.longValue());
        if (courseSchedule == null) {
            throw new BizException("课程不存在，确保课程id正确");
        }
        for (CourseScheduleReview courseScheduleReview : courseScheduleReviewList) {
            courseScheduleReview.setCourseScheduleId(courseSchedule.getId().intValue());
            courseScheduleReview.setClassGroupId(courseSchedule.getClassGroupId());
            courseScheduleReview.setTeacherId(teacherId);
        }
        int nums = courseScheduleReviewDao.batchAdd(courseScheduleReviewList);
        if (nums <= 0) {
            throw new BizException("评价插入失败，请重试");
        }
        return courseScheduleReviewList;
    }

    @Override
    public ReviewInfoDto getStuAndTeaReviewInfo(Long courseId, Integer userId) {
        //老师评价
        CourseScheduleReview courseScheduleReview = courseScheduleReviewDao.findByCourseScheduleAndStudent(courseId, userId);
        //学生评价
        CourseScheduleComplaintsDto courseScheduleComplaint = courseScheduleComplaintsDao.findByUserIdAndCourseId(userId.longValue(), courseId);

        if (courseScheduleReview == null && courseScheduleComplaint == null) {
            throw new BizException("评价不存在");
        }

        TeacherClassHeadInfo teacherClassGroupInfo = getCourseInfoHead(courseId.intValue());
        ReviewInfoDto reviewInfoDto = new ReviewInfoDto();
        reviewInfoDto.setTeacherClassHeadInfo(teacherClassGroupInfo);

        if (courseScheduleReview != null) {
            CourseHomework homework = courseHomeworkDao.findByCourseSchedule(courseId);
            if (homework != null) {
                courseScheduleReview.setHomeWork(homework.getContent());
            }
            courseScheduleReview.setTeacherName(teacherClassGroupInfo.getBishopTeacher());
            CourseSchedule courseSchedule = courseScheduleDao.get(courseId);
            if (courseSchedule.getGroupType().equals(GroupType.PRACTICE)) {
                PracticeCourseDto practiceGroup = practiceGroupDao.findByGroupId(Integer.parseInt(courseSchedule.getMusicGroupId()));
                courseScheduleReview.setEduTeacherName(practiceGroup.getEduTeacherName());
            }
            reviewInfoDto.setCourseScheduleReview(courseScheduleReview);
        }

        if (courseScheduleComplaint != null) {
            List<CourseScheduleComplaintsDto> courseScheduleComplaints = new ArrayList<>();
            courseScheduleComplaints.add(courseScheduleComplaint);
            reviewInfoDto.setCourseScheduleComplaints(courseScheduleComplaints);
        }
        return reviewInfoDto;
    }

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

        List<CourseReviewDto> dataList = null;
        int count = courseScheduleReviewDao.countOnlineCourseReviews(params);
        if (count > 0) {
            pageInfo.setTotal(count);
            params.put("offset", pageInfo.getOffset());
            dataList = courseScheduleReviewDao.getOnlineCourseReviewList(params);
        }
        if (count == 0) {
            dataList = new ArrayList<>();
        }
        pageInfo.setRows(dataList);
        return pageInfo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
    public CourseHomework addHomeWork(Integer courseScheduleId, String content, Date expiryDate) {
        if (StringUtils.isBlank(content)) {
            throw new BizException("作业内容不能为空");
        }
        if (courseScheduleId == null || courseScheduleId <= 0) {
            throw new BizException("课程id必须大于0");
        }
        Date date = new Date();
        CourseSchedule courseSchedule = courseScheduleDao.get(courseScheduleId.longValue());
        if (courseSchedule == null) {
            throw new BizException("课程不存在");
        }
        studentDao.lockUser(courseSchedule.getActualTeacherId());

        CourseHomework existHomework = courseHomeworkDao.findByCourseSchedule(courseScheduleId.longValue());

        //新增课堂作业
        CourseHomework courseHomework = new CourseHomework();
        List<CourseScheduleStudentPayment> courseScheduleStudentPayments = courseScheduleStudentPaymentDao.findByCourseSchedule(courseSchedule.getId());

        Set<Integer> serveStudentIds = studentServeService.getStudentWithCourse(courseSchedule.getId());
        Iterator<CourseScheduleStudentPayment> iterator = courseScheduleStudentPayments.iterator();
        while (iterator.hasNext()){
            CourseScheduleStudentPayment courseScheduleStudentPayment = iterator.next();
            if(!serveStudentIds.contains(courseScheduleStudentPayment.getUserId())){
                iterator.remove();
            }
        }

        if (Objects.nonNull(existHomework)) {
            courseHomework.setId(existHomework.getId());
            courseHomework.setContent(content);
            courseHomework.setExpiryDate(expiryDate);
            courseHomeworkService.update(courseHomework);
        } else {
            courseHomework.setContent(content);
            courseHomework.setCourseScheduleId(courseSchedule.getId());
            courseHomework.setMusicGroupId(courseSchedule.getMusicGroupId());
            courseHomework.setGroupType(courseSchedule.getGroupType());
            courseHomework.setClassGroupId(courseSchedule.getClassGroupId());
            courseHomework.setExpiryDate(expiryDate);
            courseHomework.setExpectNum(CollectionUtils.isEmpty(courseScheduleStudentPayments) ? 0 : courseScheduleStudentPayments.size());
            courseHomeworkService.insert(courseHomework);
        }

        if (!CollectionUtils.isEmpty(courseScheduleStudentPayments)) {
            Teacher teacher = teacherDao.get(courseSchedule.getActualTeacherId());
            String dateStr = DateUtil.dateToString(DateUtil.addDays(date, 3), "MM月dd日");
            for (CourseScheduleStudentPayment courseScheduleStudentPayment : courseScheduleStudentPayments) {
                StudentCourseHomework studentCourseHomework = new StudentCourseHomework();
                if (Objects.isNull(existHomework)) {
                    studentCourseHomework.setCourseHomeworkId(courseHomework.getId());
                    studentCourseHomework.setUserId(courseScheduleStudentPayment.getUserId());
                    studentCourseHomework.setCourseScheduleId(courseSchedule.getId());
                    studentCourseHomework.setCreateTime(date);
                    studentCourseHomework.setUpdateTime(date);
                    studentCourseHomework.setStatus(YesOrNoEnum.NO);
                    studentCourseHomework.setIsView(YesOrNoEnum.NO);
                    studentCourseHomework.setIsReplied(YesOrNoEnum.NO);
                    studentCourseHomework.setIsRepliedTimely(0);
                    studentCourseHomeworkDao.insert(studentCourseHomework);
                } else {
                    studentCourseHomework = studentCourseHomeworkDao.findByStudentAndCourseHomewok(existHomework.getId(), courseScheduleStudentPayment.getUserId());
                }

                Map<Integer, String> userMap = new HashMap<>();
                userMap.put(courseScheduleStudentPayment.getUserId(), courseScheduleStudentPayment.getUserId().toString());
                String notifyUrl = "?courseScheduleID=" + courseSchedule.getId() + "&studentCourseHomeworkId=" + studentCourseHomework.getId() + "&extra=0";
                String extra = "dayaedu" + notifyUrl + "&userId=" + courseScheduleStudentPayment.getUserId();

                sysMessageService.batchSendImMessage(MessageTypeEnum.IM_HOMEWORK_REMIND, courseSchedule.getActualTeacherId().toString(), extra,
                        new String[]{courseScheduleStudentPayment.getUserId().toString()},
                        null, courseSchedule.getName(), dateStr, courseHomework.getContent());

                sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.HOMEWORK_REMIND,
                        userMap, null, 0, 3 + notifyUrl, "STUDENT", teacher.getRealName(), courseSchedule.getName(), dateStr);
            }

            List<Integer> studentIds = courseScheduleStudentPayments.stream().map(CourseScheduleStudentPayment::getUserId).collect(Collectors.toList());
            studentServeService.updateExercisesSituation(courseSchedule.getClassDate(), studentIds, courseSchedule.getActualTeacherId());
        }

        return courseHomework;
    }

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

        List<CourseReviewDto> dataList = null;
        int count = courseScheduleReviewDao.countVipCourseReviews(params);
        if (count > 0) {
            pageInfo.setTotal(count);
            params.put("offset", pageInfo.getOffset());
            dataList = courseScheduleReviewDao.getVipCourseReviewList(params);
            if (dataList != null && dataList.size() > 0) {
                Set<Integer> organIds = dataList.stream().map(CourseReviewDto::getOrganId).collect(Collectors.toSet());
                Map<Integer, String> organNames = MapUtil.convertMybatisMap(organizationDao.findOrganNameMapList(organIds));
                dataList.forEach(e -> {
                    e.setOrganName(organNames.get(e.getOrganId()));
                });
            }
        }
        if (count == 0) {
            dataList = new ArrayList<>();
        }
        pageInfo.setRows(dataList);
        return pageInfo;

    }
}
