package com.xhkjedu.sstudy.service.paperstudent;

import com.alibaba.fastjson.JSON;
import com.xhkjedu.constant.PlatformConstant;
import com.xhkjedu.exception.MissingParametersException;
import com.xhkjedu.sstudy.mapper.paper.PaperAnalyzeMapper;
import com.xhkjedu.sstudy.mapper.paper.PaperMapper;
import com.xhkjedu.sstudy.mapper.paper.PaperQtypeQuestionMapper;
import com.xhkjedu.sstudy.mapper.paper.PaperScantronMapper;
import com.xhkjedu.sstudy.mapper.paperstudent.PaperClassMapper;
import com.xhkjedu.sstudy.mapper.paperstudent.PaperStudentMapper;
import com.xhkjedu.sstudy.mapper.paperstudent.PaperStudentQuestionMapper;
import com.xhkjedu.sstudy.mapper.paperstudent.PaperStudentScantronMapper;
import com.xhkjedu.sstudy.model.paper.TPaperFile;
import com.xhkjedu.sstudy.model.paper.TPaperScantron;
import com.xhkjedu.sstudy.model.paperstudent.TPaperClass;
import com.xhkjedu.sstudy.model.paperstudent.TPaperStudent;
import com.xhkjedu.sstudy.model.paperstudent.TPaperStudentQuestion;
import com.xhkjedu.sstudy.model.paperstudent.TPaperStudentScantron;
import com.xhkjedu.sstudy.model.question.TQuestion;
import com.xhkjedu.sstudy.utils.ArithUtil;
import com.xhkjedu.sstudy.utils.ConvertUtil;
import com.xhkjedu.sstudy.utils.StudyUtil;
import com.xhkjedu.sstudy.vo.paperstudent.*;
import com.xhkjedu.utils.N_Utils;
import com.xhkjedu.vo.ResultVo;
import lombok.extern.slf4j.Slf4j;
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.stream.Collectors;

/**
 * @author ywx
 * @classname PaperStudentWebService
 * @description 
 * @date 2020/9/3 9:31
 **/
@Service
@Slf4j
public class PaperStudentWebService {
    @Resource
    private PaperStudentMapper paperStudentMapper;
    @Resource
    private PaperClassMapper paperClassMapper;

    @Resource
    private PaperStudentScantronService paperStudentScantronService;
    @Resource
    private PaperScantronMapper paperScantronMapper;

    @Resource
    private PaperAnalyzeMapper paperAnalyzeMapper;
    @Resource
    private PaperMapper paperMapper;
    @Resource
    private ConvertUtil convertUtil;

    @Resource
    private PaperQtypeQuestionMapper paperQtypeQuestionMapper;
    @Resource
    private PaperStudentQuestionMapper paperStudentQuestionMapper;
    @Resource
    private PaperStudentScantronMapper paperStudentScantronMapper;

    //获取作业列表
    public List<PaperStudentVo> listWeb(PaperSearchVo paperSearch) {
        Integer timestamp = N_Utils.getSecondTimestamp();
        paperSearch.setNowtime(timestamp);
        return paperStudentMapper.listWeb(paperSearch);
    }

    /**
     * 学生开始做题库作业
     * @Param [psid]
     * @Author ywx
     * @Date 2020/6/10 15:56
     * @return com.xhkjedu.vo.paperstudent.StudentPaperVo
     **/
    @Transactional(rollbackFor = Exception.class)
    public StudentPaperVo startPaper(Integer psid) {
        StudentPaperVo paper = paperStudentMapper.getStudentPaper(psid);
        try {
            List<StudentPaperTypeVo> types = paperStudentQuestionMapper.listPaperType(psid);
            if (N_Utils.isListEmpty(types)){
                List<TPaperStudentQuestion> savelist = new ArrayList<>();
                //作业中的所有试题集合
                List<TPaperStudentQuestion> list = paperStudentQuestionMapper.listPaperQuestion(psid);
                if(paper.getPapertype() == 1){
                    savelist.addAll(list);
                }else if(paper.getPapertype() == 3){
                   //靶向作业中学生试题id集合
                    List<String> stuids = JSON.parseArray(paper.getQuestionids(),String.class);

                    //学生作业id
                    List<TPaperStudentQuestion> stuques = list.stream().filter(
                            (pq) -> stuids.stream().collect(Collectors.toList()).contains(pq.getQuestionpid())).collect(Collectors.toList());

                    if(N_Utils.isListNotEmpty(stuques)) savelist.addAll(stuques);
                }
                if(N_Utils.isListNotEmpty(savelist)) paperStudentQuestionMapper.batchSave(savelist);

                types = paperStudentQuestionMapper.listPaperType(psid);
            }
            StudyUtil.setPaperQuestionNoAnswer(types, paperAnalyzeMapper);
            paper.setTypes(types);
            Integer timestamp = N_Utils.getSecondTimestamp();
            paperStudentMapper.updateState(null,null,psid,1,timestamp);//更改开始状态
        }catch (Exception e){
            log.error("开始做作业失败："+e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }

        return paper;
    }

    /**
     * 学生开始做答题卡作业
     * @Param [psid]
     * @Author ywx
     * @Date 2020/9/3 11:36
     * @return com.xhkjedu.vo.paperstudent.StudentPaperVo
     **/
    public StudentPaperVo scantronStartPaper(Integer psid){
        StudentPaperVo paper = paperStudentMapper.getStudentPaper(psid);
        List<StudentPaperTypeVo> types = paperStudentScantronMapper.listPaperStuSacnsByPsid(psid);
        if (N_Utils.isListEmpty(types)){
            paperStudentScantronService.saveBatchStudentScantron(psid);
            types = paperStudentScantronMapper.listPaperStuSacnsByPsid(psid);
        }

        paper.setTypes(types);
        List<TPaperFile> files = paperMapper.listPaperFile(paper.getPaperid(), 0);
        paper.setFiles(files);
        Integer timestamp = N_Utils.getSecondTimestamp();
        paperStudentMapper.updateState(null,null,psid,1,timestamp);//更改开始状态
        return paper;
    }

    /**
     * 题库作业--提交作业
     * @Param [psqs]
     * @Author ywx
     * @Date 2020/9/3 11:51
     * @return void
     **/
    @Transactional(rollbackFor = Exception.class)
    public ResultVo submitPaper(PaperStudentWebVo paper) {
        try {
            List<TPaperStudentQuestion> psqs = paper.getPsqs();
            TPaperStudentQuestion psq = psqs.get(0);
            TPaperStudent ps = new TPaperStudent();
            Double userscore = 0.0;
            Integer checknum = 0;
            Integer psid = psq.getPsid();
            TPaperStudent ps2 = paperStudentMapper.findById(psid);
            //学生作业不存在或是已提交不处理
            ResultVo vo = StudyUtil.checkPsState(ps2);//校验学生作业提交状态
            if (vo != null) return vo;
            Integer paperid = psq.getPaperid();
            Integer classid = paper.getClassid();
            int nowTime = N_Utils.getSecondTimestamp();
            TPaperClass pg = paperClassMapper.selectByPaperAndClassId(paperid, classid);
            if (pg.getStoptime() < nowTime){
                ps.setPsstate(2);
            } else {
                ps.setPsstate(1);
            }
            ps.setStoptime(nowTime);
            ps.setPsid(psid);

            //获取试卷中所有试题
            List<TQuestion> questions = paperQtypeQuestionMapper.listQuestionsDetilByPaperid(paperid);
            List<TPaperStudentQuestion> hbtplist = new ArrayList<>();
            for (int i = 0; i < psqs.size(); i++) {
                psq = psqs.get(i);
                String questionid = psq.getQuestionid();
                Double qscore = psq.getQscore();
                //获取试题详情
                TQuestion questionBean = questions.stream().filter(q -> q.getQuestionid().equals(questionid)).findFirst().orElse(null);

                //判断是否作答1.提交但未作答设置零分，2.作答设置答题状态为2，3.选择题提交为空判错入错题库
                String useranswer = psq.getUseranswer();
                String useranswertxt = psq.getUseranswertxt();
                List<String> userAnswers = JSON.parseArray(useranswer, String.class);
                String qanswer = questionBean.getQanswer();
                List<String> qanswers = JSON.parseArray(qanswer, String.class);
                //计算用户得分
                Double userScore = 0.0;
                Integer converted = 1;//是否转换0未转换1已转换2转换失败
                if (N_Utils.isEmpty(useranswer) && N_Utils.isListEmpty(userAnswers)
                        && N_Utils.isEmpty(psq.getUseranswertxt())) {
                    psq.setStuscore(userScore);
                    psq.setChecked(1);
                    psq.setCheckid(0);
                    psq.setChecktime(N_Utils.getSecondTimestamp());
                    psq.setAnswered(0);
                    checknum++;
                } else {
                    psq.setAnswered(1);
                    if(psq.getAnswertype() != 2){
                        //自动批改判断得分
                        Integer ctype = questionBean.getCtype();
                        if (N_Utils.isObjectiveQuestion(ctype)) {
                            checknum ++;
                            if (ctype == 1) {//单选
                                if (useranswer.equalsIgnoreCase(qanswer)) {
                                    userScore = qscore;
                                }
                            } else if (ctype == 2) {//多选
                                //多选不得分,或者选错不得分，不用处理
                                if (userAnswers.get(0).length() <= questionBean.getQanswer().length()){
                                    String[] qanswerList = qanswers.get(0).split("");
                                    String[] userAnswerList = userAnswers.get(0).split("");
                                    int rightNum = 0;//选对个数
                                    for (String userAnswer : userAnswerList){
                                        int right = 0;
                                        for (String answer : qanswerList){
                                            if (answer.equals(userAnswer)){
                                                right = 1;
                                                rightNum += 1;
                                            }
                                        }
                                        if (right == 0){//选错直接0分，结束循环
                                            rightNum = 0;
                                            break;
                                        }
                                    }
                                    if (rightNum > 0){//选对计算得分
                                        if (qanswerList.length == rightNum) {//1.全选对满分
                                            userScore = qscore;
                                        } else if (qanswerList.length > rightNum) {//2.少选得一半分
                                            userScore = ArithUtil.div(qscore, 2, 1);
                                        }
                                    }
                                }
                            } else if (ctype == 4 || ctype == 5 || ctype == 6) {
                                //判断题
                                if (useranswer.equalsIgnoreCase(qanswer)) {
                                    userScore = qscore;
                                }
                            } else if (ctype == 7 || ctype == 8 || ctype == 10) {//完型填空、阅读理解、任务型阅读
                                //计算每小题分数
                                Double score = ArithUtil.div(qscore, qanswers.size());
                                Double userScoreDouble = 0D;
                                for (int j = 0; j < qanswers.size(); j++) {
                                    if (qanswers.get(j).equalsIgnoreCase(userAnswers.get(j))) {
                                        userScoreDouble = ArithUtil.add(userScoreDouble, score);
                                    }
                                }
                                userScore = ArithUtil.round(userScoreDouble, 1);
                            }
                            if (userScore.compareTo(qscore) == 1) {
                                userScore = qscore;
                            }
                            psq.setStuscore(userScore);
                            psq.setChecked(1);
                            psq.setCheckid(0);
                            psq.setChecktime(N_Utils.getSecondTimestamp());
                        } else{
                            if (userAnswers.size() > 1){
                                converted = 0;//上传的多张图片设为0未转换
                                hbtplist.add(psq);
                            }
                            psq.setChecked(0);
                        }
                    }else{
                        if(N_Utils.isNotEmpty(useranswertxt)){
                            List<String> useranswertxt_list = JSON.parseArray(useranswertxt,String.class);
                            String useranswertxt_txt = useranswertxt_list.get(0);
                            if(N_Utils.isNotEmpty(useranswertxt_txt)){
                                useranswertxt_txt = N_Utils.strTrim(useranswertxt_txt);
                                if(N_Utils.isNotEmpty(useranswertxt_txt)){
                                    psq.setChecked(0);
                                    List<String> useranswertxt_list_new = new ArrayList<>();
                                    useranswertxt_list_new.add(useranswertxt_txt);
                                    psq.setUseranswertxt(JSON.toJSONString(useranswertxt_list_new));
                                }else{
                                    psq.setChecked(1);
                                    psq.setUseranswertxt("[\"\"]");
                                }
                            }else{
                                psq.setChecked(1);
                                psq.setUseranswertxt("[\"\"]");
                            }
                        }else{
                            psq.setChecked(1);
                        }
                    }
                }
                psq.setConverted(converted);
                userscore = ArithUtil.add(userscore, userScore);
            }

            paperStudentMapper.batchUpdateQuestion(psqs);

            ps.setUserscore(userscore);
            ps.setPsid(psid);
            Integer pschecked = 0;
            if (checknum == psqs.size()){//如果自动批改试题数量等于试题总量，批改状态改为1已批改
                pschecked = 1;
                ps.setAutocheck(1);
            }
            ps.setPschecked(pschecked);
            ps.setCosttime(paper.getCosttime());
            Integer showanswer = 0;
            if (pg.getShowtype() == 2 || ps.getPsstate() == 2){
                showanswer = 1;
            }
            ps.setShowanswer(showanswer);
            paperStudentMapper.submitPaper(ps);
            if(N_Utils.isListNotEmpty(hbtplist)){
                for(TPaperStudentQuestion stuq : hbtplist){
                    List<String> userAnswers = JSON.parseArray(stuq.getUseranswer(),String.class);
                    convertUtil.imgMerge(stuq.getPsqid(), userAnswers, 1);
                }
            }
            //questionClassService.submitPaper(pg);//自动批改的作业全部批改完调用批阅结束方法
        } catch (Exception e) {
            log.error("提交试卷失败："+e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return new ResultVo(1, "提交失败！");
        }
        return new ResultVo(0, "提交成功！");
    }

    /**
     * 图片作业--提交作业
     * @Param [psqs]
     * @Author ywx
     * @Date 2020/9/3 15:00
     * @return void
     **/
    @Transactional(rollbackFor = Exception.class)
    public ResultVo scantronSubmitPaper(PaperStudentWebVo paper) {
        try {
            List<TPaperStudentScantron> psqs = paper.getPss();
            TPaperStudentScantron pss = psqs.get(0);
            TPaperStudent ps = new TPaperStudent();
            Double userscore = 0.0;
            Integer checknum = 0;
            Integer psid = pss.getPsid();
            TPaperStudent ps2 = paperStudentMapper.findById(psid);
            ResultVo vo = StudyUtil.checkPsState(ps2);//校验学生作业提交状态
            if (vo != null) return vo;
            Integer paperid = pss.getPaperid();
            Integer classid = paper.getClassid();
            int nowTime = N_Utils.getSecondTimestamp();
            TPaperClass pg = paperClassMapper.selectByPaperAndClassId(paperid, classid);
            if (pg.getStoptime() < nowTime){
                ps.setPsstate(2);
            } else {
                ps.setPsstate(1);
            }
            ps.setStoptime(nowTime);
            ps.setPsid(psid);

            List<TPaperScantron> scanlist = paperScantronMapper.listPaperScansByPaperid(paperid);
            List<TPaperStudentScantron> hbtplist = new ArrayList<>();

            for (int i = 0; i < psqs.size(); i++) {
                pss = psqs.get(i);
                int pscaid = pss.getPscaid();
                //获取原试题情况
                Double qscore = pss.getQscore();
                TPaperScantron scantronBean = scanlist.stream().filter(s -> s.getPscaid().equals(pscaid)).findFirst().orElse(null);
                //判断是否作答1.提交但未作答设置零分，2.作答设置答题状态为2，3.选择题提交为空判错
                String useranswer = pss.getUseranswer();
                String useranswertxt = pss.getUseranswertxt();
                List<String> userAnswers = JSON.parseArray(useranswer, String.class);
                String psanswer = scantronBean.getPsanswer();
                List<String> psanswers = JSON.parseArray(psanswer, String.class);
                //计算用户得分
                Double userScore = 0.0;
                Integer converted = 1;//是否转换0未转换1已转换2转换失败
                if (N_Utils.isEmpty(useranswer) && N_Utils.isListEmpty(userAnswers)
                        && N_Utils.isEmpty(pss.getUseranswertxt())) {
                    pss.setStuscore(userScore);
                    pss.setChecked(1);
                    pss.setCheckid(0);
                    pss.setChecktime(N_Utils.getSecondTimestamp());
                    pss.setAnswered(0);
                    checknum++;
                } else {
                    pss.setAnswered(1);
                    if(pss.getAnswertype() != 2){
                        //自动批改判断得分
                        Integer ctype = scantronBean.getCtype();
                        if (N_Utils.isObjectiveQuestion(ctype)) {
                            checknum ++;
                            if (ctype == 1) {//单选
                                if (useranswer.equalsIgnoreCase(psanswer)) {
                                    userScore = qscore;
                                }
                            } else if (ctype == 2) {//多选
                                //多选不得分,或者选错不得分，不用处理
                                if (useranswer.length() <= psanswer.length()){
                                    String[] qanswerList = psanswers.get(0).split("");
                                    String[] userAnswerList = userAnswers.get(0).split("");
                                    int rightNum = 0;//选对个数
                                    for (String userAnswer : userAnswerList){
                                        int right = 0;
                                        for (String qanswer : qanswerList){
                                            if (qanswer.equals(userAnswer)){
                                                right = 1;
                                                rightNum += 1;
                                            }
                                        }
                                        if (right == 0){//选错直接0分，结束循环
                                            rightNum = 0;
                                            break;
                                        }
                                    }
                                    if (rightNum > 0){//选对计算得分
                                        if (qanswerList.length == rightNum) {//1.全选对满分
                                            userScore = qscore;
                                        } else if (qanswerList.length > rightNum) {//2.少选得一半分
                                            userScore = ArithUtil.div(qscore, 2, 1);
                                        }
                                    }
                                }
                            } else if (ctype == 4 || ctype == 5 || ctype == 6) {
                                //判断题
                                if (useranswer.equalsIgnoreCase(psanswer)) {
                                    userScore = qscore;
                                }
                            } else if (ctype == 7 || ctype == 8 || ctype == 10) {//完型填空、阅读理解、任务型阅读
                                //计算每小题分数
                                Double score = ArithUtil.div(qscore, psanswers.size());
                                Double userScoreDouble = 0D;
                                for (int j = 0; j < psanswers.size(); j++) {
                                    if (psanswers.get(j).equalsIgnoreCase(userAnswers.get(j))) {
                                        userScoreDouble = ArithUtil.add(userScoreDouble, score);
                                    }
                                }
                                userScore = ArithUtil.round(userScoreDouble, 1);
                            }
                            if (userScore.compareTo(qscore) == 1) {
                                userScore = qscore;
                            }
                            pss.setStuscore(userScore);
                            pss.setChecked(1);
                            pss.setCheckid(0);
                            pss.setChecktime(N_Utils.getSecondTimestamp());
                        } else {
                            if(userAnswers.size() > 1){
                                converted = 0;//上传的多张图片设为0未转换
                                hbtplist.add(pss);
                            }
                            pss.setChecked(0);
                        }
                    }else{
                        if(N_Utils.isNotEmpty(useranswertxt)){
                            List<String> useranswertxt_list = JSON.parseArray(useranswertxt,String.class);
                            String useranswertxt_txt = useranswertxt_list.get(0);
                            if(N_Utils.isNotEmpty(useranswertxt_txt)){
                                useranswertxt_txt = N_Utils.strTrim(useranswertxt_txt);
                                if(N_Utils.isNotEmpty(useranswertxt_txt)){
                                    pss.setChecked(0);
                                    List<String> useranswertxt_list_new = new ArrayList<>();
                                    useranswertxt_list_new.add(useranswertxt_txt);
                                    pss.setUseranswertxt(JSON.toJSONString(useranswertxt_list_new));
                                }else{
                                    pss.setChecked(1);
                                    pss.setUseranswertxt("[\"\"]");
                                }
                            }else{
                                pss.setChecked(1);
                                pss.setUseranswertxt("[\"\"]");
                            }
                        }else{
                            pss.setChecked(1);
                        }
                    }
                }
                pss.setConverted(converted);
                userscore = ArithUtil.add(userscore, userScore);
            }

            paperStudentScantronService.batchUpdateQuestion(psqs);

            ps.setUserscore(userscore);
            ps.setPsid(psid);
            Integer pschecked = 0;
            if (checknum == psqs.size()){//如果自动批改试题数量等于试题总量，批改状态改为1已批改
                pschecked = 1;
                ps.setAutocheck(1);
            }
            ps.setPschecked(pschecked);
            ps.setCosttime(paper.getCosttime());
            Integer showanswer = 0;
            if (pg.getShowtype() == 2 || ps.getPsstate() == 2){
                showanswer = 1;
            }
            ps.setShowanswer(showanswer);
            paperStudentMapper.submitPaper(ps);
            //保存完后调用mq
            if(N_Utils.isListNotEmpty(hbtplist)){
                for(TPaperStudentScantron stuscan : hbtplist){
                    List<String> userAnswers = JSON.parseArray(stuscan.getUseranswer(), String.class);
                    convertUtil.imgMerge(stuscan.getPssid(), userAnswers, 2);
                }
            }

            //questionClassService.submitPaper(pg);//自动批改的作业全部批改完调用批阅结束方法
        } catch (Exception e) {
            log.error("图片作业提交失败："+e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return new ResultVo(1, "提交失败！");
        }
        return new ResultVo(0, "提交成功！");
    }

    /**
     * 附件作业详情
     * @Param [psid]
     * @Author ywx
     * @Date 2020/9/5 10:22
     * @return com.xhkjedu.vo.paperstudent.StudentPaperVo
     **/
    public StudentPaperVo listPaperStudentScantrons(Integer psid) {
        StudentPaperVo paper = paperAnalyzeMapper.getStudentPaperAnalyzeWeb(psid);
        List<StudentPaperTypeVo> types = paperAnalyzeMapper.listPeopleSDetailAnalyze(psid);
        paper.setTypes(types);
        List<TPaperFile> files = paperMapper.listPaperFile(paper.getPaperid(), 0);
        paper.setFiles(files);
        return paper;
    }

    /**
     * 题库作业详情
     * @Param [psid]
     * @Author ywx
     * @Date 2020/9/5 10:47
     * @return com.xhkjedu.vo.paperstudent.StudentPaperVo
     **/
    public StudentPaperVo listPaperStudent(Integer psid) {
        StudentPaperVo paper = paperAnalyzeMapper.getStudentPaperAnalyzeWeb(psid);
        List<StudentPaperTypeVo> types = paperAnalyzeMapper.listPeopleDetailAnalyze(psid);
        StudyUtil.setPaperQuestion(types, paperAnalyzeMapper);
        paper.setTypes(types);
        List<StudentPointScoreVo> points = paperAnalyzeMapper.listPointScoreByPsId(psid);
        paper.setPoints(points);
        return paper;
    }
}
