package com.xhkjedu.smarking.service.stupaper;

import com.alibaba.fastjson.JSON;
import com.xhkjedu.exception.MissingParametersException;
import com.xhkjedu.smarking.config.ConfigKey;
import com.xhkjedu.smarking.mapper.paper.MsPaperFileMapper;
import com.xhkjedu.smarking.mapper.paper.MsPaperMapper;
import com.xhkjedu.smarking.mapper.stupaper.MsPaperStudentMapper;
import com.xhkjedu.smarking.mapper.stupaper.MsPaperStudentQuestionMapper;
import com.xhkjedu.smarking.model.paper.MsPaperFile;
import com.xhkjedu.smarking.model.paper.MsPaperQtype;
import com.xhkjedu.smarking.model.stupaper.MsPaperStudent;
import com.xhkjedu.smarking.model.stupaper.MsPaperStudentQuestion;
import com.xhkjedu.smarking.utils.ConvertUtil;
import com.xhkjedu.smarking.utils.MarkingUtil;
import com.xhkjedu.smarking.vo.stupaper.PaperStuExamVo;
import com.xhkjedu.smarking.vo.stupaper.PaperStudentWebVo;
import com.xhkjedu.smarking.vo.stupaper.QuestionAnswerVo;
import com.xhkjedu.utils.N_Utils;
import com.xhkjedu.vo.ResultVo;
import org.springframework.stereotype.Service;

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

/**
 * @Description 阅卷试卷学生表 服务实现类
 * @Author auto
 * @Date 2024-10-15
 */
@Service
public class MsPaperStudentService {
    @Resource
    private MsPaperStudentMapper msPaperStudentMapper;
    @Resource
    private MsPaperFileMapper msPaperFileMapper;
    @Resource
    private MsPaperStudentQuestionMapper msPaperStudentQuestionMapper;
    @Resource
    private ConvertUtil convertUtil;
    @Resource
    private MsPaperMapper msPaperMapper;

    /*
     * @Description 学生考试列表-待进行
     * @Date 2024/10/30 16:28:21
     * @Author WN
     * @Param [paperStudent]
     * @Return java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
     **/
    public List<Map<String,Object>> listExamPrePapersForStudent(MsPaperStudent paperStudent){
        int timestamp = N_Utils.getSecondTimestamp();
        String nowtime = N_Utils.getStrtimeTimestamp(timestamp, "yyyy-MM-dd HH:mm");
        return msPaperStudentMapper.listExamPrePapersForStudent(paperStudent.getStudentid(),nowtime);
    }

    /*
     * @Description 学生考试列表-已结束
     * @Date 2024/10/30 16:41:16
     * @Author WN
     * @Param [eps]
     * @Return java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
     **/
    public List<Map<String,Object>> listExamEndPapersForStudent(Integer studentid){
        return msPaperStudentMapper.listExamEndPapersForStudent(studentid);
    }

    /*
     * @Description 学生待考-Web考试科目信息、试卷试题信息
     * @Date 2024/10/31 11:49:54
     * @Author WN
     * @Param [mpsid]
     * @Return void
     **/
    public Map<String,Object> getWaitWebStudentPaperByMpsid(Integer mpsid){
        Map<String,Object> map = waitStudentPaperCheck(mpsid);//学生待考-校验考试状态

        int ptype = Integer.parseInt(map.get("ptype").toString());
        Integer mpid = Integer.parseInt(map.get("mpid").toString());
        List<MsPaperQtype> qtypes;
        if(ptype == 1){
            //题库试卷
            qtypes = msPaperStudentMapper.listStuPaperQuestionsForWebTk(mpsid);
        }else{
            //附件试卷
            qtypes = msPaperStudentMapper.listStuPaperQuestionsForWebFj(mpsid);
            //获取试卷文件
            List<MsPaperFile> pfiles = msPaperFileMapper.listFilesbyMpidAndType(mpid, null);
            map.put("pfiles",pfiles);
        }

        map.put("qtypes", qtypes);
        return map;
    }

    //学生待考-校验考试状态
    private Map<String,Object> waitStudentPaperCheck(Integer mpsid){
        PaperStuExamVo psVo = msPaperStudentMapper.getSubjectStateAndSstageByMpsid(mpsid);
        if(psVo.getMsstate() == 2) throw new MissingParametersException("考试已结束禁止操作");
        if(psVo.getSstate() >= 2) throw new MissingParametersException("试卷已提交");

        int nowstamp = N_Utils.getSecondTimestamp();
        long beginstamp = MarkingUtil.getTimestrToTimetamp(psVo.getSdate() + " " + psVo.getBegintime() + ":00");
        if(nowstamp < beginstamp){
            long diff = beginstamp - nowstamp;
            if(diff > 300){
                throw new MissingParametersException("未到考试时间，请耐心等待");
            }
        }
        //获取考试科目时间信息
        Map<String,Object> map = msPaperStudentMapper.getExamPaperSubjectByMpsid(mpsid);
        Long times = null;
        if (map.get("sdate") != null && map.get("begintime") != null && map.get("endtime") != null) {
            long bg = MarkingUtil.strToTimestamp(map.get("sdate").toString() + " " + map.get("begintime").toString() + ":00");
            long ed = MarkingUtil.strToTimestamp(map.get("sdate").toString() + " " + map.get("endtime").toString() + ":00");
            times = MarkingUtil.subtract(ed, bg);
        }
        map.put("times", times);
        return map;
    }

    /*
     * @Description 学生待考-Android考试科目信息、试卷试题信息
     * @Date 2024/10/31 14:52:08
     * @Author WN
     * @Param [mpsid]
     * @Return java.util.Map<java.lang.String,java.lang.Object>
     **/
    public Map<String,Object> getWaitAndroidStudentPaperByMpsid(Integer mpsid){
        Map<String,Object> map = waitStudentPaperCheck(mpsid);//学生待考-校验考试状态
        int ptype = Integer.parseInt(map.get("ptype").toString());
        int mpid = Integer.parseInt(map.get("mpid").toString());
        List<Map<String,Object>> questions;
        if(ptype == 1){
            //题库试卷
            questions = msPaperStudentMapper.listStuPaperQuestionsForAndroidTk(mpsid);
        }else{
            //附件试卷
            questions = msPaperStudentMapper.listStuPaperQuestionsForAndroidFj(mpsid);
            //获取试卷文件
            List<MsPaperFile> pfiles = msPaperFileMapper.listFilesbyMpidAndType(mpid, null);
            map.put("pfiles",pfiles);
        }

        Map<String,Object> rtnMap = new HashMap<>();
        rtnMap.put("paper", map);
        rtnMap.put("questions", questions);
        rtnMap.put("classid",map.get("classid"));

        return rtnMap;
    }

    /*
     * @Description 学生待考-进入考试
     * @Date 2024/10/31 16:39:57
     * @Author WN
     * @Param [mpsid]
     * @Return java.lang.Integer
     **/
    public Integer updatePaperStudentForIn(Integer mpsid){
        PaperStuExamVo psVo = msPaperStudentMapper.getSubjectStateAndSstageByMpsid(mpsid);
        if(psVo.getMsstate() == 2) throw new MissingParametersException("考试已结束禁止操作");
        if(psVo.getSstate() >= 2) throw new MissingParametersException("试卷已提交");

        //更改学生试卷考试状态
        msPaperStudentMapper.updatePaperStuStartime(mpsid, N_Utils.getSecondTimestamp());

        //计算考试剩余时间
        return getEndTime(psVo.getMsid(), psVo.getStudentid());
    }

    //学生考试-考试剩余时间（秒）
    public Integer getEndTime(Integer msid, Integer studentid) {
        PaperStuExamVo ps = msPaperStudentMapper.getSubjectEndtime(msid, studentid);
        if (ps == null) throw new MissingParametersException("考试不存在");
        double mul = MarkingUtil.mul(ConfigKey.markingEndtime, ps.getUserbl());
        long endtime = MarkingUtil.strToTimestamp(ps.getSdatetime());
        double timestamp = Math.floor(MarkingUtil.add(endtime, mul));
        double sub = MarkingUtil.sub(timestamp, N_Utils.getSecondTimestamp());//结束时间戳-当前时间戳
        int subtime = (int) sub;
        if (subtime < 0) subtime = 0;
        return subtime;
    }

    /*
     * @Description 学生考试-web提交试题
     * @Date 2024/11/1 10:58:11
     * @Author WN
     * @Param [pswvo]
     * @Return void
     **/
    public void saveCommitQuestionForWeb(PaperStudentWebVo pswvo){
        List<MsPaperStudentQuestion> questions = pswvo.getQuestions();
        // //获取试题正确答案
        List<QuestionAnswerVo> qaVos = msPaperStudentQuestionMapper.listPaperQuestionAnswers(pswvo.getMpsid());
        for (MsPaperStudentQuestion sq : questions) {
            QuestionAnswerVo qaVo = qaVos.stream().filter(q -> q.getMpsqid().equals(sq.getMpsqid())).findFirst().orElse(null);
            setCommitQuestion(sq,qaVo);
        }
        msPaperStudentQuestionMapper.updateBatchStudentAnswer(questions);
    }

    /*
     * @Description 学生考试-Android提交单题
     * @Date 2024/11/1 10:39:29
     * @Author WN
     * @Param [mpsq]
     * @Return void
     **/
    public void saveCommitQuestionForAndroid(MsPaperStudentQuestion mpsq){
        //获取试题正确答案
        QuestionAnswerVo qaVo = msPaperStudentQuestionMapper.getPaperQuestionAnswer(mpsq.getMpsqid());

        //判断学生单题情况
        setCommitQuestion(mpsq,qaVo);
        //修改单题提交情况
        msPaperStudentQuestionMapper.updateStudentAnswer(mpsq);
    }

    //学生考试-提交试题
    private void setCommitQuestion(MsPaperStudentQuestion psq,QuestionAnswerVo qaVo) {
        int timestamp = N_Utils.getSecondTimestamp();
        psq.setAnswertime(timestamp);

        String stuanswer = psq.getStuanswer();
        if(N_Utils.isEmpty(stuanswer) && JSON.parseArray(stuanswer, String.class).isEmpty()) {
            //学生未作答，或者作答内容为空，则自动批阅
            psq.setAnswered(0);
            psq.setStuanswer(null);
            psq.setStuscore(0.0);
            psq.setFirstccore(0.0);
            psq.setFirstcime(timestamp);
            psq.setChecked(3);//是否批阅0默认1待批阅2批阅中3已批阅
        }else{
            int ctype = qaVo.getCtype();
            double stuScore = 0.0;
            int checked = 1;//待批改
            if(N_Utils.isObjectiveQuestion(ctype)){
                //客观题,按照客观题规则，
                if(qaVo.getHasanswer()!=null && qaVo.getHasanswer() == 1){
                    //设置了正确答案，
                    if(N_Utils.isTrueInteger(qaVo.getScoreset())){
                        //分值设置0默认1送分题 20分题
                        if(qaVo.getScoreset() ==1){
                            stuScore = qaVo.getQscore();
                        }
                    }else{
                        stuScore = MarkingUtil.checkObjectiveStuAnswer(stuanswer, ctype,qaVo.getQanswer(), qaVo.getLoseoption(), qaVo.getQscore());
                    }
                    checked = 3;
                    psq.setFirstcime(timestamp);
                }
            }else{
                //主观题，如果上传的图片多张，需要合并
                if (psq.getAnswertype() == 2) {
                    // 说明提交的图片（答案类型1选择题2图片3纯文本）
                    List<String> imgs = JSON.parseArray(stuanswer, String.class);
                    if (imgs != null && imgs.size() > 1) {
                        psq.setConverted(1); //是否转换0默认1待转换2转换成功3转换失败
                    }
                }
            }
            psq.setChecked(checked);
            psq.setAnswered(1);
            psq.setStuscore(stuScore);
            psq.setFirstccore(stuScore);
        }
    }

    /*
     * @Description 学生考试-提交试卷
     * @Date 2024/11/1 11:40:31
     * @Author WN
     * @Param [ps]
     * @Return com.xhkjedu.vo.ResultVo
     **/
    public ResultVo saveCommitPaper(MsPaperStudent ps){
        Integer mpsid = ps.getMpsid();
        //获取单科状态
        PaperStuExamVo paperStuExamVo = msPaperStudentMapper.getSubjectStateByMpsid(mpsid);
        if(paperStuExamVo.getMsstate() == 2) return new ResultVo(0, "考试已结束");

        int timestamp = N_Utils.getSecondTimestamp();

        //更改未提交试题的批阅状态为已批改
        msPaperStudentQuestionMapper.updateStuQuestionsNoCommit(mpsid,timestamp);
        ps.setEndtime(timestamp);
        ps.setSstate(2);

        msPaperStudentMapper.updateStudentPaper(ps);
        chandleStudentQuestionNoconvertedPic(mpsid);
        return new ResultVo(1, "提交成功");
    }

    //学生考试-提交试卷-处理试卷中未已提交需要合并的图片
    private void chandleStudentQuestionNoconvertedPic(Integer mpsid) {
        List<MsPaperStudentQuestion> psqlist = msPaperStudentQuestionMapper.listStuQuestionStuAnswerPic(mpsid);
        if (N_Utils.isListNotEmpty(psqlist)) {
            for (MsPaperStudentQuestion sq : psqlist) {
                List<String> stuanswer = JSON.parseArray(sq.getStuanswer(), String.class);
                if (N_Utils.isListNotEmpty(stuanswer) && stuanswer.size() > 1) {
                    convertUtil.imgMerge(sq.getMpsqid(), stuanswer);
                }
            }
        }
    }

    /*
     * @Description 学生试卷-题型试题、作答、得分情况
     * @Date 2024/11/14 14:37:40
     * @Author WN
     * @Param [mpsid]
     * @Return java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
     **/
    public List<Map<String,Object>> listStuPaperQtypeQueAnswerForWeb(Integer mpsid){
        Integer papertype = msPaperMapper.getPaperTypeByMpsid(mpsid);
        List<Map<String,Object>> rtnList;
        if(papertype == 1) {
            //题库试卷
            rtnList = msPaperStudentQuestionMapper.listStuPaperQtypeQueAnswerForWebTk(mpsid);
        }else{
            rtnList = msPaperStudentQuestionMapper.listStuPaperQtypeQueAnswerForWebFj(mpsid);
        }
        return rtnList;
    }
}
