package com.xhkjedu.slive.service.liveplay;

import com.xhkjedu.slive.mapper.gradeclass.ClassTeacherMapper;
import com.xhkjedu.slive.mapper.gradeclass.SchoolMapper;
import com.xhkjedu.slive.mapper.liveplay.CourseClassMapper;
import com.xhkjedu.slive.mapper.liveplay.CourseMapper;
import com.xhkjedu.slive.mapper.liveplay.CourseSectionMapper;
import com.xhkjedu.slive.mapper.system.UserMapper;
import com.xhkjedu.slive.model.gradeclass.TClass;
import com.xhkjedu.slive.model.gradeclass.TClassTeacher;
import com.xhkjedu.slive.model.liveplay.LCourse;
import com.xhkjedu.slive.model.liveplay.LCourseClass;
import com.xhkjedu.slive.service.gradeclass.ClassService;
import com.xhkjedu.slive.vo.liveplay.*;
import com.xhkjedu.utils.N_Utils;
import com.xhkjedu.vo.ResultVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author ywx
 * @classname CourseService
 * @description
 * @date 2021/1/15 12:33
 **/
@Service
@Slf4j
public class CourseService {
    @Resource
    private CourseMapper courseMapper;
    @Resource
    private ClassService classService;
    @Resource
    private ClassTeacherMapper classTeacherMapper;
    @Resource
    private SchoolMapper schoolMapper;
    @Resource
    private UserMapper userMapper;
    @Resource
    private CourseClassMapper courseClassMapper;
    @Resource
    private CourseSectionMapper courseSectionMapper;

    //添加
    @Transactional(rollbackFor = Exception.class)
    public ResultVo save(LCourse model) {
        try {
            List<Map> users = new ArrayList<>();
            if (model.getCoursetype() == 1) {
                if (N_Utils.isListEmpty(model.getClassids())) {
                    return new ResultVo(1, "班级id集合不能为空");
                }
                users = courseMapper.listUid(model.getClassids());//获取课程学生id集合
                if (N_Utils.isListEmpty(users)) {
                    return new ResultVo(1, "直播班级学生为空");
                }
            }
            model.setStunum(0);
            model.setCoursestate(0);
            model.setCreatetime(N_Utils.getSecondTimestamp());
            String coursename = model.getCoursename();
            Integer createid = model.getCreateid();
            Integer schoolid = model.getSchoolid();
            Integer teacherid = model.getTeacherid();
            //班级信息
            TClass c = new TClass();
            c.setClassname(coursename + "班");
            c.setCreateid(createid);
            c.setSchoolid(schoolid);
            Integer year = schoolMapper.getYearById(schoolid);
            c.setSchoolyear(year);
            c.setYear(year);
            c.setClassorder(999);
            c.setGradeid(model.getGradeid());

            if (model.getCoursetype() == 1) {
                c.setClasstype(99);//已直播班级
            } else {
                c.setClasstype(3);//直播班(学生选班)
            }

            Integer classid = classService.save(c);
            if (!N_Utils.isEmptyInteger(teacherid)) {
                //班级教师
                TClassTeacher teacher = new TClassTeacher();
                teacher.setClassid(classid);
                teacher.setTeacherid(teacherid);
                teacher.setCreateid(createid);
                teacher.setCreatetime(N_Utils.getSecondTimestamp());
                teacher.setSchoolid(schoolid);

                classTeacherMapper.insertSelective(teacher);
            }
            //课程信息
            model.setClassid(classid);
            model.setDeleted(1);
            model.setCourseclass(0);
            model.setCourseschool(0);
            courseMapper.insertUseGeneratedKeys(model);
            if (model.getCoursetype() == 1) {
                Integer courseid = model.getId();
                List<Integer> studentids = new ArrayList<>();
                users.forEach(userVo -> {
                    studentids.add((Integer) userVo.get("userid"));
                });

                classService.batchSaveStu(createid, schoolid, classid, studentids);//批量添加报名学生
                courseMapper.updateStuNum(courseid);//更新已报学生数量

                //保存直播关联班级
                List<LCourseClass> cclist = new ArrayList<>();
                for(Integer cid : model.getClassids()){
                    LCourseClass cc = new LCourseClass();
                    cc.setCourseid(courseid);
                    cc.setClassid(cid);
                    cc.setCreateid(model.getCreateid());
                    cc.setCreatetime(N_Utils.getSecondTimestamp());
                    cclist.add(cc);
                }
                courseClassMapper.insertList(cclist);//保存原班级和直播的关联关系
            }
            return new ResultVo(0, "保存成功", model.getId());
        } catch (BeansException e) {
            log.error("添加课程失败", e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return new ResultVo(1, "保存失败");
        }
    }

    //删除
    @Transactional(rollbackFor = Exception.class)
    public ResultVo deleteById(Integer courseid, Integer createid) {
        LCourse course = courseMapper.selectByPrimaryKey(courseid);

        Integer usertype = userMapper.getUserTypeByUserId(createid);
        if(usertype!=0 && !createid.equals(course.getCreateid())){
            //只有学校管理员和自己创建的课程才可删除（没有删除课程权限）
            return new ResultVo(1,"没有删除课程权限");
        }
        try {
            //2021-06-07标识课程为逻辑删除deleted=10
            courseMapper.updateCourseDeleted(courseid,10);
            //标识班级状态为10
            classService.updateClassstateByClassid(course.getClassid(),10);
            return new ResultVo(0,"删除成功");
        } catch (Exception e) {
            log.error("删除课程失败",e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return new ResultVo(1,"删除失败");
        }
    }

    //修改
    public ResultVo update(LCourse model) {
        //先判断课程是否存在
        LCourse lc = courseMapper.getCourseByIdAndDeleted(model.getCourseid(),1);
        if(lc==null){
            return new ResultVo(1,"该课程已删除");
        }else{
            /*Integer createid = model.getCreateid();
            Integer usertype = userMapper.getUserTypeByUserId(createid);
            if(lc.getCoursestate()==3 || (usertype!=0 && !createid.equals(lc.getCreateid()))){
                //只有学校管理员和自己创建的课程才可以修改
                return new ResultVo(1, "没有修改课程权限");
            }*/
            model.setDeleted(null);
            model.setCoursestate(null);
            courseMapper.updateByPrimaryKeySelective(model);
            String coursename = model.getCoursename();
            if (N_Utils.isNotEmpty(coursename) && !coursename.equals(lc.getCoursename())) {
                TClass tClass = new TClass();
                tClass.setClassid(lc.getClassid());
                tClass.setClassname(coursename);
                classService.update(tClass);
            }
            return new ResultVo(0,"修改成功");
        }
    }

    //获取详情
    public CourseVo findById(LCourse course) {
        return courseMapper.findById(course);
    }

    //获取列表
    public List<CourseVo> listAll(LCourse course) {
        return courseMapper.listAll(course);
    }

    //更新已报学生数量
    public ResultVo selection(LCourse course) {
        Integer courseid = course.getCourseid();
        Integer studentid = course.getCreateid();
        LCourse c = courseMapper.selectByPrimaryKey(courseid);
        Integer schoolid = c.getSchoolid();
        if (c.getCoursestate() == 3) {
            return new ResultVo(1, "该课程已结束");
        }
        if (c.getDeleted() == 10) {
            return new ResultVo(1, "该课程已删除");
        }
        if (c.getStunum() >= c.getLimitstu()) {
            return new ResultVo(1, "该课程已报满");
        }
        int time = N_Utils.getSecondTimestamp();
        if (c.getCoursetype() == 0 && c.getLimitstamp() < time) {
            return new ResultVo(1, "该课程已经超过报名时间");
        }

        if(c.getCoursetype()==0 && c.getStarttime()>time){
            return new ResultVo(1,"该课程还未到报名时间");
        }

        //判断该用户是否已经报过该课程
       /* TClassStudent cl = classService.getByClassIdStudentId(c.getClassid(),studentid);
        if(cl!=null && cl.getCsid()>0){
            return new ResultVo(1,"已报过该课程");
        }*/

        String coursename = courseMapper.findBySchoolIdCourseIdStudentId(schoolid, courseid, studentid);
        if (N_Utils.isNotEmpty(coursename)) {
            return new ResultVo(1, "本课程时间和已报课程冲突，暂不能报名");
        }
        Integer classid = c.getClassid();
        Integer teacherid = c.getTeacherid();

        classService.saveSelection(classid, studentid, teacherid, schoolid);
        courseMapper.updateStuNum(courseid);
        return new ResultVo(0, "选课成功");
    }

    //获取学生课程列表
    public List<CourseVo> listStu(LCourse course) {
        return courseMapper.listStu(course);
    }

    //获取进行中的课节id
    public Integer findOnSection(Integer courseid) {
        return courseMapper.findOnSection(courseid);
    }

    //修改课程状态
    public ResultVo updateState(LCourse course) {
        if (course.getCoursestate() == 3) {
            Integer teacherid = course.getTeacherid();
            LCourse c = courseMapper.selectByPrimaryKey(course.getCourseid());
            Integer usertype = userMapper.getUserTypeByUserId(teacherid);
            if(usertype!=0 && !teacherid.equals(c.getCreateid())){
                //只有学校管理员和自己创建的课程才可以结课
                return new ResultVo(1, "没有结课权限");
            }

            //结课时判断是否有进行中的直播课，如果有就提示
            Integer jxznum = courseSectionMapper.getJxzSectionNum(course.getCourseid());
            if(N_Utils.isTrueInteger(jxznum)){
                return new ResultVo(1,"有进行中的课程，暂不能结课");
            }

            //如果课程状态变成已结束，则班级变成结束直播班类型
            classService.updateClasstype(c.getClassid(),99);
        }
        courseMapper.updateState(course);
        return new ResultVo(0,"修改成功");
    }

    //学生取消选课
    public ResultVo cancelSelection(LCourse course) {
        Integer studentid = course.getCreateid();
        Integer courseid = course.getCourseid();
        LCourse c = courseMapper.selectByPrimaryKey(courseid);
        int time = N_Utils.getSecondTimestamp();
        if (c.getCourseselected() == 0) {
            return new ResultVo(1, "禁止取消报名");
        }
        if (c.getCoursetype() == 0 && c.getLimitstamp() < time) {
            return new ResultVo(1, "该课程已过报名截止时间，禁止取消报名");
        }
        if(c.getCoursetype()==0 && c.getStarttime()>time){
            return new ResultVo(1,"不在报名时间范围内");
        }
        Integer classid = c.getClassid();
        classService.cancelSelection(classid, studentid);
        courseMapper.updateStuNum(courseid);
        return new ResultVo(0, "取消选课成功");
    }

    //添加学生
    public ResultVo addStu(LCourse course) {
        Integer courseid = course.getCourseid();
        Integer teacherid1 = course.getTeacherid();
        LCourse c = courseMapper.selectByPrimaryKey(courseid);
        /*Integer usertype = userMapper.getUserTypeByUserId(teacherid1);
        if(c.getCoursestate()==3 || (usertype!=0 && !teacherid1.equals(c.getCreateid()))) {
            return new ResultVo(1, "没有添加学生权限");
        }*/
        if (c.getCoursetype() == 0 && c.getStunum() >= c.getLimitstu()) {
            return new ResultVo(1, "该课程已报满");
        }
        Integer classid = c.getClassid();
        Integer teacherid = c.getTeacherid();
        Integer schoolid = c.getSchoolid();
        Integer studentid = userMapper.getUserIdByNameAndSid(course.getCreatename(),schoolid);
        if (studentid == null) {
            return new ResultVo(1, "该学校学生账号不存在");
        }
        classService.saveSelection(classid, studentid, teacherid, schoolid);
        courseMapper.updateStuNum(courseid);
        return new ResultVo(0, "保存成功");
    }

    //给课节未结束的课程添加巡课学生
    public ResultVo addXkStu(String loginname) {
        Map user = userMapper.getObjByLoginName(loginname);
        if (user == null || !user.get("usertype").equals(2) || !user.get("userstate").equals(1)) return new ResultVo(1,"该学生账号不存在");
        Integer studentid = (Integer) user.get("userid");
        Integer schoolid = (Integer) user.get("schoolid");
        //课节未结束的课程列表
        List<LCourse> courses = courseMapper.listCourse(schoolid);
        for (LCourse course : courses) {
            Integer courseid = course.getCourseid();
            classService.saveSelection(course.getClassid(), studentid, course.getCreateid(), schoolid);
            courseMapper.updateStuNum(courseid);
        }
        return new ResultVo(0, "保存成功");
    }

    //给今天以后行政和提高班的课程添加学生
    public ResultVo addXzStu(String loginname) {
        //根据登录名获取学生id和行政和提高班班级id
        Map user = userMapper.getObjByLoginName2(loginname);
        if (user == null || !user.get("usertype").equals(2) || !user.get("userstate").equals(1)) return new ResultVo(1,"该学生账号不存在");
        Integer studentid = (Integer) user.get("userid");
        Integer schoolid = (Integer) user.get("schoolid");
        String classids = user.get("ultype").toString();
        //今天以后行政和提高班的课程列表
        List<LCourse> courses = courseMapper.listCourse2(classids);
        for (LCourse course : courses) {
            Integer courseid = course.getCourseid();
            classService.saveSelection(course.getClassid(), studentid, course.getCreateid(), schoolid);
            courseMapper.updateStuNum(courseid);
        }
        return new ResultVo(0, "保存成功");
    }

    //分类下课程
    public List<CourseTypeVo> listAllForStu(LCourse course) {
        course.setCreatetime(N_Utils.getSecondTimestamp());
        //获取所有课程
        List<CourseVo> courselst = courseMapper.listAllForStu(course);

        List<CourseTypeVo> lst = new ArrayList<>();

        //处理成分类下课程
        if (courselst != null && courselst.size() > 0) {
            for (CourseVo c : courselst) {
                if (c.getCtypeid() == null) {
                    c.setCtypeid(0);
                }

                if (!isExistCoursetype(lst, c.getCtypeid())) {
                    List<CourseVo> clist = new ArrayList<>();
                    clist.add(c);
                    CourseTypeVo courseTypeVo = new CourseTypeVo(c.getCtypeid(), c.getTypename(), clist);
                    lst.add(courseTypeVo);
                } else {
                    for (CourseTypeVo ct : lst) {
                        if (ct.getCtypeid().equals(c.getCtypeid())) {
                            ct.getCourselist().add(c);
                        }
                    }
                }
            }
        }

        return lst;

    }

    private boolean isExistCoursetype(List<CourseTypeVo> ctypes, Integer ctypeid) {
        for (int i = 0; i < ctypes.size(); i++) {
            if (ctypes.get(i).getCtypeid().equals(ctypeid)) {
                return true;
            }
        }
        return false;
    }

    //课程分类列表
    public List<CTypeVo> listType(LCourse course) {
        return courseMapper.listType(course);
    }

    //课程列表
    public List<CourseVo> listAllForStu2(LCourse course) {
        course.setCreatetime(N_Utils.getSecondTimestamp());
        return courseMapper.listAllForStu2(course);
    }

    //删除学生
    public ResultVo delStu(LCourse course) {
        Integer studentid = course.getCreateid();
        Integer courseid = course.getCourseid();
        Integer teacherid = course.getTeacherid();
        LCourse c = courseMapper.selectByPrimaryKey(courseid);
        /*Integer usertype = userMapper.getUserTypeByUserId(teacherid);
        if(c.getCoursestate()==3 || (usertype!=0 && !teacherid.equals(c.getCreateid()))) {
            return new ResultVo(1, "没有删除学生权限");
        }*/
        Integer classid = c.getClassid();
        classService.cancelSelection(classid, studentid);
        courseMapper.updateStuNum(courseid);
        return new ResultVo(0, "取消选课成功");
    }

    //删除学生所有直播课
    public ResultVo delXzStu(String loginname) {
        Integer studentid = userMapper.getUserIdByNameAndSid(loginname,null);
        List<LCourse> courses = courseMapper.listCourse3(studentid);
        for (LCourse course : courses) {
            classService.cancelSelection(course.getClassid(), studentid);
            courseMapper.updateStuNum(course.getCourseid());
        }
        return new ResultVo(0, "取消选课成功");
    }

    //删除学生指定班级直播课
    public ResultVo delClassStu(String loginname, Integer classid) {
        Integer studentid = userMapper.getUserIdByNameAndSid(loginname,null);
        List<LCourse> courses = courseMapper.listCourse4(studentid, classid);
        for (LCourse course : courses) {
            classService.cancelSelection(course.getClassid(), studentid);
            courseMapper.updateStuNum(course.getCourseid());
        }
        return new ResultVo(0, "取消选课成功");
    }

    //添加学生指定班级直播课
    public ResultVo addClassStu(String loginname, Integer classid) {
        //根据登录名获取学生id和行政和提高班班级id
        Map user = userMapper.getObjByLoginName2(loginname);
        if (user == null || !user.get("usertype").equals(2) || !user.get("userstate").equals(1)) return new ResultVo(1,"该学生账号不存在");
        Integer studentid = (Integer) user.get("userid");
        Integer schoolid = (Integer) user.get("schoolid");
        String classids = classid.toString();
        //今天以后行政和提高班的课程列表
        List<LCourse> courses = courseMapper.listCourse2(classids);
        for (LCourse course : courses) {
            Integer courseid = course.getCourseid();
            classService.saveSelection(course.getClassid(), studentid, course.getCreateid(), schoolid);
            courseMapper.updateStuNum(courseid);
        }
        return new ResultVo(0, "保存成功");
    }

    //删除指定班级直播课
    @Transactional(rollbackFor = Exception.class)
    public ResultVo delClass(Integer courseid, Integer classid, String classids) {
        courseMapper.delClass(classids, classid, courseid);//删除直播课指定班级下的所有学生和班级
        classService.updateNum(classid);//更新直播班学生数量
        courseMapper.updateStuNum(courseid);//更新直播课学生数量
        return new ResultVo(0, "取消选课成功");
    }

    //删除指定班级直播课（课程班级里没有班级信息）
    @Transactional(rollbackFor = Exception.class)
    public ResultVo delClass2(Integer courseid, Integer classid, String classids) {
        courseMapper.delClass2(classids, classid, courseid);//删除直播课指定班级下的所有学生
        classService.updateNum(classid);//更新直播班学生数量
        courseMapper.updateStuNum(courseid);//更新直播课学生数量
        return new ResultVo(0, "取消选课成功");
    }

    //指定月份课程日期数量
    public List<SectionDateVo> listSectionDateForStu(CourseParams p) {
        return courseMapper.listSectionDateForStu(p);
    }

    //指定日期的课节列表
    public List<CourseSectionVo> listSectionsByDate(CourseParams p){
        int timestamp = N_Utils.getSecondTimestamp();
        String strtime = N_Utils.getStrtimeTimestamp(timestamp, "yyyy-MM-dd HH:mm");
        p.setStrtime(strtime);
        return courseMapper.listSectionsByDate(p);
    }

    public List<SectionDateVo> listSectionDateForTeacher(CourseParams p) {
        return courseMapper.listSectionDateForTeacher(p);
    }

    //巡课指定月份课程日期数量2
    public List<Map> listSectionDateForXk2(CourseParams p) {
        if (p.getUsertype() == 1 && N_Utils.isEmptyInteger(p.getClassid())) {
            String classIds = classTeacherMapper.getClassIds(p.getTeacherid(),p.getSchoolid());//获取教师任教行政和提高班id
            p.setClassids(classIds);
        }
        return courseMapper.listSectionDateForXk2(p);
    }

    //处理直播学生
    @Transactional(rollbackFor = Exception.class)
    public void handleStu(CourseParams params) {
        List<CourseStudentVo> students = listNeedHandleCourse(params);//获取需要处理的直播课
        for (CourseStudentVo student : students) {
            Integer courseid = student.getCourseid();
            Integer classid = student.getClassid();
            String classids = student.getClassids();
            if (student.getStunum().compareTo(student.getClassnum()) < 0) {//直播班人数少
                Integer createid = student.getCreateid();
                Integer createtime = student.getCreatetime();
                Integer schoolid = params.getSchoolid();
                courseMapper.addCourseStu(classid, createid, createtime, schoolid, classids);//添加直播学生
            } else {//直播班人数多
                String csids = courseMapper.getCsids(classid, classids);//获取要删除的班级学生ids
                if (N_Utils.isNotEmpty(csids)) courseMapper.delStuByCsids(csids);//删除直播学生
            }
            classService.updateNum(classid);//更新班级人数
            courseMapper.updateStuNum(courseid);//更新直播人数
        }
    }

    private List<CourseStudentVo> listNeedHandleCourse(CourseParams params) {
        return courseMapper.listNeedHandleCourse(params);
    }

    /**
     * @Description 修改课程课节名称
     * @Param [c]
     * @Return void
     * @Author wn
     * @Date 2022/4/1 14:39
     **/
    public void updateCoursename(LCourse c){
        courseMapper.updateCoursename(c);
    }

    /**
     * @Description 修改课程课节备注
     * @Param [c]
     * @Return void
     * @Author wn
     * @Date 2022/4/1 14:40
     **/
    public void updateCoursecomm(LCourse c){
        courseMapper.updateCoursecomm(c);
    }
}
