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

import com.ym.mec.biz.dal.dao.*;
import com.ym.mec.biz.dal.dto.CourseScheduleDto;
import com.ym.mec.biz.dal.dto.StudentNameAndPhoneDto;
import com.ym.mec.biz.dal.entity.CourseSchedule;
import com.ym.mec.biz.dal.entity.SysConfig;
import com.ym.mec.biz.dal.enums.ClassGroupStudentStatusEnum;
import com.ym.mec.biz.dal.enums.CourseStatusEnum;
import com.ym.mec.biz.dal.enums.GroupType;
import com.ym.mec.biz.service.SysConfigService;
import com.ym.mec.biz.service.TeacherCourseScheduleService;
import com.ym.mec.common.exception.BizException;
import com.ym.mec.util.collection.MapUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

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

/**
 * @Author Joburgess
 * @Date 2020/3/10
 */
@Service
public class TeacherCourseScheduleServiceImpl implements TeacherCourseScheduleService {

    @Autowired
    private CourseScheduleDao courseScheduleDao;
    @Autowired
    private SubjectDao subjectDao;
    @Autowired
    private StudentAttendanceDao studentAttendanceDao;
    @Autowired
    private ClassGroupStudentMapperDao classGroupStudentMapperDao;
    @Autowired
    private SysConfigService sysConfigService;

    @Override
    public List<Date> findTeacherHaveClassesDates(Integer teacherId, Date month, String groupId, GroupType type) {
        return courseScheduleDao.findHaveClassesDatesWithMonth(teacherId,month,groupId,type);
    }

    @Override
    public List<CourseScheduleDto> findCourseSchedulesWithDate(Integer teacherId, Date classDate, String groupId, GroupType groupType) {
        Date now = new Date();
        if(Objects.isNull(classDate)){
            classDate=now;
        }
        List<CourseScheduleDto> teacherCourseSchedulesWithDate = courseScheduleDao.findCourseSchedulesWithDate(teacherId,classDate,groupId,groupType);
        List<Long> allCourseScheduleIds = teacherCourseSchedulesWithDate.stream().map(CourseScheduleDto::getId).collect(Collectors.toList());
        List<Long> courseScheduleIds = teacherCourseSchedulesWithDate.stream().map(CourseScheduleDto::getId).collect(Collectors.toList());

        Map<Integer, String> subjectNameCourseMap = new HashMap<>();
        Map<Integer, String> subjectIdCourseMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(courseScheduleIds)) {
            List<Map<Integer, String>> subjectNameCourseMaps = subjectDao.findSubjectNameCourseMaps(courseScheduleIds);
            List<Map<Integer, String>> subjectIdCourseMaps = subjectDao.findClassGroupSubjectId(courseScheduleIds);
            subjectNameCourseMap = MapUtil.convertMybatisMap(subjectNameCourseMaps);
            subjectIdCourseMap = MapUtil.convertMybatisMap(subjectIdCourseMaps);
        }
        List<Map<Integer, Integer>> studentNumCourseMaps = null;
        if (!CollectionUtils.isEmpty(allCourseScheduleIds)) {
            studentNumCourseMaps = studentAttendanceDao.countStudentAttendancesByCourses(allCourseScheduleIds);
        }
        Map<Integer, Long> studentNumCourseMap = new HashMap<>();
        if (Objects.nonNull(studentNumCourseMaps)) {
            studentNumCourseMap = MapUtil.convertIntegerMap(studentNumCourseMaps);
        }

        if(CollectionUtils.isEmpty(teacherCourseSchedulesWithDate)){
            return teacherCourseSchedulesWithDate;
        }

        List<Integer> classGroupIds = teacherCourseSchedulesWithDate.stream().map(CourseScheduleDto::getClassGroupId).collect(Collectors.toList());
        List<Map<Integer, Integer>> classGroupStudentNumMaps = classGroupStudentMapperDao.countClassGroupsStudentNum(classGroupIds, ClassGroupStudentStatusEnum.NORMAL);
        Map<Integer, Long> classGroupStudentNumMap = MapUtil.convertIntegerMap(classGroupStudentNumMaps);

        SysConfig advanceLeaveHoursConfig = sysConfigService.findByParamName(SysConfigService.ADVANCE_LEAVE_HOURS);
        Integer advanceLeaveHours=advanceLeaveHoursConfig.getParanValue(Integer.class);
        List<Map<Long, Integer>> courseLeaveStudentNumMaps = studentAttendanceDao.countCourseLeaveStudentNumWithFourHoursAgo(allCourseScheduleIds, advanceLeaveHours);
        Map<Long,Long> courseLeaveStudentNumMap = MapUtil.convertIntegerMap((courseLeaveStudentNumMaps));

        for (CourseScheduleDto courseScheduleDto : teacherCourseSchedulesWithDate) {
            Long studentNum = studentNumCourseMap.get(courseScheduleDto.getId());
            if (Objects.nonNull(studentNum)) {
                courseScheduleDto.setStudentAttendanceIsFirstTime(studentNum > 0 ? 0 : 1);
            } else {
                courseScheduleDto.setStudentAttendanceIsFirstTime(1);
            }

            if (now.before(courseScheduleDto.getStartClassTime())) {
                courseScheduleDto.setStatus(CourseStatusEnum.NOT_START);
            } else if (now.after(courseScheduleDto.getEndClassTime())) {
                courseScheduleDto.setStatus(CourseStatusEnum.OVER);
            } else {
                courseScheduleDto.setStatus(CourseStatusEnum.UNDERWAY);
            }
            if (Objects.nonNull(courseScheduleDto.getClassGroupId())) {
                List<StudentNameAndPhoneDto> courseStudentNameAndPhone = classGroupStudentMapperDao.findCourseStudentNameAndPhone(courseScheduleDto.getId().intValue());
                if(!CollectionUtils.isEmpty(courseStudentNameAndPhone)){
                    List<String> studentNames = courseStudentNameAndPhone.stream().map(StudentNameAndPhoneDto::getUserName).collect(Collectors.toList());
                    courseScheduleDto.setStudentNames(org.apache.commons.lang3.StringUtils.join(studentNames, ","));
                    courseScheduleDto.setStudents(courseStudentNameAndPhone);
                }
            }
            courseScheduleDto.setSubjectName(subjectNameCourseMap.get(courseScheduleDto.getId()));
            courseScheduleDto.setSubjectId(subjectIdCourseMap.get(courseScheduleDto.getId()));
            Long leaveStudentNum = courseLeaveStudentNumMap.get(courseScheduleDto.getId());
            Long normalStudentNum = classGroupStudentNumMap.get(courseScheduleDto.getClassGroupId());
            if(Objects.nonNull(leaveStudentNum)&&Objects.nonNull(normalStudentNum)&&leaveStudentNum.intValue()==normalStudentNum.intValue()){
                courseScheduleDto.setEnableAdjustInToday(1);
            }
        }
        return teacherCourseSchedulesWithDate;
    }

    @Override
    public List<CourseScheduleDto> findGroupClassesWithCourse(Long courseScheduleId) {
        if(Objects.isNull(courseScheduleId)){
            throw new BizException("请指定课程");
        }
        CourseSchedule currentCourseSchedule = courseScheduleDao.get(courseScheduleId);
        List<CourseScheduleDto> teacherCourseSchedulesWithDate = courseScheduleDao.findCourseSchedulesWithDate(null,null,currentCourseSchedule.getMusicGroupId(),currentCourseSchedule.getGroupType());
        List<CourseScheduleDto> notStartClasses=new ArrayList<>();
        List<CourseScheduleDto> overClasses=new ArrayList<>();
        CourseScheduleDto currentClasses=null;
        Date now=new Date();
        for (CourseScheduleDto courseScheduleDto : teacherCourseSchedulesWithDate) {
            if(currentCourseSchedule.getId().equals(courseScheduleDto.getId())){
                currentClasses=courseScheduleDto;
                continue;
            }
            if(courseScheduleDto.getEndClassTime().before(now)){
                overClasses.add(courseScheduleDto);
            }else{
                notStartClasses.add(courseScheduleDto);
            }
        }

        List<CourseScheduleDto> courseSchedules=new ArrayList<>();
        courseSchedules.add(currentClasses);
        courseSchedules.addAll(notStartClasses);
        courseSchedules.addAll(overClasses);

        return courseSchedules;
    }
}
