package com.xhkjedu.sexam.service.paper;

import com.xhkjedu.config.MissingParametersException;
import com.xhkjedu.sexam.mapper.paper.EPaperCorrectTeacherMapper;
import com.xhkjedu.sexam.model.paperstudent.EPaperStudentQuestion;
import com.xhkjedu.sexam.vo.paper.EPaperSQuestionVo;
import com.xhkjedu.utils.N_Utils;
import com.xhkjedu.vo.ResultVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

@Service
@Slf4j
public class EPaperCorrectTeacherService {
    //ReentrantLock(boolean) true为公平锁，默认false不公平锁，性能更好，可以插队！
    Lock lock = new ReentrantLock();
    @Resource
    private EPaperCorrectTeacherMapper correctTeacherMapper;

    //待阅卷列表
    public List<Map> listPending(Integer teacherid) {
        return correctTeacherMapper.listPending(teacherid);
    }

    //已阅卷列表
    public List<Map> listMarked(Integer teacherid) {
        return correctTeacherMapper.listMarked(teacherid);
    }

    //随机获取待批试题
    public ResultVo getCorrectQuestion(Integer teacherid, Integer eptqid, String classids, Integer esid) {
        lock.lock();
        Map map = correctTeacherMapper.getExamNameByEsId(esid);//根据考试科目id获取考试名称
        try {
            //随机获取一条待批阅试题
            EPaperSQuestionVo sq = correctTeacherMapper.getCorrectQuestion(teacherid, eptqid, classids);
            if (sq == null) return new ResultVo(0, "已批阅完成");
            //修改试卷学生试题为批阅中
            correctTeacherMapper.updateCheckQuestionById(sq.getEpsqid(), teacherid);
            //试题批阅情况
            EPaperSQuestionVo q = correctTeacherMapper.getCheckQuestion(sq.getEptqid(), teacherid);
            Integer tjnum = q.getTjnum();
            Integer pynum = q.getPynum();
            map.put("sq", sq);//学生待批试题
            map.put("tjnum", tjnum);//提交人数
            map.put("pynum", pynum);//批阅人数
            map.put("wpynum", q.getWpynum());//我批阅人数
            map.put("pyrate", N_Utils.getIntegerDivideAndMulitiply(pynum, tjnum));//批阅进度
        } catch (Exception e) {
            log.error("随机获取待批试题出错", e.getMessage());
            throw new MissingParametersException("随机获取待批试题出错:" + e.getMessage());
        } finally {
            lock.unlock();
        }
        return new ResultVo(0, "获取成功", map);
    }

    //获取上一份批阅试题
    public ResultVo getPreQuestion(Integer eptqid, Integer teacherid, Integer esid) {
        EPaperSQuestionVo sq = correctTeacherMapper.getPreQuestion(eptqid, teacherid);
        if (sq == null) return new ResultVo(1, "您还没有批阅记录");
        Map map = correctTeacherMapper.getExamNameByEsId(esid);//根据考试科目id获取考试名称
        //试题批阅情况
        EPaperSQuestionVo q = correctTeacherMapper.getCheckQuestion(eptqid, teacherid);
        Integer tjnum = q.getTjnum();
        Integer pynum = q.getPynum();
        map.put("sq", sq);//学生待批试题
        map.put("tjnum", tjnum);//提交人数
        map.put("pynum", pynum);//批阅人数
        map.put("wpynum", q.getWpynum());//我批阅人数
        map.put("pyrate", N_Utils.getIntegerDivideAndMulitiply(pynum, tjnum));//批阅进度
        return new ResultVo(0, "获取成功", map);
    }

    //阅卷记录
    public List<Map> listRecord(Integer eptqid, Integer teacherid) {
        return correctTeacherMapper.listRecord(eptqid, teacherid);
    }

    //批阅试题
    @Async("asyncPoolTaskExecutor")
    public Future<ResultVo> correctQuestion(EPaperStudentQuestion psq) {
        try {
            correctTeacherMapper.correctQuestion(psq);
            Integer epsid = psq.getEpsid();
            Integer num = correctTeacherMapper.getNotCorrect(epsid);//学生未批改试题数量
            if (num == 0) {//批阅完成修改学生试卷批阅状态
                correctTeacherMapper.updateCheckStuById(epsid, psq.getCheckid());
            }
            return new AsyncResult<>(new ResultVo(0, "批阅成功"));
        } catch (Exception e) {
            return new AsyncResult<>(new ResultVo(1, e.getMessage()));
        }
    }
}
