package com.yonge.cooleshow.biz.dal.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yonge.cooleshow.biz.dal.dao.CourseScheduleDao;
import com.yonge.cooleshow.biz.dal.dao.StudentDao;
import com.yonge.cooleshow.biz.dal.dao.SubjectDao;
import com.yonge.cooleshow.biz.dal.dao.UserBindingTeacherDao;
import com.yonge.cooleshow.biz.dal.entity.Student;
import com.yonge.cooleshow.biz.dal.entity.StudentAttendance;
import com.yonge.cooleshow.biz.dal.entity.Subject;
import com.yonge.cooleshow.biz.dal.entity.UserBindingTeacher;
import com.yonge.cooleshow.biz.dal.enums.CourseScheduleEnum;
import com.yonge.cooleshow.biz.dal.enums.StudentCourseEnum;
import com.yonge.cooleshow.biz.dal.mapper.CourseScheduleMapper;
import com.yonge.cooleshow.biz.dal.mapper.StudentMapper;
import com.yonge.cooleshow.biz.dal.mapper.SubjectMapper;
import com.yonge.cooleshow.biz.dal.queryInfo.TeacherBindingUserQueryInfo;
import com.yonge.cooleshow.biz.dal.service.*;
import com.yonge.cooleshow.biz.dal.vo.LiveCourseGroupStudentCourseVo;
import com.yonge.cooleshow.biz.dal.vo.userBindingTeacher.UserBindingCourseWrapper;
import com.yonge.cooleshow.biz.dal.vo.userBindingTeacher.UserBindingTeacherWrapper;
import com.yonge.cooleshow.common.constant.SysConfigConstant;
import com.yonge.cooleshow.common.enums.YesOrNoEnum;
import com.yonge.toolset.base.exception.BizException;
import com.yonge.toolset.base.util.StringUtil;
import com.yonge.toolset.utils.date.DateUtil;
import org.joda.time.DateTime;
import org.joda.time.Period;
import org.joda.time.PeriodType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

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

/**
 * @Author: cy
 * @Date: 2022/5/26
 */
@Service("userBindingTeacherService")
public class UserBindingTeacherServiceImpl extends ServiceImpl<UserBindingTeacherDao, UserBindingTeacher>
        implements UserBindingTeacherService {
    private final static Logger log = LoggerFactory.getLogger(UserBindingTeacherServiceImpl.class);

    @Autowired
    private SysConfigService sysConfigService;

    @Autowired
    private StudentDao studentDao;

    @Autowired
    private SubjectDao subjectDao;

    @Autowired
    private CourseScheduleDao courseScheduleDao;

    @Autowired
    private StudentAttendanceService studentAttendanceService;

    @Override
    public void unbindTask() {
        String days = sysConfigService.findConfigValue(SysConfigConstant.PIANO_ROOM_UNBIND_DAYS);
        int i = Integer.parseInt(days);
        List<UserBindingTeacher> userBindingTeachers = baseMapper.queryUnbindList(i);
        if (!CollectionUtils.isEmpty(userBindingTeachers)) {
            removeByIds(userBindingTeachers.stream().map(UserBindingTeacher::getId).collect(Collectors.toList()));
        }
    }

    @Override
    public IPage<UserBindingTeacherWrapper> selectBindingUserPage(IPage<UserBindingTeacherWrapper> page, TeacherBindingUserQueryInfo.BindingUserQuery query) {
        if (query.getTeacherId() == null) {
            throw new BizException("老师id不能为空");
        }

        IPage<UserBindingTeacherWrapper> bindingUserPage = baseMapper.selectBindingUserPage(page, query);

        List<UserBindingTeacherWrapper> records = bindingUserPage.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return bindingUserPage;
        }

        // 学生id集合
        List<Long> studentIdList = records.stream()
                                          .map(UserBindingTeacherWrapper::getUserId)
                                          .collect(Collectors.toList());


        // 生日
        records.forEach(userBindingTeacherWrapper -> {
            Integer age = null;
            if (userBindingTeacherWrapper.getBirthdate() != null) {
                age = new Period(new DateTime(userBindingTeacherWrapper.getBirthdate()), DateTime.now(), PeriodType.years()).getYears();
            }
            userBindingTeacherWrapper.setAge(age);
        });

        // vip
        List<Student> students = studentDao.selectBatchIds(studentIdList);

        Map<Long, YesOrNoEnum> userIdVipMap = students.stream()
                                                      .collect(Collectors.toMap(Student::getUserId,
                                           student -> student.getMembershipEndTime() != null && student.getMembershipEndTime()
                                           .compareTo(new Date()) > 0?YesOrNoEnum.YES:YesOrNoEnum.NO, (o, n) -> n));

        // 声部
        List<Long> subjectIdList = new ArrayList<>();
        for (Student student1 : students) {
            if (!StringUtil.isEmpty(student1.getSubjectId())) {
                Long aLong = Long.valueOf(student1.getSubjectId());
                subjectIdList.add(aLong);
            }
        }
        List<Subject> subjectList = subjectDao.findBySubjectIds(subjectIdList);
        Map<Long, String> userIdSubjectMap = students.stream()
                      .collect(Collectors.toMap(Student::getUserId,student -> subjectList.stream()
                                 .filter(subject -> student.getSubjectId().equals(subject.getId().toString())).findFirst().get().getName(), (o, n) -> n));

        // 课程数
        List<UserBindingTeacherWrapper.CourseNum> courseNumList = courseScheduleDao.selectStudentPianoCourse(query.getTeacherId(),studentIdList);
        Map<Long, List<UserBindingTeacherWrapper.CourseNum>> userIdCourseStatusMap = courseNumList.stream()
                                                                                    .collect(Collectors.groupingBy(
                                                                                            UserBindingTeacherWrapper.CourseNum::getStudentId));

        for (UserBindingTeacherWrapper record : records) {
            record.setIsVip(userIdVipMap.get(record.getUserId()));
            record.setSubjectName(userIdSubjectMap.get(record.getUserId()));

            List<UserBindingTeacherWrapper.CourseNum> courseNums = userIdCourseStatusMap.get(record.getUserId());

            Integer endCourseNum = 0;
            Integer noStartCourseNum = 0;
            record.setCourseNum(0);
            if (!CollectionUtils.isEmpty(courseNums)) {
                record.setCourseNum(courseNums.size());
                for (UserBindingTeacherWrapper.CourseNum courseNum : courseNums) {
                    if (courseNum.getStatus().equals("COMPLETE")) {
                        endCourseNum++;
                    } else {
                        noStartCourseNum++;
                    }
                }
            }
            record.setEndCourseNum(endCourseNum);
            record.setNoStartCourseNum(noStartCourseNum);

        }
        bindingUserPage.setRecords(records);
        return bindingUserPage;
    }

    @Override
    public IPage<UserBindingCourseWrapper> selectBindingUserCoursePage(IPage<UserBindingCourseWrapper> page, TeacherBindingUserQueryInfo.BindingStudentCourseQuery query) {
        IPage<UserBindingCourseWrapper> userBindingCourseWrapperIPage = courseScheduleDao.selectBindingUserCoursePage(
                page, query);
        List<UserBindingCourseWrapper> records = userBindingCourseWrapperIPage.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return  userBindingCourseWrapperIPage;
        }

        // 声部
        List<Long> subjectIdList = records.stream().map(UserBindingCourseWrapper::getSubjectId)
                                          .collect(Collectors.toList());
        List<Subject> subjectList = subjectDao.findBySubjectIds(subjectIdList);
        Map<Long, String> subjectIdSubjectNameMap = subjectList.stream()
                                                     .collect(Collectors.toMap(Subject::getId,Subject::getName, (o, n) -> n));

        // 考勤
        List<Long> courseIdList = records.stream().map(UserBindingCourseWrapper::getCourseId).collect(Collectors.toList());
        List<StudentAttendance> studentAttendanceList = studentAttendanceService.lambdaQuery()
                                                               .in(StudentAttendance::getCourseScheduleId, courseIdList)
                                                               .list();
        Set<Long> courseAttendanceList = studentAttendanceList.stream()
                                                 .map(StudentAttendance::getCourseScheduleId)
                                                 .collect(Collectors.toSet());

        // 设置学生上课状态
        for (UserBindingCourseWrapper record : records) {
            record.setSubjectName(subjectIdSubjectNameMap.get(record.getSubjectId()));
            if (CourseScheduleEnum.NOT_START.getCode().equals(record.getCourseStatus())) {
                record.setStatus(StudentCourseEnum.NOTSTART);
            } else {
                if (courseAttendanceList.contains(record.getCourseId())) {
                    record.setStatus(StudentCourseEnum.ATTENDCLASS);
                } else {
                    record.setStatus(StudentCourseEnum.TRUANT);
                }
            }
        }
        userBindingCourseWrapperIPage.setRecords(records);
        return userBindingCourseWrapperIPage;
    }
}

