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

import com.ym.mec.biz.dal.dao.ClassGroupDao;
import com.ym.mec.biz.dal.dao.MusicGroupPaymentCalenderDao;
import com.ym.mec.biz.dal.dao.TeacherDao;
import com.ym.mec.biz.dal.dto.*;
import com.ym.mec.biz.dal.entity.*;
import com.ym.mec.biz.dal.enums.*;
import com.ym.mec.biz.dal.page.VipClassQueryInfo;
import com.ym.mec.biz.service.*;
import com.ym.mec.common.dal.BaseDAO;
import com.ym.mec.common.entity.ImGroupModel;
import com.ym.mec.common.page.PageInfo;
import com.ym.mec.common.service.impl.BaseServiceImpl;
import com.ym.mec.util.collection.MapUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;

@Service
public class ClassGroupServiceImpl extends BaseServiceImpl<Integer, ClassGroup> implements ClassGroupService {

    @Autowired
    private ClassGroupDao classGroupDao;
    @Autowired
    private TeacherDao teacherDao;
    @Autowired
    private MusicGroupPaymentCalenderDao musicGroupPaymentCalenderDao;
    @Autowired
    private ClassGroupRelationService classGroupRelationService;
    @Autowired
    private ClassGroupStudentMapperService classGroupStudentMapperService;
    @Autowired
    private ClassGroupTeacherMapperService classGroupTeacherMapperService;
    @Autowired
    private TeacherDefaultMusicGroupSalaryService teacherDefaultMusicGroupSalaryService;
    @Autowired
    private CourseScheduleService courseScheduleService;
    @Autowired
    private StudentRegistrationService studentRegistrationService;
    @Autowired
    private ClassGroupTeacherSalaryService classGroupTeacherSalaryService;

    @Override
    public BaseDAO<Integer, ClassGroup> getDAO() {
        return classGroupDao;
    }

    @Override
    public List<ClassGroup> findClassGroup4Teacher(Integer teacherId) {
        return classGroupDao.findClassGroup4Teacher(teacherId);
    }

    @Override
    public List<ClassGroup> findClassGroup(Integer musicGroupId, Integer mixClassGroupId) {
        if (null == mixClassGroupId) {
            return classGroupDao.findAllMixClassGroup(musicGroupId);
        } else {
            return classGroupDao.findMixClassChildClassGroup(mixClassGroupId);
        }
    }

    @Override
    public List<ClassGroup> findAllNormalClassGroupByMusicGroupId(int musicGroupId) {
        return classGroupDao.findAllNormalClassGroupByMusicGroupId(musicGroupId);
    }

    @Override
    public List<ClassGroup> findAllMixClassGroupByMusicGroupId(int musicGroupId) {
        List<ClassGroup> allMixClassGroup = classGroupDao.findAllMixClassGroup(musicGroupId);
        for (ClassGroup mixClassGroup : allMixClassGroup) {
            mixClassGroup.setClassNames(classGroupDao.findMixClassChildClassGroupNames(mixClassGroup.getId()).getName());
        }
        return allMixClassGroup;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ClassGroup addClassGroup(ClassGroup classGroup) throws Exception {
        Date date;
        date = new Date();
        classGroup.setCreateTime(date);
        classGroup.setUpdateTime(date);
        classGroup.setType(ClassGroupTypeEnum.NORMAL);
        String userIds = classGroup.getUserIds();
        String[] userIdArr = userIds.split(",");

        classGroup.setStudentNum(userIdArr.length);
        Long classGroupId = this.insert(classGroup);

        //2、插入班级学生关联关系
        List<ClassGroupStudentMapper> classGroupStudentList = new ArrayList<>();
        for (String userId : userIdArr) {
            ClassGroupStudentMapper classGroupStudentMapper = new ClassGroupStudentMapper();
            classGroupStudentMapper.setClassGroupId(classGroupId.intValue());
            classGroupStudentMapper.setUserId(Integer.getInteger(userId));
            classGroupStudentMapper.setCreateTime(date);
            classGroupStudentMapper.setStatus(ClassGroupStudentStatusEnum.NORMAL);
            classGroupStudentList.add(classGroupStudentMapper);
            StudentRegistration studentRegistration = new StudentRegistration();
            studentRegistration.setClassGroupId(classGroupId.intValue());
            studentRegistration.setUserId(Integer.getInteger(userId));
            studentRegistration.setMusicGroupId(classGroup.getMusicGroupId());
            studentRegistrationService.updateByUserIdAndMusicGroupId(studentRegistration);
        }

        classGroupStudentMapperService.classGroupStudentsInsert(classGroupStudentList);

        return classGroup;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ClassGroup addMixClassGroup(int musicGroupId, String name, String classGroupIds) throws Exception {
        Date date;
        date = new Date();

        List<ClassGroup> classGroups = findClassGroupByIds(classGroupIds);
        int studentNum = 0; //学生数
        String subjectIds = "";
        for (ClassGroup classGroup : classGroups) {
            studentNum += classGroup.getStudentNum();
            subjectIds += subjectIds.isEmpty() ? classGroup.getSubjectIdList() : "," + classGroup.getSubjectIdList();
        }

        //1、插入班级
        ClassGroup classGroup = new ClassGroup();
        classGroup.setMusicGroupId(musicGroupId);
        classGroup.setSubjectIdList(subjectIds);
        classGroup.setName(name);
        classGroup.setType(ClassGroupTypeEnum.MIX);
        classGroup.setCreateTime(date);
        classGroup.setUpdateTime(date);
        Long classGroupId = this.insert(classGroup);

        //2、插入班级关联关系
        List<ClassGroupRelation> classGroupRelationList = new ArrayList<>();
        for (ClassGroup cGroup : classGroups) {
            ClassGroupRelation classGroupRelation = new ClassGroupRelation();
            classGroupRelation.setClassGroupId(classGroupId.intValue());
            classGroupRelation.setSubClassGroupId(cGroup.getId());
            classGroupRelation.setCreateTime(date);
            classGroupRelationList.add(classGroupRelation);
        }
        classGroupRelationService.classGroupRelationsInsert(classGroupRelationList);
        return classGroup;
    }

    @Override
    public List<ClassGroup> findClassGroupByIds(String ids) {
        return classGroupDao.findClassGroupByIds(ids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<HighClassGroup> addHighClassGroup(List<HighClassGroup> highClassGroupList) throws Exception {
        for (HighClassGroup highClassGroup : highClassGroupList) {
            //1、插入班级信息
            Date date;
            date = new Date();
            highClassGroup.setCreateTime(date);
            highClassGroup.setUpdateTime(date);
            highClassGroup.setType(ClassGroupTypeEnum.HIGH);
            Long classGroupId = this.insert(highClassGroup);

            //2、插入班级关联老师
            TeacherDefaultMusicGroupSalary teacherSalary = teacherDefaultMusicGroupSalaryService.getTeacherSalaryByUserIdAndType(highClassGroup.getUserId(), ClassGroupTypeEnum.HIGH);
            ClassGroupTeacherMapper classGroupTeacherMapper = new ClassGroupTeacherMapper();
            classGroupTeacherMapper.setMusicGroupId(highClassGroup.getUserId());
            classGroupTeacherMapper.setClassGroupId(classGroupId.intValue());
            classGroupTeacherMapper.setTeacherRole(TeachTypeEnum.BISHOP);
            classGroupTeacherMapper.setUserId(highClassGroup.getUserId());
            classGroupTeacherMapper.setSalary(teacherSalary.getMainTeacherSalary());
            classGroupTeacherMapper.setCreateTime(date);
            classGroupTeacherMapper.setUpdateTime(date);
            classGroupTeacherMapperService.insert(classGroupTeacherMapper);

            //3、插入班级排课信息
            List<CourseSchedule> courseScheduleList = new ArrayList<>();
            int i = 0;
            LocalDateTime now = LocalDateTime.ofInstant(highClassGroup.getStartDate().toInstant(), ZoneId.systemDefault());
            while (true) {
                now = now.plusDays(i);
                int dayOfWeek = now.getDayOfWeek().getValue();

                if (highClassGroup.getDayOfWeek().equals(dayOfWeek)) {
                    CourseSchedule courseSchedule = new CourseSchedule();
                    Instant instant = now.atZone(ZoneId.systemDefault()).toInstant();
                    Date classDate = Date.from(instant);

                    courseSchedule.setClassGroupId(classGroupId.intValue());
                    courseSchedule.setStatus(CourseStatusEnum.NOT_START);
                    courseSchedule.setClassDate(classDate);
                    courseSchedule.setStartClassTime(highClassGroup.getStartClassTime());
                    courseSchedule.setEndClassTime(highClassGroup.getEndClassTime());
                    courseSchedule.setTeacherId(highClassGroup.getUserId().longValue());
                    courseSchedule.setActualTeacherId(highClassGroup.getUserId().longValue());
                    courseSchedule.setCreateTime(date);
                    courseSchedule.setUpdateTime(date);
                    courseSchedule.setTeachMode(TeachModeEnum.OFFLINE);
                    courseScheduleList.add(courseSchedule);
                    i++;
                }
                if (highClassGroup.getCourseTimes().equals(i)) {
                    break;
                }
            }
            courseScheduleService.batchAddCourseSchedule(courseScheduleList);
        }
        return highClassGroupList;
    }

    @Override
    public List<TeacherMusicClassInfoDto> getTeacherMusicClass(Integer teacherId) {
        List<TeacherMusicClassInfoDto> teacherMusicClassInfoDtos = classGroupDao.queryGroupCourses(teacherId);
        Teacher teacher = teacherDao.get(teacherId);
        if (teacher == null) {
            return null;
        }
        teacherMusicClassInfoDtos.forEach(e -> {
            e.setJobNature(teacher.getJobNature());
        });
        return teacherMusicClassInfoDtos;
    }

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

    @Override
    public List<ClassGroupTeachers> getClassGroupAndTeachers(Integer musicGroupId) {
        List<ClassGroupTeachers> classGroupAndTeachersList = classGroupDao.findClassGroupByMusicGroupId(musicGroupId);

        List<ClassGroupTeacherMapper> classGroupTeacherMapperList = classGroupTeacherMapperService.findClassGroupTeachers(classGroupAndTeachersList);

        for (ClassGroupTeachers classGroupAndTeachers : classGroupAndTeachersList) {
            List<ClassGroupTeacherMapper> oneClassGroupTeacherMapperList = new ArrayList<>();
            for (ClassGroupTeacherMapper classGroupTeacherMapper : classGroupTeacherMapperList) {
                if (classGroupTeacherMapper.getClassGroupId().equals(classGroupAndTeachers.getId())) {
                    oneClassGroupTeacherMapperList.add(classGroupTeacherMapper);
                }
            }
            classGroupAndTeachers.setClassGroupTeacherMapperList(oneClassGroupTeacherMapperList);
        }
        return classGroupAndTeachersList;
    }

    @Override
    public List<ClassGroupTeachers> getClassGroupAndTeacherSalary(Integer musicGroupId) {
        //乐团班级及班级老师
        List<ClassGroupTeachers> classGroupAndTeachers = getClassGroupAndTeachers(musicGroupId);
        //乐团的课程计划
        List<CourseSchedule> classGroupCourseSchedules = courseScheduleService.findClassGroupCourseSchedules(classGroupAndTeachers);

        //获取乐团老师课酬
        List<ClassGroupTeacherSalary> nowClassGroupTeacherSalaryList = classGroupTeacherSalaryService.findByMusicGroupId(musicGroupId);

        //基础课时
        BigDecimal baseDuration = new BigDecimal("30");
        for (ClassGroupTeachers classGroupAndTeacher : classGroupAndTeachers) {

            Set<Long> courseScheduleDurationSet = new HashSet<>();
            for (CourseSchedule classGroupCourseSchedule : classGroupCourseSchedules) {
                if (classGroupCourseSchedule.getClassGroupId().equals(classGroupAndTeacher.getId())) {
                    //课程时长
                    long duration = (classGroupCourseSchedule.getEndClassTime().getTime() - classGroupCourseSchedule.getStartClassTime().getTime()) / (1000 * 60);
                    courseScheduleDurationSet.add(duration);
                }
            }

            //获取教师列表
            List<ClassGroupTeacherMapper> classGroupTeacherMapperList = classGroupAndTeacher.getClassGroupTeacherMapperList();

            ArrayList<ClassGroupTeacherSalary> classGroupTeacherSalaryList = new ArrayList<>();
            for (Long duration : courseScheduleDurationSet) {
                THREE:
                for (ClassGroupTeacherMapper classGroupTeacherMapper : classGroupTeacherMapperList) {

                    //已经设置跳过计算
                    for (ClassGroupTeacherSalary classGroupTeacherSalary : nowClassGroupTeacherSalaryList) {
                        if (classGroupTeacherMapper.getClassGroupId().equals(classGroupTeacherSalary.getClassGroupId()) &&
                                classGroupTeacherMapper.getUserId().equals(classGroupTeacherSalary.getUserId()) &&
                                classGroupTeacherSalary.getDuration().equals(duration)
                        ) {
                            classGroupTeacherSalaryList.add(classGroupTeacherSalary);
                            continue THREE;
                        }
                    }

                    ClassGroupTeacherSalary classGroupTeacherSalary = new ClassGroupTeacherSalary();
                    classGroupTeacherSalary.setMusicGroupId(classGroupTeacherMapper.getMusicGroupId());
                    classGroupTeacherSalary.setClassGroupId(classGroupTeacherMapper.getClassGroupId());
                    classGroupTeacherSalary.setTeacherRole(classGroupTeacherMapper.getTeacherRole());
                    classGroupTeacherSalary.setUserId(classGroupTeacherMapper.getUserId());
                    classGroupTeacherSalary.setDuration(duration.intValue());
                    BigDecimal salary = new BigDecimal(duration).divide(baseDuration).multiply(classGroupTeacherMapper.getSalary()).setScale(2, BigDecimal.ROUND_HALF_UP);
                    classGroupTeacherSalary.setSalary(salary);
                    classGroupTeacherSalaryList.add(classGroupTeacherSalary);
                }
            }
            //教师课酬列表
            classGroupAndTeacher.setClassGroupTeacherSalaryList(classGroupTeacherSalaryList);
        }
        return classGroupAndTeachers;
    }

    public List<CourseListDto> queryCoursePage(Integer userId) {
        List<CourseListDto> courseListDtos = classGroupDao.queryCoursePage(userId);
        courseListDtos.forEach(e->{
            if("VIP".equals(e.getTeachMode())){
                //获取vip课的学生名称列表
                e.setStudentNames(classGroupDao.findVipStuNames(e.getMusicGroupId()));
            }else {
                //获取学员乐团课的续费状态

                //获取当前乐团缴费周期
                List<MusicGroupPaymentCalender> musicGroupPaymentCalenders = musicGroupPaymentCalenderDao.findByMusicGroupId(e.getMusicGroupId());


            }
        });
        return classGroupDao.queryCoursePage(userId);
    }

    @Override
    public List<ImGroupModel> queryUserGroups(Integer userId) {
        return classGroupDao.queryUserGroups(userId);
    }
}