package com.xhkjedu.smarking.service.exam;

import com.xhkjedu.exception.ServiceException;
import com.xhkjedu.smarking.mapper.exam.*;
import com.xhkjedu.smarking.mapper.paper.MsPaperMapper;
import com.xhkjedu.smarking.mapper.stupaper.MsPaperStudentMapper;
import com.xhkjedu.smarking.model.exam.MsClass;
import com.xhkjedu.smarking.model.exam.MsClassStudent;
import com.xhkjedu.smarking.model.paper.MsPaper;
import com.xhkjedu.smarking.model.stupaper.MsPaperStudent;
import com.xhkjedu.smarking.vo.exam.CStudentVo;
import com.xhkjedu.smarking.vo.exam.SCStudentVo;
import com.xhkjedu.utils.N_Utils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description 阅卷考试学生表 服务实现类
 * @Author auto
 * @Date 2024-10-15
 */
@Service
public class MsClassStudentService {
    @Resource
    private MsClassStudentMapper msClassStudentMapper;
    @Resource
    private MsSubjectMapper msSubjectMapper;
    @Resource
    private MsClassMapper msClassMapper;
    @Resource
    private MsExamMapper msExamMapper;
    @Resource
    private MsPaperMapper msPaperMapper;
    @Resource
    private MsPaperStudentMapper msPaperStudentMapper;

    /**
     * @Description 新增考生-按学生
     * @Date 2024/10/22 9:36
     * @Author YWX
     * @Param [cs]
     * @Return void
     **/
    @Transactional(rollbackFor = Exception.class)
    public void saveByStudent(SCStudentVo cs) {
        List<Integer> classIds = cs.getStudents().stream().map(MsClassStudent::getClassid).distinct().collect(Collectors.toList());
        cs.setClassids(classIds);
        saveClassAndStudent(cs);
    }

    //保存班级和学生信息
    private void saveClassAndStudent(SCStudentVo cs) {
        Integer examid = cs.getExamid();
        Map exam = msExamMapper.findById(examid);
        if (exam.get("fixedscore").equals(1)) {
            throw new ServiceException("一键统分后，不支持添加考生！");
        }
        List<MsClassStudent> studentsList = cs.getStudents();
        if (!exam.get("exammode").equals(3)) {//线下考试
            List<Integer> studentIds = studentsList.stream().map(MsClassStudent::getStudentid).distinct().collect(Collectors.toList());
            Integer num = msClassStudentMapper.getNoExamNoNumByStudentIds(studentIds);//根据学生ids获取没有考号学生数量
            if (num != 0) throw new ServiceException("有学生未设置考号，请先设置");
        }
        List<MsClass> classList = msClassMapper.listByClassIds(cs.getClassids());
        List<MsClass> classes = new ArrayList<>();
        List<MsClassStudent> students = new ArrayList<>();
        List<MsPaperStudent> paperStudents = new ArrayList<>();
        boolean fb = !exam.get("examstate").equals(0);
        for (String subjectid : cs.getSubjectids()) {
            for (MsClass c : classList) {
                MsClass msClass = new MsClass();
                msClass.setClassid(c.getClassid());
                msClass.setClassname(c.getClassname());
                msClass.setSchoolid(c.getSchoolid());
                msClass.setClasstype(c.getClasstype());
                msClass.setExamid(examid);
                msClass.setSubjectid(subjectid);
                classes.add(msClass);
            }
            MsPaper paper = null;
            if (fb) paper = msPaperMapper.getPaperByExamIdAndSubjectId(examid, subjectid);
            for (MsClassStudent stu : studentsList) {
                //没有学生对应班级科目信息，添加学生信息
                MsClassStudent student = new MsClassStudent();
                student.setExamid(examid);
                student.setSubjectid(subjectid);
                student.setClassid(stu.getClassid());
                student.setStudentid(stu.getStudentid());
                students.add(student);
                if (fb) {//考试已发布，没有学生对应科目试卷添加学生试卷
                    MsPaperStudent paperStudent = new MsPaperStudent();
                    paperStudent.setExamid(examid);
                    paperStudent.setMsid(paper.getMsid());
                    paperStudent.setMpid(paper.getMpid());
                    paperStudent.setSubjectid(subjectid);
                    paperStudent.setStudentid(stu.getStudentid());
                    paperStudent.setPnum(paper.getPnum());
                    paperStudent.setPscore(paper.getPscore());
                    paperStudent.setCreatetime(N_Utils.getSecondTimestamp());
                    paperStudents.add(paperStudent);
                }
            }
        }

        msClassMapper.batchSave(classes);
        msClassStudentMapper.batchSave(students);
        if (N_Utils.isListNotEmpty(paperStudents)) msPaperStudentMapper.batchSave(paperStudents);
    }

    /**
     * @Description 新增考生-按班级
     * @Date 2024/10/22 11:42
     * @Author YWX
     * @Param [cs]
     * @Return void
     **/
    @Transactional(rollbackFor = Exception.class)
    public void saveByClass(SCStudentVo cs) {
        List<MsClassStudent> studentsList = msClassStudentMapper.listByClassIds(cs.getClassids());
        cs.setStudents(studentsList);
        saveClassAndStudent(cs);
    }

    /**
     * @return java.util.List<com.xhkjedu.smarking.model.exam.MsClassStudent>
     * @Description 列表
     * @Param [msClassStudent]
     * @Author auto
     * @Date 2024-10-15
     **/
    public List<Map> queryList(MsClassStudent msClassStudent) {
        return msClassStudentMapper.listAll(msClassStudent);
    }

    /**
     * @Description 移除单个科目学生
     * @Date 2024/10/22 14:13
     * @Author YWX
     * @Param [cs]
     * @Return void
     **/
    public void deleteByStudent(CStudentVo cs) {
        Integer mcsid = cs.getMcsid();
        MsClassStudent student = msClassStudentMapper.selectByPrimaryKey(mcsid);
        if (student == null) return;
        Integer examid = student.getExamid();
        Map exam = msExamMapper.findById(examid);
        if (exam.get("fixedscore").equals(1)) throw new ServiceException("一键统分后，不支持移除考生！");
        student.setExammode(N_Utils.obj2Int(exam.get("exammode")));
        Integer num = msPaperStudentMapper.getNumByExamIdAndSubjectIdAndStuId(student);
        if (N_Utils.isTrueInteger(num)) {
            throw new ServiceException("有学生作答记录，不支持移除考生");
        }
        cs.setExamid(examid);
        cs.setSubjectid(student.getSubjectid());
        cs.setStudentid(student.getStudentid());
        List<Integer> classIds = msClassStudentMapper.listBySubjectIdAndStuId(cs);
        if (classIds.size() == 1) {//如果学生只在一个班级，则移除班级学生和试卷信息
            msClassStudentMapper.deleteByStu(cs);
        } else {//如果学生在多个班级，只移除班级学生信息
            msClassStudentMapper.deleteByPrimaryKey(mcsid);
        }

    }

    /**
     * @Description 移除班级学生
     * @Date 2024/10/22 14:17
     * @Author YWX
     * @Param [cs]
     * @Return void
     **/
    public void deleteByClass(CStudentVo cs) {
        Map exam = msExamMapper.findById(cs.getExamid());
        if (exam.get("fixedscore").equals(1)) throw new ServiceException("一键统分后，不支持移除考生！");
        Integer num = msPaperStudentMapper.getStartNumByExamIdExamMode(cs.getExamid(), N_Utils.obj2Int(exam.get("exammode")));
        if (N_Utils.isTrueInteger(num)) {
            throw new ServiceException("有学生作答记录，不支持移除班级！");
        }
        msClassStudentMapper.deleteByClass(cs);
    }

    /**
     * @Description 考试班级列表
     * @Date 2024/10/22 16:50
     * @Author YWX
     * @Param [cs]
     * @Return java.util.List<java.util.Map>
     **/
    public List<Map> listClass(CStudentVo cs) {
        return msClassStudentMapper.listClass(cs);
    }

    /**
     * @Description 班级搜索列表
     * @Date 2024/10/22 16:57
     * @Author YWX
     * @Param [cs]
     * @Return java.util.List<java.util.Map>
     **/
    public List<Map> searchClass(CStudentVo cs) {
        setParam(cs);
        return msClassStudentMapper.searchClass(cs);
    }

    public void setParam(CStudentVo cs) {
        Map exam = msExamMapper.findById(cs.getExamid());
        if (exam == null) throw new ServiceException("考试不存在！");
        cs.setGradeid(N_Utils.obj2Int(exam.get("gradeid")));
        cs.setYear(N_Utils.obj2Int(exam.get("year")));
    }

    /**
     * @Description 学生搜索列表
     * @Date 2024/10/22 17:05
     * @Author YWX
     * @Param [cs]
     * @Return java.util.List<java.util.Map>
     **/
    public List<Map> searchStudent(CStudentVo cs) {
        // setParam(cs);
        return msClassStudentMapper.searchStudent(cs);
    }
}
