package com.ssj.service.conch.opentest;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ssj.bean.mybatis.OpenTestMBDto;
import com.ssj.bean.sys.opentest.*;
import com.ssj.bean.weixin.user.domain.User;
import com.ssj.framework.basic.config.bean.Config;
import com.ssj.framework.basic.config.service.ConfigService;
import com.ssj.framework.basic.utils.DateHelper;
import com.ssj.framework.core.security.manager.TokenManager;
import com.ssj.framework.core.util.ResponseEntity;
import com.ssj.framework.core.util.StringUtil;
import com.ssj.service.conch.opentest.dto.QuestionDto;
import com.ssj.service.conch.opentest.dto.ResultDto;
import com.ssj.service.conch.opentest.request.*;
import com.ssj.service.mapper.OpenTestMapper;
import com.ssj.service.sys.opentest.*;
import com.ssj.service.weixin.user.service.UserService;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

@Service
@Transactional
public class OpenTestServiceImpl implements OpenTestService {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private OpenTestUserService openTestUserService;

    @Autowired
    private OpenTestQuestionService openTestQuestionService;

    @Autowired
    private OpenTestResultService openTestResultService;

    @Autowired
    private OpenTestModuleResultService openTestModuleResultService;

    @Autowired
    private OpenTestTemplateService openTestTemplateService;

    @Autowired
    private OpenTestMapper openTestMapper;

    @Autowired
    private UserService userService;

    @Autowired
    private TokenManager tokenManager;

    @Autowired
    private ConfigService configService;

    @Autowired
    private RecordQuestionService recordQuestionService;

    @Override
    public ResponseEntity saveInfo(SaveInfoReq req, String userId) {
        ResponseEntity responseEntity = new ResponseEntity();
        OpenTestUser user = openTestUserService.findByUserId(userId);
        if (user == null) {
            user = new OpenTestUser();
        }
        user.setName(req.getName());
        user.setUserId(userId);
        user.setPhone(req.getPhone());
        user.setSchool(req.getSchool());
        user.setOrganization(req.getOrganization());
        user.setCreateTime(new Date());
        openTestUserService.save(user);
        responseEntity.success("成功");
        return responseEntity;
    }

    @Override
    public ResponseEntity getMyInfo(String userId) {
        ResponseEntity responseEntity = new ResponseEntity();
        Map<String, Object> data = new HashMap<>();
        User user = userService.getById(userId);
        if (user == null) {
            return responseEntity.failure("找不到该用户");
        }
        data.put("imgUrl", user.getPhoto());
        data.put("wxName", user.getName());
        data.put("name", "");
        data.put("phone", "");
        data.put("school", "");
        data.put("organization", "");
        OpenTestUser openTestUser = openTestUserService.findByUserId(userId);
        if (openTestUser != null) {
            data.put("name", openTestUser.getName());
            data.put("phone", openTestUser.getPhone());
            data.put("school", openTestUser.getSchool());
            data.put("organization", openTestUser.getOrganization());
        }
        return responseEntity.success(data, "成功");
    }

    @Override
    public ResponseEntity getQuestion(GetQuestionReq req,String userId) {
        ResponseEntity responseEntity = new ResponseEntity();
        Map<String, Object> data = new HashMap<>();
        List<QuestionDto> list = new ArrayList<>();
        //查看该套题目是否已经答过
        OpenTestResult result = openTestResultService.findResult(userId, req.getGrade(), req.getSubject(), req.getVersion());
        //未答过该题
        if (result == null) {
            List<OpenTestQuestion> questionList = openTestQuestionService.findQuestionList(req.getSubject(), req.getGrade(), req.getVersion(), null);
            questionList.forEach(e -> {
                List<QuestionDto.Option> optionList = new ArrayList<>();
                QuestionDto dto = new QuestionDto();
                dto.setQuestionId(e.getId());
                dto.setQuestionNo(e.getQuestionNum());
                dto.setQuestion(e.getQuestion());
                dto.setModule(e.getModule());
                dto.setAnswer(e.getOptionAnswer());
                //选项内容
                String optionContent = e.getOptionContent();
                if (StringUtil.isNotBlank(optionContent)) {
                    //将选项分离出来
                    String[] options = optionContent.split("#S");
                    String value = "";
                    for (int i = 0; i < options.length; i++) {
                        QuestionDto.Option option = dto.new Option();
                        String s = options[i];
                        //这个是图片选项
                        if (s.contains("img:")) {
                            switch (i) {
                                case 0:
                                    value = s.substring(s.indexOf("A.img:") + 6);
                                    option.setOption("A");
                                    break;
                                case 1:
                                    value = s.substring(s.indexOf("B.img:") + 6);
                                    option.setOption("B");
                                    break;
                                case 2:
                                    value = s.substring(s.indexOf("C.img:") + 6);
                                    option.setOption("C");
                                    break;
                                case 3:
                                    value = s.substring(s.indexOf("D.img:") + 6);
                                    option.setOption("D");
                                    break;
                                case 4:
                                    value = s.substring(s.indexOf("E.img:") + 6);
                                    option.setOption("E");
                                    break;
                                case 5:
                                    value = s.substring(s.indexOf("F.img:") + 6);
                                    option.setOption("F");
                                    break;
                                case 6:
                                    value = s.substring(s.indexOf("G.img:") + 6);
                                    option.setOption("G");
                                case 7:
                                    value = s.substring(s.indexOf("H.img:") + 2);
                                    option.setOption("H");
                                    break;
                                default:
                                    break;
                            }
                            option.setType(2);
                        } else {
                            //这里是文字选项
                            switch (i) {
                                case 0:
                                    value = s.substring(s.indexOf("A.") + 2);
                                    option.setOption("A");
                                    break;
                                case 1:
                                    value = s.substring(s.indexOf("B.") + 2);
                                    option.setOption("B");
                                    break;
                                case 2:
                                    value = s.substring(s.indexOf("C.") + 2);
                                    option.setOption("C");
                                    break;
                                case 3:
                                    value = s.substring(s.indexOf("D.") + 2);
                                    option.setOption("D");
                                    break;
                                case 4:
                                    value = s.substring(s.indexOf("E.") + 2);
                                    option.setOption("E");
                                    break;
                                case 5:
                                    value = s.substring(s.indexOf("F.") + 2);
                                    option.setOption("F");
                                    break;
                                case 6:
                                    value = s.substring(s.indexOf("G.") + 2);
                                    option.setOption("G");
                                    break;
                                case 7:
                                    value = s.substring(s.indexOf("H.") + 2);
                                    option.setOption("H");
                                    break;
                                default:
                                    break;
                            }
                            option.setType(1);
                        }
                        option.setValue(value);
                        optionList.add(option);
                    }
                    dto.setOptionList(optionList);
                }
                list.add(dto);
            });
            data.put("resultId", "");
            //属于哪套题，更新版本号
            data.put("updateVersion", questionList.size() > 0 ? questionList.get(0).getUpdateVersion() : 0);
        } else {
            data.put("resultId", result.getId());
            data.put("updateVersion", 0);
        }
        data.put("list", list);
        return responseEntity.success(data, "成功");
    }

    @Override
    public ResponseEntity getQuestionV1(GetQuestionV1Req req,String userId) {
        ResponseEntity responseEntity = new ResponseEntity();
        Map<String, Object> data = new HashMap<>(16);
        List<QuestionDto> list = new ArrayList<>();
        List<OpenTestQuestion> questionList = openTestQuestionService.findQuestionList(req.getSubject(), req.getGrade(), req.getVersion(), req.getUnit(), 1, req.getType(), req.getSemester());
        if (CollectionUtils.isNotEmpty(questionList)) {
            questionList.forEach(e -> {
                List<QuestionDto.Option> optionList = new ArrayList<>();
                QuestionDto dto = new QuestionDto();
                dto.setQuestionId(e.getId());
                dto.setQuestionNo(e.getQuestionNum());
                dto.setQuestion(e.getQuestion());
                dto.setModule(e.getModule());
                dto.setAnswer(e.getOptionAnswer());
                //选项内容
                String optionContent = e.getOptionContent();
                if (StringUtil.isNotBlank(optionContent)) {
                    //将选项分离出来
                    String[] options = optionContent.split("#S");
                    String value = "";
                    for (int i = 0; i < options.length; i++) {
                        QuestionDto.Option option = dto.new Option();
                        String s = options[i];
                        //这里是文字选项
                        switch (i) {
                            case 0:
                                value = s.substring(s.indexOf("A.") + 2);
                                option.setOption("A");
                                break;
                            case 1:
                                value = s.substring(s.indexOf("B.") + 2);
                                option.setOption("B");
                                break;
                            case 2:
                                value = s.substring(s.indexOf("C.") + 2);
                                option.setOption("C");
                                break;
                            case 3:
                                value = s.substring(s.indexOf("D.") + 2);
                                option.setOption("D");
                                break;
                            case 4:
                                value = s.substring(s.indexOf("E.") + 2);
                                option.setOption("E");
                                break;
                            case 5:
                                value = s.substring(s.indexOf("F.") + 2);
                                option.setOption("F");
                                break;
                            case 6:
                                value = s.substring(s.indexOf("G.") + 2);
                                option.setOption("G");
                                break;
                            case 7:
                                value = s.substring(s.indexOf("H.") + 2);
                                option.setOption("H");
                                break;
                            default:
                                break;
                        }
                        option.setValue(value);
                        optionList.add(option);
                    }
                    dto.setOptionList(optionList);
                }
                list.add(dto);
            });
        }
        data.put("resultId", "");
        //属于哪套题，更新版本号
        data.put("updateVersion", questionList.size() > 0 ? questionList.get(0).getUpdateVersion() : 0);
        data.put("list", list);
        return responseEntity.success(data, "成功");
    }



    @Override
    public ResponseEntity getTestList(String userId) {
        ResponseEntity responseEntity = new ResponseEntity();
        Map<String, Object> data = new HashMap<>();
        List<Map<String, Object>> list = new ArrayList<>();
        //该用户所有测评结果
        List<OpenTestResult> resultList = openTestResultService.findByUserId(userId);
        if (resultList.size() > 0) {
            resultList.forEach(result -> {
                Map<String, Object> resultMap = new HashMap<>();
                resultMap.put("resultId", result.getId());
                resultMap.put("version", result.getVersion());
                resultMap.put("grade", result.getGrade());
                resultMap.put("subject", result.getSubject());
                list.add(resultMap);
            });
        }
        data.put("list", list);
        return responseEntity.success(data, "成功");
    }

    @Override
    public ResponseEntity getTestListV1(String userId, int type) {
        ResponseEntity responseEntity = new ResponseEntity();
        Map<String, Object> data = new HashMap<>();
        List<Map<String, Object>> list = new ArrayList<>();
        //该用户所有测评结果
        List<OpenTestResult> resultList = openTestResultService.findByUserIdAndType(userId, type);
        if (resultList.size() > 0) {
            resultList.forEach(result -> {
                Map<String, Object> resultMap = new HashMap<>(16);
                resultMap.put("resultId", result.getId());
                resultMap.put("version", result.getVersion());
                resultMap.put("grade", result.getGrade());
                resultMap.put("subject", result.getSubject());
                resultMap.put("unit", result.getUnit() != null ? result.getUnit() : "");
                resultMap.put("semester", result.getSemester());
                list.add(resultMap);
            });
        }
        data.put("list", list);
        return responseEntity.success(data, "成功");
    }

    @Override
    public ResponseEntity getResult(GetResultReq req) {
        ResponseEntity responseEntity = new ResponseEntity();
        Map<String, Object> data = new HashMap<>();
        OpenTestResult result = openTestResultService.getById(req.getResultId());
        if (result == null) {
            return responseEntity.failure("不存在该结果");
        }
        int minute = result.getTime() / 60;
        int second = result.getTime() % 60;
        String time = "";
        if (minute < 10) {
            time += "0" + minute;
        } else {
            time += minute;
        }
        if (second < 10) {
            time += ":0" + second;
        } else {
            time += ":" + second;
        }
        data.put("time", time);
        data.put("answer", result.getAnswer());
        data.put("accuracyExceed", result.getAccuracyExceed());
        data.put("speedExceed", result.getSpeedExceed());
        data.put("version", result.getVersion());
        data.put("grade", result.getGrade());
        data.put("subject", result.getSubject());
        return responseEntity.success(data, "成功");
    }

    @Override
    public ResponseEntity getResultV1(GetResultReq req) {
        ResponseEntity responseEntity = new ResponseEntity();
        ResultDto resultDto = new ResultDto();
        OpenTestResult result = openTestResultService.getById(req.getResultId());
        if (result == null) {
            return responseEntity.failure("不存在该结果");
        }
        int minute = result.getTime() / 60;
        int second = result.getTime() % 60;
        String time = "";
        if (minute < 10) {
            time += "0" + minute;
        } else {
            time += minute;
        }
        if (second < 10) {
            time += ":0" + second;
        } else {
            time += ":" + second;
        }
        resultDto.setDuration(result.getTime());
        resultDto.setTime(time);
        resultDto.setAccuracyExceed(result.getAccuracyExceed());
        resultDto.setSpeedExceed(result.getSpeedExceed());
        resultDto.setVersion(result.getVersion());
        resultDto.setGrade(result.getGrade());
        resultDto.setSubject(result.getSubject());
        resultDto.setType(result.getType());
        resultDto.setUnit(result.getUnit());
        resultDto.setScore(result.getScore());
        resultDto.setSemester(result.getSemester());
        //格式1：“题号,答题情况,知识模块,题目id,答案;题目id,题号,答题情况,知识模块,题目id,答案”
        //格式2：“题号#S答题情况#S知识点#S题目id#S答案;题目id#S题号#S答题情况#S知识点#S题目id#S答案”
        //答题情况（1：正确，2：错误，3：未答题）
        String answerString = result.getAnswer();
        //题目对应的我的回答
        Map<String, String> answerMap = new HashMap<>();
        //答案列表
        String[] answerArray = answerString.split(";");
        for (String answer : answerArray) {
            String[] answerArray1;
            //单元测评的由于知识点里面有“,”所以使用“#S”来分割
            if (result.getType() == 2 || result.getType() == 3) {
                answerArray1 = answer.split("#S");
            } else {
                answerArray1 = answer.split(",");
            }
            if (answerArray1.length > 4) {
                //题目id->答案
                answerMap.put(answerArray1[3], answerArray1[4]);
            }
        }
        List<ResultDto.Question> questionDtoList = new ArrayList<>();
        //获取某一个更新版本的题目
        List<OpenTestQuestion> testQuestionList = openTestQuestionService.findQuestionList(result.getSubject(), result.getGrade(), result.getVersion(), result.getUnit(), result.getQuestionVersion(), result.getType(), result.getSemester());
        testQuestionList.forEach(e -> {
            List<ResultDto.Question.Option> optionList = new ArrayList<>();
            ResultDto.Question questionDto = resultDto.new Question();
            questionDto.setQuestionId(e.getId());
            questionDto.setQuestionNo(e.getQuestionNum());
            questionDto.setQuestion(e.getQuestion());
            questionDto.setModule(e.getModule());
            //正确答案
            questionDto.setRightAnswer(e.getOptionAnswer());
            //我的回答
            questionDto.setMyAnswer(answerMap.get(questionDto.getQuestionId()) != null ? answerMap.get(questionDto.getQuestionId()) : null);
            //选项内容
            String optionContent = e.getOptionContent();
            if (StringUtil.isNotBlank(optionContent)) {
                //将选项分离出来
                String[] options = optionContent.split("#S");
                String value = "";
                for (int i = 0; i < options.length; i++) {
                    ResultDto.Question.Option option = questionDto.new Option();
                    String s = options[i];
                    //选项内容（富文本方式）
                    switch (i) {
                        case 0:
                            value = s.substring(s.indexOf("A.") + 2);
                            option.setOption("A");
                            break;
                        case 1:
                            value = s.substring(s.indexOf("B.") + 2);
                            option.setOption("B");
                            break;
                        case 2:
                            value = s.substring(s.indexOf("C.") + 2);
                            option.setOption("C");
                            break;
                        case 3:
                            value = s.substring(s.indexOf("D.") + 2);
                            option.setOption("D");
                            break;
                        case 4:
                            value = s.substring(s.indexOf("E.") + 2);
                            option.setOption("E");
                            break;
                        case 5:
                            value = s.substring(s.indexOf("F.") + 2);
                            option.setOption("F");
                            break;
                        case 6:
                            value = s.substring(s.indexOf("G.") + 2);
                            option.setOption("G");
                            break;
                        case 7:
                            value = s.substring(s.indexOf("H.") + 2);
                            option.setOption("H");
                            break;
                        default:
                            break;
                    }
                    option.setValue(value);
                    optionList.add(option);
                }
                questionDto.setOptionList(optionList);
            }
            questionDtoList.add(questionDto);
        });
        resultDto.setList(questionDtoList);
        return responseEntity.success(resultDto, "成功");
    }

    @Override
    public ResponseEntity saveResult(SaveResultReq req, String userId) {
        ResponseEntity responseEntity = new ResponseEntity();
        Map<String, Object> data = new HashMap<>();
        Date now = new Date();
        OpenTestUser openTestUser = openTestUserService.findByUserId(userId);
        if (openTestUser == null) {
            return responseEntity.failure("不存在该用户，请完善资料");
        }
        //保存结果
        OpenTestResult result = new OpenTestResult();
        Map<String, Object> params = new HashMap<>();
        //记录各个知识点正确的数量
        Map<String, Integer> moduleRightNumMap = new HashMap<>();
        //记录各个知识点的总数
        Map<String, Integer> moduleTotalMap = new LinkedHashMap<>();
        //答题拼接结果：题号,答题情况,知识模块,题目id,答案;题目id,题号,答题情况,知识模块,题目id,答案
        String answerString = "";
        try {
            int second = 0;
            if (req.getDuration() != null) {
                second = req.getDuration();
            } else if (StringUtil.isNotBlank(req.getTime())) {
                //计算时间
                String[] time = req.getTime().split(":");
                second = Integer.parseInt(time[0]) * 60 + Integer.parseInt(time[1]);
            }
            result.setTime(second);
            params.put("time", second);
            //计算正确率
            //回答
            List<SaveResultReq.AnswerReq> answerReqList = req.getAnswerList();
            //正确题目数量
            int rightNum = 0;
            for (SaveResultReq.AnswerReq e : answerReqList) {
                String module = e.getModule();
                int situation = e.getSituation();
                //统计总数量
                if (moduleTotalMap.get(module) == null) {
                    moduleTotalMap.put(module, 1);
                } else {
                    moduleTotalMap.put(module, moduleTotalMap.get(module) + 1);
                }
                //统计正确的数量
                if (situation == 1) {
                    rightNum++;
                    if (moduleRightNumMap.get(module) == null) {
                        moduleRightNumMap.put(module, 1);
                    } else {
                        moduleRightNumMap.put(module, moduleRightNumMap.get(module) + 1);
                    }
                }
                //题号,答题情况,知识模块,题目id,答案;题目id,题号,答题情况,知识模块,题目id,答案
                answerString += e.getQuestionNo() + "," + e.getSituation() + "," + e.getModule() + "," + e.getQuestionId() + "," + e.getAnswer() + ";";
            }
            /*//回答(示例：”1,1,字词;2,2,字词;3,3,字词;4,1,字词;5:2,字词”) 用“题id,题号,答题情况,知识模块;题号,答题情况,知识模块”这种格式，答题情况（1：正确，2：错误，3：未答题）
            String[] answers = req.getAnswer().split(";");
            //正确题目数量
            int rightNum = 0;
            for (String answer : answers) {
                String[] answerDetails = answer.split(",");
                //答题情况（1：正确，2：错误，3：未答题）
                String situation = answerDetails[1];
                //知识模块
                String module = answerDetails[2];
                //统计总数量
                if (moduleTotalMap.get(module) == null) {
                    moduleTotalMap.put(module, 1);
                } else {
                    moduleTotalMap.put(module, moduleTotalMap.get(module) + 1);
                }
                //统计正确的数量
                if ("1".equals(situation)) {
                    rightNum++;
                    if (moduleRightNumMap.get(module) == null) {
                        moduleRightNumMap.put(module, 1);
                    } else {
                        moduleRightNumMap.put(module, moduleRightNumMap.get(module) + 1);
                    }
                }
            }*/
            //正确率
            BigDecimal accuracyRate = new BigDecimal((double) rightNum / answerReqList.size() * 100).setScale(2, BigDecimal.ROUND_HALF_UP);
            params.put("accuracyRate", accuracyRate);
            result.setAccuracyRate(accuracyRate);
            result.setScore(accuracyRate.setScale(0, BigDecimal.ROUND_HALF_UP).intValue());
        } catch (Exception e) {
            return responseEntity.failure("时间或答案传参错误");
        }
        params.put("grade", req.getGrade());
        params.put("subject", req.getSubject());
        if ("语文".equals(req.getSubject()) && StringUtil.isBlank(req.getVersion())) {
            params.put("version", "部编版");
        } else {
            params.put("version", req.getVersion());
        }
        //计算人数
        OpenTestMBDto openTestMBDto = openTestMapper.countResult(params);
        if (openTestMBDto.getTotal() > 0) {
            //计算速度超过百分比
            BigDecimal speedExceed = new BigDecimal((double) openTestMBDto.getTimeLower() / openTestMBDto.getTotal() * 100).setScale(2, BigDecimal.ROUND_HALF_UP);
            result.setSpeedExceed(speedExceed + "%");
            //计算正确率超过百分比
            BigDecimal accuracyExceed = new BigDecimal((double) openTestMBDto.getAccuracyLower() / openTestMBDto.getTotal() * 100).setScale(2, BigDecimal.ROUND_HALF_UP);
            result.setAccuracyExceed(accuracyExceed + "%");
        } else {
            result.setSpeedExceed("100%");
            result.setAccuracyExceed("100%");
        }
        result.setSubject(req.getSubject());
        result.setGrade(req.getGrade());
        result.setVersion(req.getVersion());
        result.setAnswer(answerString);
        result.setUserId(userId);
        result.setTestUserId(openTestUser.getId());
        result.setCreateTime(now);
        result.setQuestionVersion(req.getUpdateVersion());
        openTestResultService.save(result);
        //“掌握良好”的知识模块
        String zwlh = "";
        //“部分掌握”的知识模块
        String bfzw = "";
        //“未能掌握”的知识模块
        String wnzw = "";
        //计算各个知识点答题情况
        int i = 1;
        for (String key : moduleTotalMap.keySet()) {
            //该知识点题目总数
            Integer total = moduleTotalMap.get(key);
            //该知识点回答正确数量
            Integer rightNum = moduleRightNumMap.get(key) != null ? moduleRightNumMap.get(key) : 0;
            OpenTestModuleResult moduleResult = new OpenTestModuleResult();
            //知识模块的排序
            moduleResult.setModuleSort(i++);
            moduleResult.setName(key);
            moduleResult.setResultId(result.getId());
            moduleResult.setUserId(userId);
            moduleResult.setTestUserId(openTestUser.getId());
            moduleResult.setCreateTime(now);
            moduleResult.setRightNum(rightNum);
            moduleResult.setWrongNum(total - rightNum);
            moduleResult.setGrade(req.getGrade());
            moduleResult.setSubject(req.getSubject());
            moduleResult.setVersion(result.getVersion());
            //正确率(这个存的数保留两位小数，如99.99，实际上这个正确率是99.99%)
            BigDecimal accuracyRate = new BigDecimal((double) rightNum / total * 100).setScale(2, BigDecimal.ROUND_HALF_UP);
            moduleResult.setAccuracyRate(accuracyRate);
            //所有人平均正确率(这个存的数保留两位小数，如99.99，实际上这个正确率是99.99%)
            Double otherAvgAccuracyRate = openTestModuleResultService.findAvgAccuracyRate(key, req.getSubject(), req.getGrade(), req.getVersion());
            //证明我是第一个测试数据的
            if(otherAvgAccuracyRate==null){
                moduleResult.setAvgAccuracyRate(accuracyRate);
            }else{
                //把我的和别人的数据平均一下
                BigDecimal avgAccuracyRate = new BigDecimal((accuracyRate.doubleValue() + otherAvgAccuracyRate) / 2).setScale(2, BigDecimal.ROUND_HALF_UP);
                moduleResult.setAvgAccuracyRate(avgAccuracyRate);
            }
            //测试诊断模板
            OpenTestTemplate template = openTestTemplateService.findTemplate(key, rightNum.toString(), req.getSubject(), req.getGrade(), req.getVersion());
            if (template != null) {
                moduleResult.setSituation(template.getSituation());
                moduleResult.setAnswerSituation(template.getAnswerSituation());
                moduleResult.setSuggestion(template.getSuggestion());
                if ("掌握良好".equals(template.getSituation())) {
                    if (zwlh == "") {
                        zwlh += key;
                    } else {
                        zwlh += "、" + key;
                    }
                } else if ("部分掌握".equals(template.getSituation())) {
                    if (bfzw == "") {
                        bfzw += key;
                    } else {
                        bfzw += "、" + key;
                    }
                } else if ("未能掌握".equals(template.getSituation())) {
                    if (wnzw == "") {
                        wnzw += key;
                    } else {
                        wnzw += "、" + key;
                    }
                }
            }
            openTestModuleResultService.save(moduleResult);
        }
        //根据我们对你的观察，发现你已经对【知识模块】、【知识模块】和【知识模块】掌握良好。
        //在【知识模块】和【知识模块】上，测试显示你还有部分知识未掌握。
        //在【知识模块】、【知识模块】和【知识模块】上，你掌握得还不够充分，需要加强学习和练习。
        String explanation = "根据我们对你的观察，发现你";
        if (zwlh != "") {
            explanation+="已经对"+zwlh+"掌握良好。";
        }
        if (bfzw != "") {
            explanation+="在"+bfzw+"上，测试显示你还有部分知识未掌握。";
        }
        if (wnzw != "") {
            explanation+="在"+wnzw+"上，你掌握得还不够充分，需要加强学习和练习。";
        }
        //诊断说明
        result.setExplanation(explanation);
        openTestResultService.save(result);
        data.put("resultId", result.getId());
        data.put("accuracyExceed", result.getAccuracyExceed());
        data.put("speedExceed", result.getSpeedExceed());
        return responseEntity.success(data, "成功");
    }

    @Override
    public ResponseEntity saveResultV1(SaveResultV1Req req, String userId) {
        ResponseEntity responseEntity;
        //查找是否已答，已答则清除
        OpenTestResult result = openTestResultService.findResult(userId, req.getGrade(), req.getSubject(), req.getVersion(), req.getUnit(), req.getSemester(), req.getType());
        if (result != null) {
            result.setIsDelete(1);
            openTestResultService.save(result);
        }
        if (req.getType() == 1) {
            //提交学前测评答题结果
            responseEntity = this.saveOpenTestResult(req, userId);
        } else {
            //提交单元测评答题结果
            responseEntity = this.saveUnitTestResult(req, userId);
        }
        return responseEntity;
    }

    private ResponseEntity saveOpenTestResult(SaveResultV1Req req, String userId) {
        ResponseEntity responseEntity = new ResponseEntity();
        Map<String, Object> data = new HashMap<>();
        Date now = new Date();
        OpenTestUser openTestUser = openTestUserService.findByUserId(userId);
        if (openTestUser == null) {
            return responseEntity.failure("不存在该用户，请完善资料");
        }
        //保存结果
        OpenTestResult result = new OpenTestResult();
        Map<String, Object> params = new HashMap<>();
        //记录各个知识点正确的数量
        Map<String, Integer> moduleRightNumMap = new HashMap<>();
        //记录各个知识点的总数
        Map<String, Integer> moduleTotalMap = new LinkedHashMap<>();
        //答题拼接结果：题号,答题情况,知识模块,题目id,答案;题目id,题号,答题情况,知识模块,题目id,答案
        String answerString = "";
        try {
            int second = 0;
            if (req.getDuration() != null) {
                second = req.getDuration();
            }
            result.setTime(second);
            params.put("time", second);
            //计算正确率
            //回答
            List<SaveResultV1Req.AnswerReq> answerReqList = req.getAnswerList();
            //正确题目数量
            int rightNum = 0;
            for (SaveResultV1Req.AnswerReq e : answerReqList) {
                String module = e.getModule();
                int situation = e.getSituation();
                //统计总数量
                if (moduleTotalMap.get(module) == null) {
                    moduleTotalMap.put(module, 1);
                } else {
                    moduleTotalMap.put(module, moduleTotalMap.get(module) + 1);
                }
                //统计正确的数量
                if (situation == 1) {
                    rightNum++;
                    if (moduleRightNumMap.get(module) == null) {
                        moduleRightNumMap.put(module, 1);
                    } else {
                        moduleRightNumMap.put(module, moduleRightNumMap.get(module) + 1);
                    }
                }
                //题号,答题情况,知识模块,题目id,答案;题目id,题号,答题情况,知识模块,题目id,答案
                answerString += e.getQuestionNo() + "," + e.getSituation() + "," + e.getModule() + "," + e.getQuestionId() + "," + e.getAnswer() + ";";
            }
            //正确率
            BigDecimal accuracyRate = new BigDecimal((double) rightNum / answerReqList.size() * 100).setScale(2, BigDecimal.ROUND_HALF_UP);
            params.put("accuracyRate", accuracyRate);
            result.setAccuracyRate(accuracyRate);
            result.setScore(accuracyRate.setScale(0, BigDecimal.ROUND_HALF_UP).intValue());
        } catch (Exception e) {
            return responseEntity.failure("时间或答案传参错误");
        }
        params.put("grade", req.getGrade());
        params.put("subject", req.getSubject());
        if ("语文".equals(req.getSubject()) && StringUtil.isBlank(req.getVersion())) {
            params.put("version", "部编版");
        } else {
            params.put("version", req.getVersion());
        }
        //计算人数
        OpenTestMBDto openTestMBDto = openTestMapper.countResult(params);
        if (openTestMBDto.getTotal() > 0) {
            //计算速度超过百分比
            BigDecimal speedExceed = new BigDecimal((double) openTestMBDto.getTimeLower() / openTestMBDto.getTotal() * 100).setScale(2, BigDecimal.ROUND_HALF_UP);
            result.setSpeedExceed(speedExceed + "%");
            //计算正确率超过百分比
            BigDecimal accuracyExceed = new BigDecimal((double) openTestMBDto.getAccuracyLower() / openTestMBDto.getTotal() * 100).setScale(2, BigDecimal.ROUND_HALF_UP);
            result.setAccuracyExceed(accuracyExceed + "%");
        } else {
            result.setSpeedExceed("100%");
            result.setAccuracyExceed("100%");
        }
        result.setType(req.getType());
        result.setSubject(req.getSubject());
        result.setGrade(req.getGrade());
        result.setVersion(req.getVersion());
        result.setAnswer(answerString);
        result.setUserId(userId);
        result.setTestUserId(openTestUser.getId());
        result.setCreateTime(now);
        result.setQuestionVersion(req.getUpdateVersion());
        result.setSemester(req.getSemester());
        openTestResultService.save(result);
        //“掌握良好”的知识模块
        String zwlh = "";
        //“部分掌握”的知识模块
        String bfzw = "";
        //“未能掌握”的知识模块
        String wnzw = "";
        //计算各个知识点答题情况
        int i = 1;
        for (String key : moduleTotalMap.keySet()) {
            //该知识点题目总数
            Integer total = moduleTotalMap.get(key);
            //该知识点回答正确数量
            Integer rightNum = moduleRightNumMap.get(key) != null ? moduleRightNumMap.get(key) : 0;
            OpenTestModuleResult moduleResult = new OpenTestModuleResult();
            //知识模块的排序
            moduleResult.setModuleSort(i++);
            moduleResult.setName(key);
            moduleResult.setResultId(result.getId());
            moduleResult.setUserId(userId);
            moduleResult.setTestUserId(openTestUser.getId());
            moduleResult.setCreateTime(now);
            moduleResult.setRightNum(rightNum);
            moduleResult.setWrongNum(total - rightNum);
            moduleResult.setGrade(req.getGrade());
            moduleResult.setSubject(req.getSubject());
            moduleResult.setVersion(result.getVersion());
            //正确率(这个存的数保留两位小数，如99.99，实际上这个正确率是99.99%)
            BigDecimal accuracyRate = new BigDecimal((double) rightNum / total * 100).setScale(2, BigDecimal.ROUND_HALF_UP);
            moduleResult.setAccuracyRate(accuracyRate);
            //所有人平均正确率(这个存的数保留两位小数，如99.99，实际上这个正确率是99.99%)
            Double otherAvgAccuracyRate = openTestModuleResultService.findAvgAccuracyRate(key, req.getSubject(), req.getGrade(), req.getVersion());
            //证明我是第一个测试数据的
            if(otherAvgAccuracyRate==null){
                moduleResult.setAvgAccuracyRate(accuracyRate);
            }else{
                //把我的和别人的数据平均一下
                BigDecimal avgAccuracyRate = new BigDecimal((accuracyRate.doubleValue() + otherAvgAccuracyRate) / 2).setScale(2, BigDecimal.ROUND_HALF_UP);
                moduleResult.setAvgAccuracyRate(avgAccuracyRate);
            }
            //测试诊断模板
            OpenTestTemplate template = openTestTemplateService.findTemplate(key, rightNum.toString(), req.getSubject(), req.getGrade(), req.getVersion());
            if (template != null) {
                moduleResult.setSituation(template.getSituation());
                moduleResult.setAnswerSituation(template.getAnswerSituation());
                moduleResult.setSuggestion(template.getSuggestion());
                if ("掌握良好".equals(template.getSituation())) {
                    if (zwlh == "") {
                        zwlh += key;
                    } else {
                        zwlh += "、" + key;
                    }
                } else if ("部分掌握".equals(template.getSituation())) {
                    if (bfzw == "") {
                        bfzw += key;
                    } else {
                        bfzw += "、" + key;
                    }
                } else if ("未能掌握".equals(template.getSituation())) {
                    if (wnzw == "") {
                        wnzw += key;
                    } else {
                        wnzw += "、" + key;
                    }
                }
            }
            openTestModuleResultService.save(moduleResult);
        }
        //根据我们对你的观察，发现你已经对【知识模块】、【知识模块】和【知识模块】掌握良好。
        //在【知识模块】和【知识模块】上，测试显示你还有部分知识未掌握。
        //在【知识模块】、【知识模块】和【知识模块】上，你掌握得还不够充分，需要加强学习和练习。
        String explanation = "根据我们对你的观察，发现你";
        if (zwlh != "") {
            explanation+="已经对"+zwlh+"掌握良好。";
        }
        if (bfzw != "") {
            explanation+="在"+bfzw+"上，测试显示你还有部分知识未掌握。";
        }
        if (wnzw != "") {
            explanation+="在"+wnzw+"上，你掌握得还不够充分，需要加强学习和练习。";
        }
        //诊断说明
        result.setExplanation(explanation);
        openTestResultService.save(result);
        data.put("resultId", result.getId());
        data.put("accuracyExceed", result.getAccuracyExceed());
        data.put("speedExceed", result.getSpeedExceed());
        return responseEntity.success(data, "成功");
    }

    private ResponseEntity saveUnitTestResult(SaveResultV1Req req, String userId){
        ResponseEntity responseEntity = new ResponseEntity();
        Map<String, Object> data = new HashMap<>(16);
        Date now = new Date();
        OpenTestUser openTestUser = openTestUserService.findByUserId(userId);
        if (openTestUser == null) {
            return responseEntity.failure("不存在该用户，请完善资料");
        }
        //保存结果
        OpenTestResult result = new OpenTestResult();
        //答题拼接结果：题号#S答题情况#S知识点#S题目id#S答案;题目id#S题号#S答题情况#S知识点#S题目id#S答案
        String answerString = "";
        try {
            int second = 0;
            if (req.getDuration() != null) {
                second = req.getDuration();
            }
            result.setTime(second);
            //计算正确率
            //回答
            List<SaveResultV1Req.AnswerReq> answerReqList = req.getAnswerList();
            //正确题目数量
            int rightNum = 0;
            for (SaveResultV1Req.AnswerReq e : answerReqList) {
                int situation = e.getSituation();
                //统计正确的数量
                if (situation == 1) {
                    rightNum++;
                }
                //题号#S答题情况#S知识点#S题目id#S答案;题目id#S题号#S答题情况#S知识点#S题目id#S答案
                answerString += e.getQuestionNo() + "#S" + e.getSituation() + "#S" + e.getModule() + "#S" + e.getQuestionId() + "#S" + e.getAnswer() + ";";
            }
            //正确率
            BigDecimal accuracyRate = new BigDecimal((double) rightNum / answerReqList.size() * 100).setScale(2, BigDecimal.ROUND_HALF_UP);
            result.setAccuracyRate(accuracyRate);
            result.setScore(accuracyRate.setScale(0, BigDecimal.ROUND_HALF_UP).intValue());
        } catch (Exception e) {
            return responseEntity.failure("时间或答案传参错误");
        }
        result.setType(req.getType());
        result.setSubject(req.getSubject());
        result.setGrade(req.getGrade());
        result.setVersion(req.getVersion());
        result.setUnit(req.getUnit());
        result.setAnswer(answerString);
        result.setUserId(userId);
        result.setTestUserId(openTestUser.getId());
        result.setCreateTime(now);
        result.setQuestionVersion(req.getUpdateVersion());
        result.setSemester(req.getSemester());
        openTestResultService.save(result);
        data.put("resultId", result.getId());
        return responseEntity.success(data, "成功");
    }

    @Override
    public ResponseEntity getReport(GetResultReq req) {
        ResponseEntity responseEntity = new ResponseEntity();
        Map<String, Object> data = new HashMap<>();
        List<Map<String, Object>> list = new ArrayList<>();
        //该用户测评结果
        OpenTestResult result = openTestResultService.getById(req.getResultId());
        //知识模块结果
        List<OpenTestModuleResult> moduleResultList = openTestModuleResultService.findByResultId(req.getResultId());
        for (OpenTestModuleResult moduleResult : moduleResultList) {
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("name", moduleResult.getName());
            resultMap.put("myAccuracyRate", moduleResult.getAccuracyRate());
            resultMap.put("allAccuracyRate", moduleResult.getAvgAccuracyRate());
            resultMap.put("situation", moduleResult.getSituation());
            resultMap.put("answerSituation", moduleResult.getAnswerSituation());
            resultMap.put("suggestion", moduleResult.getSuggestion());
            resultMap.put("rightNum", moduleResult.getRightNum());
            resultMap.put("wrongNum", moduleResult.getWrongNum());
            list.add(resultMap);
        }
        //历史答题记录
        List<OpenTestResult> resultList = openTestResultService.findAllResult(result.getUserId(), result.getGrade(), result.getSubject(), result.getVersion(), null, 1);
        List<Map<String, Object>> scoreList = new ArrayList<>();
        resultList.forEach(e -> {
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("score", e.getScore());
            resultMap.put("time", DateHelper.format(e.getCreateTime(), "MM.dd"));
            scoreList.add(resultMap);
        });
        data.put("moduleList", list);
        data.put("scoreList", scoreList);
        data.put("explanation", result.getExplanation());
        return responseEntity.success(data, "成功");
    }

    @Override
    public ResponseEntity getRankingList(GetResultReq req, String userId) {
        ResponseEntity responseEntity = new ResponseEntity();
        Map<String, Object> data = new HashMap<>();
        List<Map<String, Object>> list = new ArrayList<>();
        //该用户测评结果
        OpenTestResult myResult = openTestResultService.getById(req.getResultId());
        OpenTestUser user = openTestUserService.findByUserId(userId);
        Map<String, Object> params = new HashMap<>();
        params.put("grade", myResult.getGrade());
        params.put("subject", myResult.getSubject());
        params.put("version", myResult.getVersion());
        params.put("unit", myResult.getUnit());
        params.put("type", myResult.getType() != null ? myResult.getType() + "" : null);
        //显示50个排名
        Page page = new Page(0, 50);
        List<OpenTestMBDto> resultList = openTestMapper.findRankingResult(page, params);
        //只有我一个人的时候只显示我的排行
        if (resultList.size() > 1) {
            for (OpenTestMBDto result : resultList) {
                Map<String, Object> resultMap = new HashMap<>();
                resultMap.put("rankingNo", result.getRankingNo());
                resultMap.put("name", result.getName());
                resultMap.put("score", result.getScore());
                list.add(resultMap);
            }
        }
        data.put("total", (int) page.getTotal());
        data.put("myRankingNo", openTestResultService.getMyRankingNo(myResult.getScore(), myResult.getCreateTime().toString(), myResult.getGrade(), myResult.getSubject(), myResult.getVersion(), myResult.getUnit(), myResult.getType()));
        data.put("myName", user.getName());
        data.put("myScore", myResult.getScore());
        data.put("list", list);
        return responseEntity.success(data, "成功");
    }

    @Override
    public ResponseEntity getConditionInfo() {
        ResponseEntity responseEntity = new ResponseEntity();
        Config config = configService.findConfigByParamCode("open_test_info");
        JSONObject json = JSONObject.parseObject(config.getParamVal());
        /*String key = "/api/xiaoshuTest/getConditionInfo";
        Map<String, Object> data = tokenManager.get(key, Map.class);
        if (data == null) {
            data = new HashMap<>();
            //所有年级
            List<ConditionDto> list = new ArrayList();
            ConditionDto condition1 = new ConditionDto();
            //科目
            List<ConditionDto.Subject> subjectList = new ArrayList<>();
            ConditionDto.Subject subjectChinese = condition1.new Subject();
            subjectChinese.setSubject("语文");
            subjectChinese.setVersionList(new ArrayList<>());
            subjectList.add(subjectChinese);

            ConditionDto.Subject subjectMath = condition1.new Subject();
            subjectMath.setSubject("数学");
            List<ConditionDto.Subject.Version> versionMathList = new ArrayList<>();
            ConditionDto.Subject.Version versionMath1 = subjectMath.new Version();
            versionMath1.setVersion("人教版");
            ConditionDto.Subject.Version versionMath2 = subjectMath.new Version();
            versionMath2.setVersion("北师大版");
            subjectMath.setVersionList(versionMathList);
            subjectList.add(subjectMath);

            ConditionDto.Subject subjectEnglish = condition1.new Subject();
            subjectEnglish.setSubject("英语");
            List<ConditionDto.Subject.Version> versionEnglishList = new ArrayList<>();
            ConditionDto.Subject.Version versionEnglish1 = subjectMath.new Version();
            versionEnglish1.setVersion("人教版");
            ConditionDto.Subject.Version versionEnglish2 = subjectMath.new Version();
            versionEnglish2.setVersion("教科版");
            ConditionDto.Subject.Version versionEnglish3 = subjectMath.new Version();
            versionEnglish3.setVersion("沪教版");
            subjectEnglish.setVersionList(versionEnglishList);
            subjectList.add(subjectEnglish);

            //此种不包含英语
            List<ConditionDto.Subject> subjectList1 = new ArrayList<>();
            subjectList1.addAll(subjectList);
            subjectList1.remove(2);

            condition1.setGrade("一年级");
            condition1.setSubjectList(subjectList1);
            list.add(condition1);
            ConditionDto condition2 = new ConditionDto();
            condition2.setGrade("二年级");
            condition2.setSubjectList(subjectList1);
            list.add(condition2);
            ConditionDto condition3 = new ConditionDto();
            condition3.setGrade("三年级");
            condition3.setSubjectList(subjectList);
            list.add(condition3);
            ConditionDto condition4 = new ConditionDto();
            condition4.setGrade("四年级");
            condition4.setSubjectList(subjectList);
            list.add(condition4);
            ConditionDto condition5 = new ConditionDto();
            condition5.setGrade("五年级");
            condition5.setSubjectList(subjectList);
            list.add(condition5);

            data.put("list", list);
            tokenManager.set("/api/xiaoshuTest/getConditionInfo", data);
        }*/
        return responseEntity.success(json, "成功");
    }

    @Override
    public ResponseEntity getConditionInfoV1() {
        return recordQuestionService.getConditionInfo(false, 0);
        /*ResponseEntity responseEntity = new ResponseEntity();
        JSONObject data = tokenManager.get("/api/xiaoshuTest/getConditionInfo", JSONObject.class);
        if (data != null) {
            return responseEntity.success(data, "成功");
        }
        Config config = configService.findConfigByParamCode("open_test_info_v1");
        data = JSONObject.parseObject(config.getParamVal());
        //获取单元相关
        ResponseEntity responseEntity1 = recordQuestionService.getConditionInfo(false);
        Map<String, Object> map = (Map) responseEntity1.getData();
        List<Condition1Dto> dtoList = (List<Condition1Dto>) map.get("list");
        data.getJSONArray("list").getJSONObject(0).replace("gradeList", dtoList);
        config.setParamVal(data.toString());
        configService.save(config);
        tokenManager.set("/api/xiaoshuTest/getConditionInfo", data);
        return responseEntity.success(data, "成功");*/
    }

    @Override
    public ResponseEntity setConditionInfo(String value) {
        ResponseEntity responseEntity = new ResponseEntity();
        /*Map<String, Object> data = new HashMap<>();
        data.put("list", req);
        tokenManager.set("/api/xiaoshuTest/getConditionInfo", data);*/
        Config config = configService.findConfigByParamCode("open_test_info_v1");
        if (config == null) {
            config = new Config();
            config.setParamCode("open_test_info_v1");
            config.setParamDesc("小塾测评小程序筛选条件");
        }
        config.setParamVal(value);
        configService.save(config);
        return responseEntity.success("成功");
    }
    /**
     * 清除结果
     *
     * @return
     */
    @Override
    public ResponseEntity deleteResult(String resultId) {
        ResponseEntity responseEntity = new ResponseEntity();
        OpenTestResult result = openTestResultService.getById(resultId);
        if (result != null) {
            //设为失效
            result.setIsDelete(1);
            openTestResultService.save(result);
        }
        List<OpenTestModuleResult> moduleResultList = openTestModuleResultService.findByResultId(resultId);
        if (moduleResultList != null && moduleResultList.size() > 0) {
            moduleResultList.forEach(e -> e.setIsDelete(1));
            openTestModuleResultService.save(moduleResultList);
        }
        return responseEntity.success("成功");
    }

}