package com.xhkjedu.smarking.service.papercheck;

import com.xhkjedu.exception.ServiceException;
import com.xhkjedu.smarking.mapper.exam.MsSubjectMapper;
import com.xhkjedu.smarking.mapper.papercheck.*;
import com.xhkjedu.smarking.mapper.stupaper.MsPaperStudentBlockMapper;
import com.xhkjedu.smarking.model.papercheck.*;
import com.xhkjedu.utils.N_Utils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * @Description 阅卷试卷阅卷方式表 服务实现类
 * @Author auto
 * @Date 2024-10-15
 */
@Service
public class MsPaperCheckService {
    @Resource
    private MsPaperCheckMapper msPaperCheckMapper;
    @Resource
    private MsPaperCheckTeacherMapper msPaperCheckTeacherMapper;
    @Resource
    private MsSubjectMapper msSubjectMapper;
    @Resource
    private MsPaperCheckTeacherTaskMapper msPaperCheckTeacherTaskMapper;
    @Resource
    private MsBlockCheckService msBlockCheckService;
    @Resource
    private MsPaperStudentBlockMapper studentBlockMapper;

    /**
     * @Description 设置评卷方式
     * @Date 2024/10/24 14:16
     * @Author YWX
     * @Param [msPaperCheck]
     * @Return void
     **/
    public void add(MsPaperCheck msPaperCheck) {
        Integer checkstate = msSubjectMapper.getCheckStateByMsId(msPaperCheck.getMsid());//根据考试科目id获取阅卷状态
        if (checkstate.equals(0)) throw new ServiceException("开始阅卷后不支持修改");
        saveOrUpdate(msPaperCheck);
    }

    //添加或更新阅卷方式
    private void saveOrUpdate(MsPaperCheck msPaperCheck) {
        Integer mpcid = msPaperCheckMapper.getMpcIdByMBlockId(msPaperCheck.getMpid(), msPaperCheck.getMblockid());
        if (N_Utils.isTrueInteger(mpcid)) {
            msPaperCheck.setMpcid(mpcid);
            msPaperCheckMapper.updateByPrimaryKeySelective(msPaperCheck);
        } else {
            msPaperCheck.setCreatetime(N_Utils.getSecondTimestamp());
            msPaperCheckMapper.insertSelective(msPaperCheck);
            msSubjectMapper.updateCheckSetByMsId(msPaperCheck.getMsid(), 1, msPaperCheck.getCorrecttype());//更改考试科目阅卷设置状态
        }
    }

    /**
     * @Description 阅卷分配-按题块列表（线下）
     * @Date 2024/10/24 14:19
     * @Author YWX
     * @Param [mpid]
     * @Return java.util.List<java.util.Map>
     **/
    public List<Map> listPaperCheck(Integer mpid) {
        return msPaperCheckMapper.listPaperCheck(mpid);
    }

    /**
     * @Description 设置仲裁教师
     * @Date 2024/10/24 14:40
     * @Author YWX
     * @Param [msPaperCheck]
     * @Return void
     **/
    public void setArbitrate(MsPaperCheck msPaperCheck) {
        saveOrUpdate(msPaperCheck);
    }

    /**
     * @Description 设置阅卷教师
     * @Date 2024/10/24 15:24
     * @Author YWX
     * @Param [msPaperCheck]
     * @Return void
     **/
    @Transactional(rollbackFor = Exception.class)
    public void setCheckTeacher(MsPaperCheck msPaperCheck) {
        if (msPaperCheck.getCorrecttype().equals(1)) {//按班设置默认单评、效率优先、按上传总数
            msPaperCheck.setChecktype(1);
            msPaperCheck.setDispenseway(2);
            msPaperCheck.setNumtype(1);
        }
        saveOrUpdate(msPaperCheck);
        Integer mpid = msPaperCheck.getMpid();
        Integer mblockid = msPaperCheck.getMblockid();
        Integer createid = msPaperCheck.getCreateid();
        int timestamp = N_Utils.getSecondTimestamp();
        List<MsPaperCheckTeacher> teachers = msPaperCheck.getTeachers();
        for (MsPaperCheckTeacher teacher : teachers) {
            teacher.setMpid(mpid);
            teacher.setMblockid(mblockid);
            teacher.setCreateid(createid);
            teacher.setCreatetime(timestamp);
            teacher.setDeleted(1);
        }
        msPaperCheckTeacherMapper.batchSave(teachers);
        setBlockTask(msPaperCheck.getMpid(), mblockid);//设置一个题块的批卷任务
    }

    /**
     * @Description 设置分配方式
     * @Date 2024/10/24 15:41
     * @Author YWX
     * @Param [msPaperCheck]
     * @Return void
     **/
    @Transactional(rollbackFor = Exception.class)
    public void setDispenseWay(MsPaperCheck msPaperCheck) {
        Integer dispenseway = msPaperCheck.getDispenseway();
        Integer mpid = msPaperCheck.getMpid();
        Integer mblockid = msPaperCheck.getMblockid();
        Integer createid = msPaperCheck.getCreateid();
        if (dispenseway.equals(3)) {
            List<MsPaperCheckTeacher> teachers = msPaperCheck.getTeachers();
            if (N_Utils.isListEmpty(teachers)) throw new ServiceException("请选择阅卷教师");
            for (MsPaperCheckTeacher teacher : teachers) {
                teacher.setMpid(mpid);
                teacher.setMblockid(mblockid);
                teacher.setCreateid(createid);
                teacher.setCreatetime(N_Utils.getSecondTimestamp());
                teacher.setDeleted(1);
            }
            msPaperCheckTeacherMapper.batchSave(teachers);
        }
        saveOrUpdate(msPaperCheck);
        setBlockTask(mpid, mblockid);//设置一个题块的批卷任务
    }

    //设置一个题块的批卷任务
    public void setBlockTask(Integer mpid, Integer mblockid) {
        MsPaperCheck check = msPaperCheckMapper.findByMBlockId(mpid, mblockid);
        msBlockCheckService.setOneBlockTask(check);//设置一个题块的批卷任务
    }

    /**
     * @Description 题块阅卷教师列表
     * @Date 2024/10/25 9:05
     * @Author YWX
     * @Param [mblockid]
     * @Return java.util.List<java.util.Map>
     **/
    public List<Map> listCheckTeacher(Integer mpid, Integer mblockid) {
        return msPaperCheckTeacherMapper.listCheckTeacher(mpid, mblockid);
    }

    /**
     * @Description 获取试卷分配总数
     * @Date 2024/10/25 11:29
     * @Author YWX
     * @Param [mblockid]
     * @Return java.util.Map
     **/
    public Map getDispenseNum(Integer mpid, Integer mblockid) {
        MsPaperCheck check = msPaperCheckMapper.findByMBlockId(mpid, mblockid);
        Map map = msPaperCheckMapper.getDispenseNum(check.getMpid(), mblockid, check.getCorrecttype());
        if (check.getChecktype().equals(2)) {//双评，每个学生的试卷要批阅两次
            map.put("signupnum", N_Utils.obj2Int(map.get("signupnum")) * 2);
            map.put("commitnum", N_Utils.obj2Int(map.get("commitnum")) * 2);
        }
        return map;
    }

    /**
     * @Description 添加任务
     * @Date 2024/10/25 17:57
     * @Author YWX
     * @Param [check]
     * @Return void
     **/
    @Transactional(rollbackFor = Exception.class)
    public void addTaskToTeacher(MsPaperCheck check) {
        Integer mblockid = check.getMblockid();
        Integer addTeacherId = check.getTeacherid();
        MsPaperCheckTeacher teacher = msPaperCheckTeacherMapper.findByBlockId(mblockid, addTeacherId);
        if (teacher == null) {
            throw new ServiceException("教师未分配该题块");
        }
        List<MsPaperCheckTeacher> teachers = check.getTeachers();
        Integer taskorder = teacher.getTaskorder();
        for (MsPaperCheckTeacher t : teachers) {
            Integer tasknum = t.getTasknum();
            if (!N_Utils.isTrueInteger(tasknum)) continue;
            Integer teacherid = t.getTeacherid();
            taskorder = updateTeacherTask(mblockid, addTeacherId, taskorder, tasknum, teacherid);
        }
    }

    //更新教师任务信息
    private Integer updateTeacherTask(Integer mblockid, Integer addTeacherId, Integer taskorder, Integer tasknum, Integer teacherid) {
        List<Integer> taskIds = msPaperCheckTeacherTaskMapper.getTaskIdsByMBlockIdAndTeacherId(mblockid, teacherid, tasknum);
        List<MsPaperCheckTeacherTask> tasks = new ArrayList<>();
        for (Integer taskId : taskIds) {
            MsPaperCheckTeacherTask task = new MsPaperCheckTeacherTask();
            task.setMpcttid(taskId);
            taskorder++;
            task.setTaskorder(taskorder);
            task.setTeacherid(addTeacherId);
            tasks.add(task);
        }
        tasknum = taskIds.size();
        if(N_Utils.isListNotEmpty(tasks)) msPaperCheckTeacherTaskMapper.batchUpdate(tasks);//批量更新任务信息
        msPaperCheckTeacherMapper.updateTaskNum(mblockid, teacherid, tasknum, addTeacherId);//更新批阅教师任务数量
        return taskorder;
    }

    /**
     * @Description 分解任务
     * @Date 2024/10/28 10:19
     * @Author YWX
     * @Param [check]
     * @Return void
     **/
    public void fetchTaskToTeacher(MsPaperCheck check) {
        Integer mblockid = check.getMblockid();
        Integer fetchTeacherId = check.getTeacherid();
        List<MsPaperCheckTeacher> teachers = check.getTeachers();
        for (MsPaperCheckTeacher t : teachers) {
            Integer tasknum = t.getTasknum();
            if (!N_Utils.isTrueInteger(tasknum)) continue;
            Integer teacherid = t.getTeacherid();
            MsPaperCheckTeacher teacher = msPaperCheckTeacherMapper.findByBlockId(mblockid, teacherid);
            if (teacher == null) {
                throw new ServiceException("教师未分配该题块");
            }
            Integer taskorder = teacher.getTaskorder();
            updateTeacherTask(mblockid, teacherid, taskorder, tasknum, fetchTeacherId);
        }
    }

    /**
     * @Description 修改题块状态
     * @Date 2024/10/30 9:59
     * @Author YWX
     * @Param [mblockid, checkstate]
     * @Return void
     **/
    public void updateCheckState(Integer mpid, Integer mblockid, Integer checkstate) {
        MsPaperCheck check = msPaperCheckMapper.findByMBlockId(mpid, mblockid);
        if (check == null) {
            throw new ServiceException("该题块未设置阅卷方式");
        }

        if (checkstate.equals(check.getCheckstate())) return;

        MsPaperCheck update = new MsPaperCheck();
        update.setMpcid(check.getMpcid());
        update.setCheckstate(checkstate);
        msPaperCheckMapper.updateByPrimaryKeySelective(update);
    }

    /**
     * @Description 删除阅卷教师
     * @Date 2024/11/5 14:24
     * @Author YWX
     * @Param [mblockid, teacherid]
     * @Return void
     **/
    @Transactional(rollbackFor = Exception.class)
    public void deleteCheckTeacher(Integer mblockid, Integer teacherid) {
        MsPaperCheckTeacher teacher = msPaperCheckTeacherMapper.getTeacherBlockCheck(mblockid, teacherid);//获取教师题块批阅信息
        if (teacher == null || teacher.getDeleted().equals(10)) return;
        teacher.setDeleted(10);
        teacher.setTasknum(teacher.getTasknum() - teacher.getCheckednum());
        msPaperCheckTeacherMapper.updateByPrimaryKeySelective(teacher);

        String mpsbids = teacher.getMpsbids();
        if (N_Utils.isNotEmpty(mpsbids)) {
            msPaperCheckTeacherTaskMapper.deleteByMpsbids(mpsbids);//删除教师阅卷任务
            studentBlockMapper.updateByMpsbidsAndTeacherid(mpsbids, teacherid);//清空教师未阅卷任务
        }
    }

    /**
     * @Description 阅卷分配-按班级列表（线上）
     * @Date 2024/11/6 10:30
     * @Author YWX
     * @Param [mpid]
     * @Return java.util.List<java.util.Map>
     **/
    public List<Map> listClass(Integer mpid) {
        return msPaperCheckMapper.listSubjectClass(mpid);
    }

    /**
     * @Description 阅卷分配-按试题列表（线上）
     * @Date 2024/11/6 14:45
     * @Author YWX
     * @Param [mpid]
     * @Return java.util.List<java.util.Map>
     **/
    public List<Map> listQuestion(Integer mpid) {
        return msPaperCheckMapper.listQuestion(mpid);
    }

    /**
     * @Description 复制阅卷任务
     * @Date 2024/11/6 15:51
     * @Author YWX
     * @Param [mpcid, mblockids]
     * @Return void
     **/
    @Transactional(rollbackFor = Exception.class)
    public void copyTask(Integer mpcid, List<Integer> mblockids) {
        MsPaperCheck check = msPaperCheckMapper.selectByPrimaryKey(mpcid);
        if (check == null) {
            throw new ServiceException("该阅卷方式不存在");
        }
        List<MsPaperCheck> checks = new ArrayList<>();
        List<MsPaperCheckTeacher> teachers = new ArrayList<>();
        List<MsPaperCheckTeacher> list = msPaperCheckTeacherMapper.listCheckTeacher2(check.getMpid(), check.getMblockid());
        for (Integer mblockid : mblockids) {
            MsPaperCheck newCheck = new MsPaperCheck();
            BeanUtils.copyProperties(check, newCheck);
            newCheck.setMblockid(mblockid);
            newCheck.setMpcid(null);
            newCheck.setCreatetime(N_Utils.getSecondTimestamp());
            checks.add(newCheck);
            if (N_Utils.isListNotEmpty(list)) {
                for (MsPaperCheckTeacher teacher : list) {
                    MsPaperCheckTeacher newTeacher = new MsPaperCheckTeacher();
                    BeanUtils.copyProperties(teacher, newTeacher);
                    newTeacher.setMblockid(mblockid);
                    newTeacher.setMpctid(null);
                    newTeacher.setCreatetime(N_Utils.getSecondTimestamp());
                    teachers.add(newTeacher);
                }
            }
        }
        msPaperCheckMapper.deleteByMpIdAndBlockIds(check.getMpid(), mblockids);//根据mpid和mblockids删除阅卷方式
        msPaperCheckMapper.insertList(checks);//批量插入阅卷方式
        if (N_Utils.isListNotEmpty(teachers)) msPaperCheckTeacherMapper.batchSave(teachers);//批量插入阅卷教师
        if (!check.getDispenseway().equals(2)) {
            for (Integer mblockid : mblockids) {
                setBlockTask(check.getMpid(), mblockid);//设置一个题块的批卷任务
            }
        }
    }
}
