package com.testor.module.train.myManagement.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.testor.common.util.DateUtil;
import com.testor.module.hazard.dao.TrainExaminationManageRetakeDao;
import com.testor.module.hazard.model.domain.TrainExaminationManageRetake;
import com.testor.module.train.exam.model.domain.TTrainExamChoice;
import com.testor.module.train.exam.model.domain.TTrainExamJudgment;
import com.testor.module.train.exam.model.domain.TTrainTestQuestions;
import com.testor.module.train.exam.service.TTrainExamChoiceService;
import com.testor.module.train.exam.service.TTrainExamJudgmentService;
import com.testor.module.train.exam.service.TTrainTestQuestionsService;
import com.testor.module.train.myManagement.dao.TTrainMyManagementDao;
import com.testor.module.train.myManagement.dao.TTrainTestQuestionsExerciseDao;
import com.testor.module.train.myManagement.model.domain.TTrainMyManagement;
import com.testor.module.train.myManagement.model.domain.TTrainTestQuestionsExercise;
import com.testor.module.train.myManagement.model.dto.TTrainTestQuestionsExerciseParam;
import com.testor.module.train.myManagement.service.TTrainMyManagementService;
import com.testor.module.train.myManagement.service.TTrainTestQuestionsExerciseService;
import com.testor.module.train.paper.model.domain.TTrainPaper;
import com.testor.module.train.paper.model.dto.Options;
import com.testor.module.train.paper.model.dto.ReturnTrainPaper;
import com.testor.module.train.paper.model.dto.TestQuestionsContent;
import com.testor.module.train.paper.service.TTrainPaperService;
import com.testor.module.train.project.model.dto.Exercise;
import com.tongtech.tfw.backend.common.biz.constants.BizConstants;
import com.tongtech.tfw.backend.common.biz.models.BaseResponse;
import com.tongtech.tfw.backend.common.biz.models.BaseResponseList;
import com.tongtech.tfw.backend.common.biz.models.BizGeneralResponse;
import com.tongtech.tfw.backend.common.context.ContextUtils;
import com.tongtech.tfw.backend.common.exception.BusinessException;
import com.tongtech.tfw.backend.common.models.supers.SuperServiceImpl;
import com.tongtech.tfw.backend.common.models.sys.UserInfo;
import com.tongtech.tfw.backend.core.helper.IdHelper;
import com.tongtech.tfw.backend.core.helper.ObjectHelper;
import com.tongtech.tfw.backend.core.helper.StringHelper;
import com.tongtech.tfw.backend.core.helper.TypeHelper;
import com.tongtech.tfw.backend.core.helper.bean.BeanHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * 我的试题练习、考试—安全培训教育Service业务层处理
 *
 * @author testor-framework
 * @date 2022-08-08 10:16:57
 */
@Service
public class TTrainTestQuestionsExerciseServiceImpl extends SuperServiceImpl<TTrainTestQuestionsExerciseDao, TTrainTestQuestionsExercise> implements TTrainTestQuestionsExerciseService {
    @Autowired(required = false)
    private TTrainTestQuestionsExerciseDao tTrainTestQuestionsExerciseDao;
    @Autowired
    private AsyncTestQuestions asyncTestQuestions;

    @Autowired
    private TTrainMyManagementService tTrainMyManagementService;

    @Autowired
    private TTrainTestQuestionsService tTrainTestQuestionsService;
    @Autowired
    private TTrainExamJudgmentService tTrainExamJudgmentService;
    @Autowired
    private TTrainExamChoiceService tTrainExamChoiceService;
    @Autowired
    private TTrainPaperService tTrainPaperService;

    @Autowired
    private TTrainMyManagementDao tTrainMyManagementDao;

    @Autowired
    private TrainExaminationManageRetakeDao trainExaminationManageRetakeDao;


    @Override
    public BaseResponse<TTrainTestQuestionsExercise> saveClose(List<TTrainTestQuestionsExercise> questBody) throws Exception {
        BaseResponse<TTrainTestQuestionsExercise> exerciseBaseResponse = new BaseResponse<>();
        if (ObjectHelper.isNotEmpty(questBody)) {
            UserInfo loginUser = ContextUtils.getLoginUser();
            List<TTrainTestQuestionsExercise> exercises = new ArrayList<>();
            // 保存所有试题id
            List<String> list = new ArrayList<>();
            String MYID = "";
            for (TTrainTestQuestionsExercise tTrain : questBody) {
                TTrainTestQuestionsExercise tTrainTest = BeanHelper.beanToBean(tTrain, TTrainTestQuestionsExercise.class);
                tTrainTest.setPersonId(loginUser.getUserId());
                // 选择是否正确
                if (StringHelper.isNotEmpty(tTrain.getOptionsId())) {
                    String s = checkIsCorrect(tTrain.getTestQuestionsId(), tTrain.getOptionsId());
                    // 个人中心主键id
                    MYID = tTrain.getMyId();
                    list.add(tTrain.getTestQuestionsId());
                    tTrainTest.setIsCorrect(s);
                    exercises.add(tTrainTest);
                    // 获取已存在的题目
                    this.remove(new QueryWrapper<TTrainTestQuestionsExercise>()
                            .in(TTrainTestQuestionsExercise.TEST_QUESTIONS_ID, list)
                            .eq(TTrainTestQuestionsExercise.MY_ID, MYID)
                            .eq(TTrainTestQuestionsExercise.PERSON_ID, loginUser.getUserId()));

                    this.saveBatch(exercises);
                }
            }

            // 根据试题id获取题库id
            if (list.size() > 0) {
                TTrainTestQuestions testQuestions = tTrainTestQuestionsService.getById(list.get(0));
                // 获取题库id
                String questionBankId = testQuestions.getQuestionBankId();
                // 异步调用统计练习数量
                Exercise exercise = new Exercise();
                exercise.setId(questionBankId);
                asyncTestQuestions.getTestQuestions(exercise, loginUser.getUserId());
            }
        }
        return exerciseBaseResponse;
    }

    @Override
    public BaseResponse<BizGeneralResponse> againExercise(List<String> id) {
        BaseResponse<BizGeneralResponse> response = new BaseResponse<>();
        String userId = ContextUtils.getLoginUser().getUserId();
        List<TTrainTestQuestionsExercise> exercises = this.list(new QueryWrapper<TTrainTestQuestionsExercise>().in(TTrainTestQuestionsExercise.TEST_QUESTIONS_ID, id)
                .eq(TTrainTestQuestionsExercise.PERSON_ID, userId));
        boolean remove = remove(new QueryWrapper<TTrainTestQuestionsExercise>()
                .in(TTrainTestQuestionsExercise.TEST_QUESTIONS_ID, id)
                .eq(TTrainTestQuestionsExercise.PERSON_ID, userId)
        );
        if (exercises.size() > 0) {
            // 个人中心主键 id
            String myId = exercises.get(0).getMyId();
            tTrainMyManagementService.update(new UpdateWrapper<TTrainMyManagement>().eq(TTrainMyManagement.ID,myId)
                .set(TTrainMyManagement.TEST_QUESTIONS_NUM,"0").set(TTrainMyManagement.EXERCISE_NUM,"0")
                    .set(TTrainMyManagement.EXERCISE_RATE,"0").set(TTrainMyManagement.ERRORS_NUM,"0")
            );
        }
        response.setData(
                BizGeneralResponse.builder().result(TypeHelper.castToString(remove)).build());
        return response;
    }

    @Override
    public IPage<TTrainTestQuestionsExercise> errorRecord(TTrainTestQuestionsExerciseParam param,String userId) {
        Long page = StringHelper.isEmpty(param.getPage()) ? BizConstants.PAGE : Long.valueOf(param.getPage());
        Long limit = StringHelper.isEmpty(param.getLimit()) ? BizConstants.LIMIT : Long.valueOf(param.getLimit());
        Page<TTrainTestQuestionsExercise> resultPage = new Page<>(page, limit);
        return tTrainTestQuestionsExerciseDao.errorRecord(resultPage, param , userId);
    }

    @Override
    public BaseResponse<BaseResponseList<TestQuestionsContent>> getTestQuestions(Exercise exercise) throws Exception {
        BaseResponse<BaseResponseList<TestQuestionsContent>> baseResponse1 = new BaseResponse<>();
        if (StringHelper.isNotEmpty(exercise.getId())) {
            TTrainMyManagement management = tTrainMyManagementService.getById(exercise.getId());
            // 题库id
            String taskId = management.getTaskId();
            Long pages =
                    StringHelper.isEmpty(exercise.getPage()) ? BizConstants.PAGE : Long.valueOf(exercise.getPage());
            Long limits =
                    StringHelper.isEmpty(exercise.getLimit()) ? BizConstants.LIMIT : Long.valueOf(exercise.getLimit());
            Page<TTrainTestQuestions> resultPage = new Page<>(pages, limits);
            QueryWrapper<TTrainTestQuestions> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.eq(TTrainTestQuestions.QUESTION_BANK_ID, taskId);
            queryWrapper1.ne(TTrainTestQuestions.STATUS, BizConstants.STATUS_DELETE);
            Page<TTrainTestQuestions> page1 = tTrainTestQuestionsService.page(resultPage, queryWrapper1);
            BaseResponseList<TestQuestionsContent> baseResponseList = new BaseResponseList<>();
            // 通过条件获取题库所有试题
            List<TTrainTestQuestions> records = page1.getRecords();
            // 个人中心主键id
            String myid = exercise.getId();
            List<TestQuestionsContent> testQuestionsContents = getAllTest(records, myid);
            baseResponseList.setData(testQuestionsContents);
            baseResponseList.setTotal(page1.getTotal());
            baseResponse1.setData(baseResponseList);
        } else {
            throw new BusinessException("请求参数不正确");
        }
        return baseResponse1;
    }

    /**
     * 返回题库或试卷中试题的详细信息
     *
     * @param records 试题的集合
     * @return
     * @Param myid 个人中心主键id
     */
    private List<TestQuestionsContent> getAllTest(List<TTrainTestQuestions> records, String myid) {
        // 试卷中的所有试题
        List<TestQuestionsContent> testQuestionsContents = new ArrayList<>();
//        int num = 0;
        for (TTrainTestQuestions tTrainTestQuestions : records) {
            String testQuestionsType = tTrainTestQuestions.getTestQuestionsType();
            //试题id
            String questionsId = tTrainTestQuestions.getId();
//            num++;
            if ("SELECT".equals(testQuestionsType) || "MORE_SELECT".equals(testQuestionsType)) {
                // 每一个题目
                TestQuestionsContent testQuestionsContent = BeanHelper.beanToBean(tTrainTestQuestions, TestQuestionsContent.class);
                QueryWrapper<TTrainExamChoice> wrapper = new QueryWrapper<>();
                wrapper.eq(TTrainExamChoice.TEST_QUESTIONS_ID, questionsId);
                // 当前题目包含的所有选项
                List<TTrainExamChoice> list1 = tTrainExamChoiceService.list(wrapper);
                // 按照选项排序
                list1 = list1.stream().sorted(Comparator.comparing(TTrainExamChoice::getOptions))
                        .collect(Collectors.toList());
                List<Options> optionsList = new ArrayList<>();
                for (TTrainExamChoice tTrainExamChoice : list1) {
                    Options options = BeanHelper.beanToBean(tTrainExamChoice, Options.class);
                    String optionsTest = options.getOptions() + ": " + options.getOptionText();
                    options.setOptionText(optionsTest);
                    optionsList.add(options);
                }
                String testQuestionsContent1 =testQuestionsContent.getTestQuestionsContent();
                testQuestionsContent.setTestQuestionsContent(testQuestionsContent1);
                testQuestionsContent.setOptions(optionsList);
                String score = "";
                TTrainMyManagement management = tTrainMyManagementService.getById(myid);
                String testPaperId = management.getTestPaperId();
                if (StringHelper.isNotEmpty(testPaperId)) {
                    TTrainPaper trainPaper = tTrainPaperService.getById(testPaperId);
                    if ("SELECT".equals(testQuestionsType)) {
                        score = "(单选题、" + trainPaper.getSingleScore() + "分)";
                    }
                    if ("MORE_SELECT".equals(testQuestionsType)) {
                        score = "(多选题、" + trainPaper.getMoreScore() + "分)";
                    }
                }
                testQuestionsContent.setScore(score);
                testQuestionsContent.setDictKey(testQuestionsType);
                testQuestionsContents.add(testQuestionsContent);
            }
            if ("JUDGE".equals(testQuestionsType)) {
                // 每一个题目
                TestQuestionsContent testQuestionsContent = BeanHelper.beanToBean(tTrainTestQuestions, TestQuestionsContent.class);
                QueryWrapper<TTrainExamJudgment> wrapper = new QueryWrapper<>();
                wrapper.eq(TTrainExamJudgment.TEST_QUESTIONS_ID, questionsId);
                // 当前题目包含的所有选项
                List<TTrainExamJudgment> list1 = tTrainExamJudgmentService.list(wrapper);
                // 按照选项排序
                list1 = list1.stream().sorted(Comparator.comparing(TTrainExamJudgment::getOptions))
                        .collect(Collectors.toList());
                List<Options> optionsList = new ArrayList<>();
                for (TTrainExamJudgment tTrainExamChoice : list1) {
                    Options options = BeanHelper.beanToBean(tTrainExamChoice, Options.class);
                    String optionsTest = options.getOptions() + ": " + options.getOptionText();
                    options.setOptionText(optionsTest);
                    optionsList.add(options);
                }
                String testQuestionsContent1 =  testQuestionsContent.getTestQuestionsContent();
                testQuestionsContent.setTestQuestionsContent(testQuestionsContent1);
                testQuestionsContent.setOptions(optionsList);
                String score = "";
                TTrainMyManagement management = tTrainMyManagementService.getById(myid);
                String testPaperId = management.getTestPaperId();
                if (StringHelper.isNotEmpty(testPaperId)) {
                    TTrainPaper trainPaper = tTrainPaperService.getById(testPaperId);
                    if ("JUDGE".equals(testQuestionsType)) {
                        score = "(判断题、" + trainPaper.getJudgeScore() + "分)";
                    }
                }
                testQuestionsContent.setScore(score);
                testQuestionsContent.setDictKey(testQuestionsType);
                testQuestionsContents.add(testQuestionsContent);
            }
        }
        UserInfo loginUser = ContextUtils.getLoginUser();
        //得到已经做过的题目
        List<TTrainTestQuestionsExercise> list = this.list(new QueryWrapper<TTrainTestQuestionsExercise>()
                .eq(TTrainTestQuestionsExercise.MY_ID, myid)
                .eq(TTrainTestQuestionsExercise.PERSON_ID, loginUser.getUserId()).isNull(TTrainTestQuestionsExercise.PARENT_ID)
        );
        for (TestQuestionsContent test : testQuestionsContents) {
            for (TTrainTestQuestionsExercise tTrain : list) {
                if (test.getId().equals(tTrain.getTestQuestionsId())) {
                    test.setIsSelect("1");
                    test.setIsCorrect(tTrain.getIsCorrect());
                    if (StringHelper.isNotEmpty(tTrain.getOptionsId())) {
                        String[] split = tTrain.getOptionsId().split(",");
                        for (Options option : test.getOptions()) {
                            for (String s : split) {
                                if (option.getId().equals(s)) {
                                    option.setIsSelect("1");
                                }
                            }
                        }
                    }
                }
            }
        }
        List<TestQuestionsContent> collect = testQuestionsContents.stream().
                sorted(Comparator.comparing(TestQuestionsContent::getDictKey).reversed()).collect(Collectors.toList());
        AtomicInteger num = new AtomicInteger(1);
        collect.stream().forEach(item->{
            item.setTestQuestionsContent(num.getAndIncrement() +"."+item.getTestQuestionsContent());
        });
        return collect;
    }


    private List<TestQuestionsContent> getAllTestRetake(List<TTrainTestQuestions> records, String myid) {
        // 试卷中的所有试题
        List<TestQuestionsContent> testQuestionsContents = new ArrayList<>();
//        int num = 0;
        for (TTrainTestQuestions tTrainTestQuestions : records) {
            String testQuestionsType = tTrainTestQuestions.getTestQuestionsType();
            //试题id
            String questionsId = tTrainTestQuestions.getId();
//            num++;
            if ("SELECT".equals(testQuestionsType) || "MORE_SELECT".equals(testQuestionsType)) {
                // 每一个题目
                TestQuestionsContent testQuestionsContent = BeanHelper.beanToBean(tTrainTestQuestions, TestQuestionsContent.class);
                QueryWrapper<TTrainExamChoice> wrapper = new QueryWrapper<>();
                wrapper.eq(TTrainExamChoice.TEST_QUESTIONS_ID, questionsId);
                // 当前题目包含的所有选项
                List<TTrainExamChoice> list1 = tTrainExamChoiceService.list(wrapper);
                // 按照选项排序
                list1 = list1.stream().sorted(Comparator.comparing(TTrainExamChoice::getOptions))
                        .collect(Collectors.toList());
                List<Options> optionsList = new ArrayList<>();
                for (TTrainExamChoice tTrainExamChoice : list1) {
                    Options options = BeanHelper.beanToBean(tTrainExamChoice, Options.class);
                    String optionsTest = options.getOptions() + ": " + options.getOptionText();
                    options.setOptionText(optionsTest);
                    optionsList.add(options);
                }
                String testQuestionsContent1 =testQuestionsContent.getTestQuestionsContent();
                testQuestionsContent.setTestQuestionsContent(testQuestionsContent1);
                testQuestionsContent.setOptions(optionsList);
                String score = "";
                TTrainMyManagement management = tTrainMyManagementService.getById(myid);
                String testPaperId = management.getTestPaperId();
                if (StringHelper.isNotEmpty(testPaperId)) {
                    TTrainPaper trainPaper = tTrainPaperService.getById(testPaperId);
                    if ("SELECT".equals(testQuestionsType)) {
                        score = "(单选题、" + trainPaper.getSingleScore() + "分)";
                    }
                    if ("MORE_SELECT".equals(testQuestionsType)) {
                        score = "(多选题、" + trainPaper.getMoreScore() + "分)";
                    }
                }
                testQuestionsContent.setScore(score);
                testQuestionsContent.setDictKey(testQuestionsType);
                testQuestionsContents.add(testQuestionsContent);
            }
            if ("JUDGE".equals(testQuestionsType)) {
                // 每一个题目
                TestQuestionsContent testQuestionsContent = BeanHelper.beanToBean(tTrainTestQuestions, TestQuestionsContent.class);
                QueryWrapper<TTrainExamJudgment> wrapper = new QueryWrapper<>();
                wrapper.eq(TTrainExamJudgment.TEST_QUESTIONS_ID, questionsId);
                // 当前题目包含的所有选项
                List<TTrainExamJudgment> list1 = tTrainExamJudgmentService.list(wrapper);
                // 按照选项排序
                list1 = list1.stream().sorted(Comparator.comparing(TTrainExamJudgment::getOptions))
                        .collect(Collectors.toList());
                List<Options> optionsList = new ArrayList<>();
                for (TTrainExamJudgment tTrainExamChoice : list1) {
                    Options options = BeanHelper.beanToBean(tTrainExamChoice, Options.class);
                    String optionsTest = options.getOptions() + ": " + options.getOptionText();
                    options.setOptionText(optionsTest);
                    optionsList.add(options);
                }
                String testQuestionsContent1 =  testQuestionsContent.getTestQuestionsContent();
                testQuestionsContent.setTestQuestionsContent(testQuestionsContent1);
                testQuestionsContent.setOptions(optionsList);
                String score = "";
                TTrainMyManagement management = tTrainMyManagementService.getById(myid);
                String testPaperId = management.getTestPaperId();
                if (StringHelper.isNotEmpty(testPaperId)) {
                    TTrainPaper trainPaper = tTrainPaperService.getById(testPaperId);
                    if ("JUDGE".equals(testQuestionsType)) {
                        score = "(判断题、" + trainPaper.getJudgeScore() + "分)";
                    }
                }
                testQuestionsContent.setScore(score);
                testQuestionsContent.setDictKey(testQuestionsType);
                testQuestionsContents.add(testQuestionsContent);
            }
        }
        UserInfo loginUser = ContextUtils.getLoginUser();
        //得到已经做过的题目
        List<TTrainTestQuestionsExercise> list = this.list(new QueryWrapper<TTrainTestQuestionsExercise>()
                .eq(TTrainTestQuestionsExercise.PARENT_ID, myid)
                .eq(TTrainTestQuestionsExercise.PERSON_ID, loginUser.getUserId())
        );
        for (TestQuestionsContent test : testQuestionsContents) {
            for (TTrainTestQuestionsExercise tTrain : list) {
                if (test.getId().equals(tTrain.getTestQuestionsId())) {
                    test.setIsSelect("1");
                    test.setIsCorrect(tTrain.getIsCorrect());
                    if (StringHelper.isNotEmpty(tTrain.getOptionsId())) {
                        String[] split = tTrain.getOptionsId().split(",");
                        for (Options option : test.getOptions()) {
                            for (String s : split) {
                                if (option.getId().equals(s)) {
                                    option.setIsSelect("1");
                                }
                            }
                        }
                    }
                }
            }
        }
        List<TestQuestionsContent> collect = testQuestionsContents.stream().
                sorted(Comparator.comparing(TestQuestionsContent::getDictKey).reversed()).collect(Collectors.toList());
        AtomicInteger num = new AtomicInteger(1);
        collect.stream().forEach(item->{
            item.setTestQuestionsContent(num.getAndIncrement() +"."+item.getTestQuestionsContent());
        });
        return collect;
    }

    @Override
    public BaseResponse<ReturnTrainPaper> startExamine(String id) throws Exception{
        BaseResponse<ReturnTrainPaper> baseResponse = new BaseResponse<>();
        if (StringHelper.isNotEmpty(id)) {
            // 获取考试计划
            TTrainMyManagement management = tTrainMyManagementService.getById(id);
            if ("1".equals(management.getIsAddExam())) {
                throw new BusinessException("请勿重复考试");
            }
            if(!"3".equals(management.getLearnWay())){
                // 考试开始时间
                //String startTime = management.getVisitStartTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                String startTime =   DateUtil.convertDateToStr(management.getVisitStartTime(),"yyyy-MM-dd HH:mm:ss");
                // 考试结束时间
                //String endTime = management.getVisitEndTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                String endTime =  DateUtil.convertDateToStr(management.getVisitEndTime(),"yyyy-MM-dd HH:mm:ss");
                // 当前时间
                String currentTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                if (currentTime.compareTo(startTime) < 0) {
                    throw new BusinessException("考试时间未到");
                }
                if (currentTime.compareTo(endTime) > 0) {
                    throw new BusinessException("考试时间已过");
                }
            }

            String testPaperId = management.getTestPaperId();
            if (StringHelper.isNotEmpty(testPaperId)) {
                ReturnTrainPaper returnTrainPaper = new ReturnTrainPaper();
                TTrainPaper trainPaper = tTrainPaperService.getById(testPaperId);
                String[] testQuestionsId = trainPaper.getTestQuestionsId().split(",");
                List<TTrainTestQuestions> questions = tTrainTestQuestionsService.list(new QueryWrapper<TTrainTestQuestions>()
                        .in(TTrainTestQuestions.ID, testQuestionsId)
                        .ne(TTrainTestQuestions.STATUS, BizConstants.STATUS_DELETE)
                );
                List<TestQuestionsContent> allTest = getAllTest(questions, id);
                returnTrainPaper.setPassScore(trainPaper.getPassScore());
                returnTrainPaper.setFullScore(trainPaper.getFullScore());
                returnTrainPaper.setTestPaperName(trainPaper.getTestPaperName());
                returnTrainPaper.setTestQuestionsContent(allTest);
                baseResponse.setData(returnTrainPaper);
            }
        }
        return baseResponse;
    }

    @Override
    public BaseResponse<TTrainTestQuestionsExercise> submitTestPaper(List<TTrainTestQuestionsExercise> questBody) throws Exception{
        BaseResponse<TTrainTestQuestionsExercise> exerciseBaseResponse = new BaseResponse<>();
        if (ObjectHelper.isNotEmpty(questBody)) {
            UserInfo loginUser = ContextUtils.getLoginUser();
            List<TTrainTestQuestionsExercise> exercises = new ArrayList<>();
            // 保存所有试题id
            List<String> list = new ArrayList<>();
            String MYID = "";
            String parentId = "";
            if(ObjectHelper.isNotEmpty(questBody.get(0).getMyId())){
                parentId = questBody.get(0).getParentId();
            }
            for (TTrainTestQuestionsExercise tTrain : questBody) {
                TTrainTestQuestionsExercise tTrainTest = BeanHelper.beanToBean(tTrain, TTrainTestQuestionsExercise.class);
                tTrainTest.setPersonId(loginUser.getUserId());
                String s = "";
                // 对以做的题目进行判分
                if (StringHelper.isNotEmpty(tTrain.getOptionsId())) {
                    // 选择是否正确
                    s = checkIsCorrect(tTrain.getTestQuestionsId(), tTrain.getOptionsId());
                }else {
                    // 如果没有选择直接判错
                    s = "0";
                    tTrainTest.setOptionsId(IdHelper.getId32bit());
                }
                // 个人中心主键id
                MYID = tTrain.getMyId();
                list.add(tTrain.getTestQuestionsId());
                tTrainTest.setIsCorrect(s);
                exercises.add(tTrainTest);
            }
            TTrainMyManagement management = tTrainMyManagementService.getById(MYID);
            if(parentId == null || "".equals(parentId)){
                if ("1".equals(management.getIsAddExam())) {
                    throw new BusinessException("请勿重复考试");
                }
            }

            // 正式考的时候删除
            if(null == parentId){
                this.remove(new QueryWrapper<TTrainTestQuestionsExercise>()
                        .in(TTrainTestQuestionsExercise.TEST_QUESTIONS_ID, list)
                        .eq(TTrainTestQuestionsExercise.MY_ID, MYID)
                        .eq(TTrainTestQuestionsExercise.PERSON_ID, loginUser.getUserId()));
            }


            boolean result = this.saveBatch(exercises);
            if (result) {
                // 保存成功进行批卷处理
                markTestPaper(MYID,parentId);
            }
        }
        return exerciseBaseResponse;
    }

    @Override
    public BaseResponse<ReturnTrainPaper> getTestPaperDetail(String id) throws Exception {
        BaseResponse<ReturnTrainPaper> baseResponse = new BaseResponse<>();
        if (StringHelper.isNotEmpty(id)) {
            // 获取考试计划
            TTrainMyManagement management = tTrainMyManagementService.getById(id);
            if (ObjectHelper.isEmpty(management)) {
                return baseResponse;
            }
            String testPaperId = management.getTestPaperId();
            if (StringHelper.isNotEmpty(testPaperId)) {
                ReturnTrainPaper returnTrainPaper = new ReturnTrainPaper();
                TTrainPaper trainPaper = tTrainPaperService.getById(testPaperId);
                String[] testQuestionsId = trainPaper.getTestQuestionsId().split(",");
                List<TTrainTestQuestions> questions = tTrainTestQuestionsService.list(new QueryWrapper<TTrainTestQuestions>()
                        .in(TTrainTestQuestions.ID, testQuestionsId)
                        .ne(TTrainTestQuestions.STATUS, BizConstants.STATUS_DELETE)
                );
                List<TestQuestionsContent> allTest = getAllTest(questions, id);
                // 获取答题正确和错误的数量
                AtomicInteger trueNum = new AtomicInteger();
                AtomicInteger falseNum = new AtomicInteger();
                allTest.stream().forEach(item->{
                    if ("1".equals(item.getIsCorrect()) && "1".equals(item.getIsSelect())) {
                        trueNum.getAndIncrement();
                    }
                    if("0".equals(item.getIsCorrect()) && "1".equals(item.getIsSelect())){
                        falseNum.getAndIncrement();
                    }
                });
                returnTrainPaper.setTrueNum(String.valueOf(trueNum));
                returnTrainPaper.setFalseNum(String.valueOf(falseNum));
                returnTrainPaper.setPassScore(trainPaper.getPassScore());
                returnTrainPaper.setFullScore(trainPaper.getFullScore());
                returnTrainPaper.setTestPaperName(trainPaper.getTestPaperName());
                returnTrainPaper.setTestScore(management.getTestScore());
                returnTrainPaper.setTestQuestionsContent(allTest);
                baseResponse.setData(returnTrainPaper);
            }
        }
        return baseResponse;
    }

    @Override
    public BaseResponse<ReturnTrainPaper> startExamineRetake(String id) throws Exception {
        BaseResponse<ReturnTrainPaper> baseResponse = new BaseResponse<>();
        if (StringHelper.isNotEmpty(id)) {
            // 获取考试计划(如果没有补考记录就代表可以补考)
            TTrainMyManagement management = tTrainMyManagementDao.getDetail(id);
            if(null == management){
                // 获取考试计划
                management = tTrainMyManagementService.getById(id);
                if (ObjectHelper.isEmpty(management)) {
                    return baseResponse;
                }
            }
            String testPaperId = management.getTestPaperId();
            if (StringHelper.isNotEmpty(testPaperId)) {
                ReturnTrainPaper returnTrainPaper = new ReturnTrainPaper();
                TTrainPaper trainPaper = tTrainPaperService.getById(testPaperId);
                String[] testQuestionsId = trainPaper.getTestQuestionsId().split(",");
                List<TTrainTestQuestions> questions = tTrainTestQuestionsService.list(new QueryWrapper<TTrainTestQuestions>()
                        .in(TTrainTestQuestions.ID, testQuestionsId)
                        .ne(TTrainTestQuestions.STATUS, BizConstants.STATUS_DELETE)
                );
                List<TestQuestionsContent> allTest = getAllTest(questions, id);
                returnTrainPaper.setPassScore(trainPaper.getPassScore());
                returnTrainPaper.setFullScore(trainPaper.getFullScore());
                returnTrainPaper.setTestPaperName(trainPaper.getTestPaperName());
                returnTrainPaper.setTestQuestionsContent(allTest);
                baseResponse.setData(returnTrainPaper);
            }
        }
        return baseResponse;
    }

    @Override
    public List<TTrainTestQuestionsExercise> getByExaminationId(String id, String userId) {
        return baseMapper.getByExaminationId(id,userId);
    }

    @Override
    public BaseResponse<ReturnTrainPaper> getTestPaperRetakeDetail(String id) throws Exception {
        BaseResponse<ReturnTrainPaper> baseResponse = new BaseResponse<>();
        if (StringHelper.isNotEmpty(id)) {
            // 获取考试计划
            TTrainMyManagement management = tTrainMyManagementService.getById(id);
            if (ObjectHelper.isEmpty(management)) {
                return baseResponse;
            }
            String testPaperId = management.getTestPaperId();
            if (StringHelper.isNotEmpty(testPaperId)) {
                ReturnTrainPaper returnTrainPaper = new ReturnTrainPaper();
                TTrainPaper trainPaper = tTrainPaperService.getById(testPaperId);
                String[] testQuestionsId = trainPaper.getTestQuestionsId().split(",");
                List<TTrainTestQuestions> questions = tTrainTestQuestionsService.list(new QueryWrapper<TTrainTestQuestions>()
                        .in(TTrainTestQuestions.ID, testQuestionsId)
                        .ne(TTrainTestQuestions.STATUS, BizConstants.STATUS_DELETE)
                );
                List<TestQuestionsContent> allTest = getAllTestRetake(questions, id);
                // 获取答题正确和错误的数量
                AtomicInteger trueNum = new AtomicInteger();
                AtomicInteger falseNum = new AtomicInteger();
                allTest.stream().forEach(item->{
                    if ("1".equals(item.getIsCorrect()) && "1".equals(item.getIsSelect())) {
                        trueNum.getAndIncrement();
                    }
                    if("0".equals(item.getIsCorrect()) && "1".equals(item.getIsSelect())){
                        falseNum.getAndIncrement();
                    }
                });
                returnTrainPaper.setTrueNum(String.valueOf(trueNum));
                returnTrainPaper.setFalseNum(String.valueOf(falseNum));
                returnTrainPaper.setPassScore(trainPaper.getPassScore());
                returnTrainPaper.setFullScore(trainPaper.getFullScore());
                returnTrainPaper.setTestPaperName(trainPaper.getTestPaperName());
                returnTrainPaper.setTestScore(management.getRepairTest());
                returnTrainPaper.setTestQuestionsContent(allTest);
                baseResponse.setData(returnTrainPaper);
            }
        }
        return baseResponse;
    }

    @Override
    public List<TTrainTestQuestionsExercise> getByMyIdAndCreateBy(String id, String createBy) {
        return baseMapper.getByMyIdAndCreateBy(id,createBy);
    }

    /**
     * 个人中心主键id
     * 进行批改试卷处理
     * @param myid
     */
    public void markTestPaper(String myid,String parentId) throws Exception{
        // 获取一条考试计划
        TTrainMyManagement trainMyManagement = tTrainMyManagementService.getById(myid);
        // 获取试卷id
        String testPaperId = trainMyManagement.getTestPaperId();
        if (StringHelper.isNotEmpty(testPaperId)) {
            // 获得一条试卷数据
            TTrainPaper trainPaper = tTrainPaperService.getById(testPaperId);
            String[] testQuestionsId = trainPaper.getTestQuestionsId().split(",");
            List<TTrainTestQuestions> questions = tTrainTestQuestionsService.list(new QueryWrapper<TTrainTestQuestions>()
                    .in(TTrainTestQuestions.ID, testQuestionsId)
                    .ne(TTrainTestQuestions.STATUS, BizConstants.STATUS_DELETE)
            );
            // 获取试卷中的所有试题
            List<TestQuestionsContent> allTest = new ArrayList<>();
            if(null == parentId){
                allTest = getAllTest(questions, myid);
            }else{
                allTest = getAllTestRetake(questions, parentId);
            }

            // 试卷分数汇总并保存考试分数
            saveTestScore(allTest ,trainPaper,myid,parentId);
        }
    }

    /**
     * 试卷分数汇总并保存考试分数
     * @param allTest 试卷中的所有试题
     * @param trainPaper  试卷的详细信息
     * @param myid 个人中心主键id
     */
    private void saveTestScore(List<TestQuestionsContent> allTest, TTrainPaper trainPaper, String myid,String parentId) throws Exception{
        AtomicInteger score = new AtomicInteger();
        allTest.stream().forEach(item->{
            if ("SELECT".equals(item.getDictKey()) && "1".equals(item.getIsCorrect())) {
                score.addAndGet(Math.toIntExact(trainPaper.getSingleScore()));
            }
            if ("MORE_SELECT".equals(item.getDictKey()) && "1".equals(item.getIsCorrect())) {
                score.addAndGet(Math.toIntExact(trainPaper.getMoreScore()));
            }
            if ("JUDGE".equals(item.getDictKey()) && "1".equals(item.getIsCorrect())) {
                score.addAndGet(Math.toIntExact(trainPaper.getJudgeScore()));
            }
        });
        // 获取试卷得分
        String sum = String.valueOf(score.get());
        // 试卷及格分数
        String passScore = String.valueOf(trainPaper.getPassScore());
        // 考试情况
        String percentage = "";
        if (Integer.parseInt(sum) >= Integer.parseInt(passScore)) {
            percentage = "1";
        } else {
            percentage = "2";
        }
        boolean update = true;
        //parentId不为空时代表补考,否则为正常考试
        if(null == parentId || "".equals(parentId)){
            update = tTrainMyManagementService.update(new UpdateWrapper<TTrainMyManagement>()
                    .eq(TTrainMyManagement.ID, myid)
                    .set(TTrainMyManagement.TEST_SCORE, sum)
                    .set(TTrainMyManagement.IS_ADD_EXAM,"1")
                    .set(TTrainMyManagement.PERCENTAGE,percentage));
        }else{
            update = tTrainMyManagementService.update(new UpdateWrapper<TTrainMyManagement>()
                    .eq(TTrainMyManagement.ID, myid)
                    .set(TTrainMyManagement.REPAIR_TEST, sum)
                    .set(TTrainMyManagement.PERCENTAGE,percentage)
                    .set(TTrainMyManagement.IS_ADD_EXAM,"1"));

        }

        if (!update) {
            throw new BusinessException("更新考试成绩失败");
        }
    }

    /**
     * 检查所选试题是否正确
     *
     * @param testQuestionsId
     * @param optionsId
     */
    private String checkIsCorrect(String testQuestionsId, String optionsId) {
        TTrainTestQuestions one = tTrainTestQuestionsService.getOne(new QueryWrapper<TTrainTestQuestions>()
                .eq(TTrainTestQuestions.ID, testQuestionsId)
        );
        String testQuestionsType = one.getTestQuestionsType();
        String isCorrect = "";
        if ("SELECT".equals(testQuestionsType) || "MORE_SELECT".equals(testQuestionsType)) {
            // 获取所有正确选项
            List<TTrainExamChoice> list = tTrainExamChoiceService.list(new QueryWrapper<TTrainExamChoice>()
                    .eq(TTrainExamChoice.TEST_QUESTIONS_ID, testQuestionsId)
                    .eq(TTrainExamChoice.IS_CORRECT, "1")
            );
            String[] split = optionsId.split(",");
            if (list.size() != split.length) {
                return "0";
            }
            int count = 0;
            for (TTrainExamChoice choice : list) {
                for (String s : split) {
                    if (choice.getId().equals(s)) {
                        count++;
                    }
                }
            }
            if (count == list.size()) {
                isCorrect = "1";
            } else {
                isCorrect = "0";
            }
        }
        if ("JUDGE".equals(testQuestionsType)) {
            // 获取所有真确选项
            List<TTrainExamJudgment> list = tTrainExamJudgmentService.list(new QueryWrapper<TTrainExamJudgment>()
                    .eq(TTrainExamChoice.TEST_QUESTIONS_ID, testQuestionsId)
                    .eq(TTrainExamChoice.IS_CORRECT, "1")
            );
            String[] split = optionsId.split(",");
            if (list.size() != split.length) {
                return "0";
            }
            int count = 0;
            for (TTrainExamJudgment choice : list) {
                for (String s : split) {
                    if (choice.getId().equals(s)) {
                        count++;
                    }
                }
            }
            if (count == list.size()) {
                isCorrect = "1";
            } else {
                isCorrect = "0";
            }
        }
        return isCorrect;
    }

    /**
     * 判断所选试题是否真确
     *
     * @param optionsId 已选试题选项
     * @param list      正缺试题选项
     * @return
     */
    private String judgmentIsCorrect(String optionsId, List<TTrainExamChoice> list) {
        String[] split = optionsId.split(",");
        int length = list.size();
        int count = 0;
        for (TTrainExamChoice choice : list) {
            for (String s : split) {
                if (choice.getId().equals(s)) {
                    count++;
                }
            }
        }
        if (count == length) {
            return "1";
        } else {
            return "0";
        }
    }
}
