package com.xhkjedu.sclass.service.classroom;

import com.alibaba.fastjson.JSON;
import com.xhkjedu.sclass.mapper.classroom.ClassroomPaperFileMapper;
import com.xhkjedu.sclass.mapper.classroom.ClassroomPaperMapper;
import com.xhkjedu.sclass.mapper.classroom.ClassroomPaperQtypeMapper;
import com.xhkjedu.sclass.mapper.classroom.ClassroomPaperScantronMapper;
import com.xhkjedu.sclass.mapper.classroom.ClassroomPaperStudentMapper;
import com.xhkjedu.sclass.mapper.classroom.ClassroomPaperStudentScantronMapper;
import com.xhkjedu.sclass.model.classroom.TClassroomPaper;
import com.xhkjedu.sclass.model.classroom.TClassroomPaperFile;
import com.xhkjedu.sclass.model.classroom.TClassroomPaperQtype;
import com.xhkjedu.sclass.model.classroom.TClassroomPaperScantron;
import com.xhkjedu.sclass.model.classroom.TClassroomPaperStudent;
import com.xhkjedu.sclass.model.classroom.TClassroomPaperStudentScantron;
import com.xhkjedu.sclass.model.paperstudent.TPaperStudentScantron;
import com.xhkjedu.sclass.utils.ArithUtil;
import com.xhkjedu.utils.N_Utils;
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.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author ywx
 * @classname RoomPaperService
 * @description 堂测
 * @date 2020/7/15 8:20
 **/
@Slf4j
@Service
public class ClassroomPaperService {
    @Resource
    private ClassroomPaperMapper classroomPaperMapper;
    @Resource
    private ClassroomPaperFileMapper classroomPaperFileMapper;
    @Resource
    private ClassroomPaperQtypeMapper classroomPaperQtypeMapper;
    @Resource
    private ClassroomPaperScantronMapper classroomPaperScantronMapper;
    @Resource
    private ClassroomPaperStudentMapper classroomPaperStudentMapper;
    @Resource
    private ClassroomPaperStudentScantronMapper classroomPaperStudentScantronMapper;
    private static Integer[] QTYPE = {1, 2, 4, 5, 6, 7, 8, 10};

    /**
     * 答题卡作业--保存
     * @Param [paper]
     * @Author ywx
     * @Date 2020/7/15 8:22
     * @return void
     **/
    @Transactional(rollbackFor = Exception.class)
    public void saveScantronPaper(TClassroomPaper paper) {
        try {
            List<TClassroomPaperQtype> qtypes = paper.getQtypes();
            //答题卡中试题
            List<TClassroomPaperScantron> scanlist = new ArrayList<>();
            qtypes.forEach(t->{
                scanlist.addAll(t.getScantrons());
            });
            paper.setPapernum(scanlist.size());
            Double paperscore = scanlist.stream().collect(Collectors.summingDouble(TClassroomPaperScantron::getPsscore));
            paper.setPaperscore(paperscore);
            String directorid = paper.getDirectorid();
            if (directorid != null && (directorid.equals("0") || directorid.equals(""))) {
                paper.setDirectorid(null);
            }
            classroomPaperMapper.insertSelective(paper);//保存作业

            //保存作业关联信息
            List<TClassroomPaperFile> lst = paper.getPfiles();
            if(lst==null || lst.size()==0 || scanlist ==null || scanlist.size()==0){
            }else{
                //保存作业附件
                savePaperScantronFile(paper);
                //保存答题卡信息
                savePaperScantronQtype(paper,qtypes);
            }

        }catch (Exception e){
            log.error("保存答题卡作业失败：" + e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }

    //课堂考试--保存附件信息
    private void savePaperScantronFile(TClassroomPaper paper){
        List<TClassroomPaperFile> lst = paper.getPfiles();
        for(TClassroomPaperFile pf : lst){
            pf.setCreateid(paper.getCreateid());
            pf.setCreatetime(N_Utils.getSecondTimestamp());
            pf.setSchoolid(paper.getSchoolid());
            pf.setPaperid(paper.getPaperid());
        }
        classroomPaperFileMapper.insertList(lst);
    }

    //课堂考试--保存答题卡-题型-试题
    private void savePaperScantronQtype(TClassroomPaper paper,List<TClassroomPaperQtype> qtypes){
        int sorder = 1;//答题卡试题序号
        int qtypeorder = 1;//答题卡题型序号
        //处理答题卡--题型--试题
        List<TClassroomPaperScantron> savescan = new ArrayList<>();
        for(TClassroomPaperQtype qtype : qtypes){
            List<TClassroomPaperScantron> scanlst = qtype.getScantrons();//题型下试题
            qtype.setCreateid(paper.getCreateid());
            qtype.setCreatetime(paper.getCreatetime());
            qtype.setSchoolid(paper.getSchoolid());
            qtype.setPqnum(scanlst.size());
            Double qtypescore = scanlst.stream().collect(Collectors.summingDouble(TClassroomPaperScantron::getPsscore));
            qtype.setPqscore(qtypescore);
            qtype.setPaperid(paper.getPaperid());
            qtype.setPqorder(qtypeorder);
            qtypeorder++;

            for(TClassroomPaperScantron sc : scanlst){
                sc.setCreateid(paper.getCreateid());
                sc.setCreatetime(N_Utils.getSecondTimestamp());
                sc.setSchoolid(paper.getSchoolid());
                sc.setPaperid(paper.getPaperid());
                sc.setPsorder(sorder);
                savescan.add(sc);
                sorder++;
            }
        }

        //保存答题卡题型
        classroomPaperQtypeMapper.batchSave(qtypes);
        //保存答题卡题型下试题
        classroomPaperScantronMapper.batchSave(savescan);
    }

    /**
     * 堂测--学生作答详情
     * @Param [scantrons]
     * @Author ywx
     * @Date 2020/7/15 9:34
     * @return void
     **/
    @Transactional(rollbackFor = Exception.class)
    public void saveStudentScantron(TClassroomPaperStudent student) {
        try {
            classroomPaperStudentMapper.insertUseGeneratedKeys(student);
            Integer psid = student.getId();
            Double userscore = 0.0;
            Integer checknum = 0;
            List<TClassroomPaperStudentScantron> scantrons = student.getScantrons();
            List<Long> pscaids = scantrons.stream().map(TClassroomPaperStudentScantron::getPscaid).collect(Collectors.toList());
            List<TClassroomPaperScantron> scantronList = classroomPaperScantronMapper.listByIds(pscaids);

            int qorder = 1;//试题序号
            for (TClassroomPaperStudentScantron s : scantrons) {
                s.setPsid(psid);
                s.setQorder(qorder);
                qorder++;
                //获取原试题情况
                Double qscore = s.getQscore();
                TClassroomPaperScantron scantronBean = scantronList.stream().filter(q -> q.getPscaid().equals(s.getPscaid())).findFirst().orElse(null);
                //判断是否作答1.提交但未作答设置零分，2.作答设置答题状态为2，3.选择题提交为空判错
                String useranswer = s.getUseranswer();
                List<String> userAnswers = JSON.parseArray(useranswer, String.class);
                String psanswer = scantronBean.getPsanswer();
                List<String> psanswers = JSON.parseArray(psanswer, String.class);
                //计算用户得分
                Double userScore = 0.0;
                if (N_Utils.isListEmpty(userAnswers)) {
                    s.setStuscore(userScore);
                    s.setChecked(1);
                    s.setCheckid(0);
                    s.setChecktime(N_Utils.getSecondTimestamp());
                    s.setAnswered(0);
                    checknum++;
                } else {
                    s.setAnswered(1);
                    //自动批改判断得分
                    Integer ctype = scantronBean.getCtype();
                    if (Arrays.asList(QTYPE).contains(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;
                        }
                        s.setStuscore(userScore);
                        s.setChecked(1);
                        s.setCheckid(0);
                        s.setChecktime(N_Utils.getSecondTimestamp());
                    }
                }

                userscore = ArithUtil.add(userscore, userScore);
            }
            classroomPaperStudentScantronMapper.insertList(scantrons);

            Integer pschecked = 0;
            if (checknum == scantrons.size()) {//如果自动批改试题数量等于试题总量，批改状态改为1已批改
                pschecked = 1;
            }
            //修改学生得分和批改状态
            classroomPaperStudentMapper.updateScantronStuScoreAndChecked(psid, userscore, pschecked);
        } catch (Exception e) {
            log.error("保存学生作答详情失败："+e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public int correctExam(Integer psid, Integer checkid, String questionResult) throws Exception {
        try {
            TClassroomPaperStudent ps = classroomPaperStudentMapper.findById(psid);
            Long paperid = ps.getPaperid();
            Integer classid = ps.getClassid();
            List<TPaperStudentScantron> psslist = JSON.parseArray(questionResult, TPaperStudentScantron.class);
            if (N_Utils.isListNotEmpty(psslist)) {
                for (TPaperStudentScantron pss : psslist) {
                    //设置批改状态为已批改
                    pss.setCheckid(checkid);
                    pss.setChecked(1);
                    pss.setChecktime(N_Utils.getSecondTimestamp());
                }

                //批量更新试题批改信息
                classroomPaperStudentScantronMapper.updateScantronQuestionBatch(psslist);
            }
            //更新用户得分
            classroomPaperStudentMapper.updateScantronStuScore(psid);
            //判断该作业该班级时候已经批改完成
            //查询如果为0，则证明本作业本班级截止当前时间已经提交作业学生全部批改完成
            Integer notCorrect = classroomPaperStudentMapper.getNotCorrect(paperid, classid);
            return notCorrect;
        } catch (Exception e) {
            log.error("课堂考试批阅失败："+e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new RuntimeException("课堂考试批阅失败");
        }
    }

    /**
     * 根据考试学生id获取考试是否完成批阅
     * @Param [psid]
     * @Author ywx
     * @Date 2020/9/10 16:23
     * @return java.lang.Integer
     **/
    public Integer getCheckedByPsId(Integer psid) {
        return classroomPaperStudentMapper.getCheckedByPsId(psid);
    }

    /**
     * 获取考试学生待批改试题列表
     * @Param [psid]
     * @Author ywx
     * @Date 2020/9/10 16:24
     * @return java.util.List<com.xhkjedu.vo.paperstudent.PaperStudentScantronVo>
     **/
    public List<Map> listCorrectQuestion(Integer psid) {
        return classroomPaperStudentScantronMapper.listCorrectQuestion(psid);
    }

    /**
     * 修改学生作答记录（教师添加批注）
     * @Param [pssid, useranswer]
     * @Author ywx
     * @Date 2020/9/11 15:15
     * @return void
     **/
    public void updateScantronUseranswer(Integer pssid, String useranswer) {
        classroomPaperStudentScantronMapper.updateScantronUseranswer(pssid, useranswer);
    }

    /**
     * 考试按人统计
     * @Param [paperid]
     * @Author ywx
     * @Date 2022/3/11 16:48
     * @return java.util.List<java.util.Map>
     **/
    public List<Map> listEStudent(Long paperid) {
        return classroomPaperStudentMapper.listEStudent(paperid);
    }
}
