package cn.com.qmth.examcloud.core.questions.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;
import org.bson.types.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import cn.com.qmth.examcloud.api.commons.security.bean.User;
import cn.com.qmth.examcloud.api.commons.security.bean.UserDataRule;
import cn.com.qmth.examcloud.commons.exception.StatusException;
import cn.com.qmth.examcloud.core.questions.base.CommonUtils;
import cn.com.qmth.examcloud.core.questions.base.Model;
import cn.com.qmth.examcloud.core.questions.base.enums.PaperType;
import cn.com.qmth.examcloud.core.questions.base.question.enums.QuesStructType;
import cn.com.qmth.examcloud.core.questions.base.word.DocxProcessUtil;
import cn.com.qmth.examcloud.core.questions.dao.PaperDetailUnitRepo;
import cn.com.qmth.examcloud.core.questions.dao.PaperRepo;
import cn.com.qmth.examcloud.core.questions.dao.QuesRepo;
import cn.com.qmth.examcloud.core.questions.dao.QuestionAudioRepo;
import cn.com.qmth.examcloud.core.questions.dao.entity.Paper;
import cn.com.qmth.examcloud.core.questions.dao.entity.PaperDetailUnit;
import cn.com.qmth.examcloud.core.questions.dao.entity.QuesOption;
import cn.com.qmth.examcloud.core.questions.dao.entity.Question;
import cn.com.qmth.examcloud.core.questions.dao.entity.QuestionAudio;
import cn.com.qmth.examcloud.core.questions.dao.entity.QuestionSearchCondition;
import cn.com.qmth.examcloud.core.questions.service.PaperService;
import cn.com.qmth.examcloud.core.questions.service.QuesService;
import cn.com.qmth.examcloud.core.questions.service.QuestionAudioService;
import cn.com.qmth.examcloud.core.questions.service.bean.QuestionAnswerBean;
import cn.com.qmth.examcloud.core.questions.service.bean.QuestionAnswerConvert;

/**
 * @author chenken
 * @date 2017年9月12日 上午11:04:23
 * @company QMTH
 * @description QuesServiceImpl.java
 */
@Service("quesService")
public class QuesServiceImpl implements QuesService {

    private static final Logger log = LoggerFactory.getLogger(QuesServiceImpl.class);

    @Autowired
    private QuesRepo quesRepo;

    @Autowired
    private QuestionAudioService questionAudioService;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private QuestionAudioRepo questionAudioRepo;

//    @Autowired
//    private QuesPkgPathRepo quesPkgPathRepo;

    @Autowired
    private PaperDetailUnitRepo unitRepo;

    @Autowired
    private PaperRepo paperRepo;

    @Autowired
    private PaperService paperService;

//    private static WordprocessingMLPackage wordMLPackage = null;

//    static {
//        try {
//            wordMLPackage = WordprocessingMLPackage.createPackage();
//        } catch (InvalidFormatException e) {
//            log.error(e.getMessage(), e);
//        }
//    }

    /**
     * 套题子题按序号自动生成ID
     *
     * @param question
     */
    private void updateSubId(Question question) {
        if (question.getSubQuestions() != null) {
            int index = 0;
            for (Question sub : question.getSubQuestions()) {
                index++;
                sub.setId(String.valueOf(index));
            }
        }
    }

    /**
     * 更新已存在的试题信息
     *
     * @param previous
     * @param update
     */
    /*
     * private void updateMainInfo(Question previous, Question update) { String
     * now = CommonUtils.getCurDateTime(); if (update.getScore() != null) {
     * previous.setScore(update.getScore()); }
     * previous.setQuesAnswer(update.getQuesAnswer());
     * previous.setQuesAnswerAnalysis(update.getQuesAnswerAnalysis());
     * previous.setQuesBody(update.getQuesBody()); if (update.getQuesOptions()
     * != null && update.getQuesOptions().size() > 0) { List<QuesOption>
     * quesOptions = update.getQuesOptions(); List<QuesOption> saveQuesOptions =
     * previous.getQuesOptions(); if (saveQuesOptions.size() !=
     * quesOptions.size()) { previous.setQuesOptions(quesOptions); } else { for
     * (int i = 0; i < quesOptions.size(); i++) {
     * saveQuesOptions.get(i).setOptionBody(quesOptions.get(i).getOptionBody());
     * // 设置正确答案(chenken-2017.4.24)
     * saveQuesOptions.get(i).setIsCorrect(quesOptions.get(i).getIsCorrect()); }
     * } } if (update.getQuesParams() != null) { if (previous.getQuesParams() ==
     * null) { previous.setQuesParams(new HashMap<>()); } for (String key :
     * update.getQuesParams().keySet()) { previous.getQuesParams().put(key,
     * update.getQuesParams().get(key)); } } if (previous.getCreateTime() ==
     * null) { previous.setCreateTime(now); } if (update.getSubQuestions() !=
     * null) { if (previous.getSubQuestions() == null) {
     * previous.setSubQuestions(new ArrayList<>()); } int previousSize =
     * previous.getSubQuestions().size(); int updateSize =
     * update.getSubQuestions().size(); for (int i = 0; i < updateSize; i++) {
     * if (previousSize <= i) {
     * previous.getSubQuestions().add(update.getSubQuestions().get(i)); } else {
     * updateMainInfo(previous.getSubQuestions().get(i),
     * update.getSubQuestions().get(i)); } } } previous.setUpdateTime(now);
     * updateSubId(previous); }
     */

    /**
     * 保存试题，用于页面新增和更新 导入时不能调用该方法，里面有更新Word的代码
     *
     * @param question
     */
    public Question saveQues(Question question) {
    	if(question.getQuesOptions()!=null&&question.getQuesOptions().size()>26) {
    		throw new StatusException("选项数量不能超过26");
    	}
        if (question.getDifficultyDegree() > 0 && question.getDifficultyDegree() < 0.4) {
            question.setDifficulty("难");
        } else if (question.getDifficultyDegree() > 0.3 && question.getDifficultyDegree() < 0.8) {
            question.setDifficulty("中");
        } else {
            question.setDifficulty("易");
        }
        String now = CommonUtils.getCurDateTime();
        if (StringUtils.isNotEmpty(question.getId())) {
            question.setCreateTime(now);
            question.setUpdateTime(now);
        } else {
            question.setUpdateTime(now);
        }
        // 跟新音频文件，以及音频文件排序
        if (question.getHasAudio() != null && question.getHasAudio()) {
            questionAudioService.deleteAudioNotInQuestion(question);
            // 给音频重新排序
            questionAudioService.sortAudio(question);
            // 如果根据questionId查询不出音频了，将hasAudio设置为false
            List<QuestionAudio> questionAudios = questionAudioRepo.findByQuestionId(question.getId());
            if (questionAudios.size() == 0) {
                question.setHasAudio(false);
            }
        }
        setSelectQuestionAnswer(question, "");
        updateSubId(question);
//        updateQuesWord(question);
        // 更新QuesBody，把 下划线 转成 ##
        updateQuesBody(question);
//        //多选题答案逗号分隔
//        formatSelectQuestionAnswer(question);
        return quesRepo.save(question);
    }
   
//    private void formatSelectQuestionAnswer(Question question) {
//        if(question.getQuestionType() == QuesStructType.MULTIPLE_ANSWER_QUESTION) {
//            if(StringUtils.isNotBlank(question.getQuesAnswer())&&question.getQuesAnswer().indexOf(",")==-1) {
//                String[] sarr=new String[question.getQuesAnswer().length()];
//                for(int i=0;i<sarr.length;i++) {
//                    sarr[i]=String.valueOf(question.getQuesAnswer().charAt(i));
//                }
//                question.setQuesAnswer(StringUtils.join(sarr, ","));
//            }
//        }
//        
//    }

    private void updateQuesBody(Question question) {
        String newQuesBody = question.getQuesBody().replaceAll("______", "###");
        question.setQuesBody(newQuesBody);
    }

    /**
     * 批量保存试题
     *
     * @param list
     */
    public void saveQuesList(List<Question> list) {
        if (list != null) {
            for (Question question : list) {
                saveQues(question);
            }
        }
    }

    /**
     * 查询所有试题
     *
     * @param searchCondition
     * @param curPage
     * @param pageSize
     * @param refIds
     * @param userId
     * @return
     */
    public Page<Question> findAll(QuestionSearchCondition searchCondition, int curPage, int pageSize,UserDataRule ud) {
    	if (ud.assertEmptyQueryResult()) {
			return Page.empty();
		}
    	formatQuesCondition(searchCondition);

        Query query = new Query();
        query.addCriteria(Criteria.where("orgId").is(searchCondition.getOrgId()));
        query.addCriteria(Criteria.where("course.enable").is("true"));
        if (ud.assertNeedQueryRefIds()) {
            query.addCriteria(Criteria.where("course.id").in(ud.stringRefIds()));
        }
        if (StringUtils.isNotBlank(searchCondition.getCourseNo())) {
            query.addCriteria(Criteria.where("course.code").is(searchCondition.getCourseNo()));
        }

        if (StringUtils.isNotBlank(searchCondition.getCourseLevel())) {
            query.addCriteria(Criteria.where("course.level").is(searchCondition.getCourseLevel()));
        }

        if (searchCondition.getQuestionType() != null) {
            query.addCriteria(Criteria.where("questionType").is(searchCondition.getQuestionType()));
        }

        if (searchCondition.getPublicity() != null) {
            query.addCriteria(Criteria.where("publicity").is(searchCondition.getPublicity()));
        }

        if (searchCondition.getCoursePropertyName() != null) {
            query.addCriteria(
                    Criteria.where("quesProperties.coursePropertyName").is(searchCondition.getCoursePropertyName()));
        }

        // 二级属性不为空，那么一级属性也不为空
        if (StringUtils.isNotEmpty(searchCondition.getSecondPropertyId())) {
            query.addCriteria(Criteria.where("quesProperties")
                    .elemMatch(Criteria.where("firstProperty.id").is(searchCondition.getFirstPropertyId())
                            .and("secondProperty.id").is(searchCondition.getSecondPropertyId())));
        } else {
            if (searchCondition.getFirstPropertyId() != null) {
                query.addCriteria(Criteria.where("quesProperties")
                        .elemMatch(Criteria.where("firstProperty.id").is(searchCondition.getFirstPropertyId())));
            }
        }

        long count = this.mongoTemplate.count(query, Question.class);
        query.limit(pageSize);
        query.skip((curPage - 1L) * pageSize);
        List<Question> questionList = this.mongoTemplate.find(query, Question.class);
        for (Question question : questionList) {
            formatQues(question);
        }

        return new PageImpl<>(questionList, PageRequest.of(curPage - 1, pageSize), count);
    }

    public void formatQuesCondition(QuestionSearchCondition searchCondition) {
        if (StringUtils.isEmpty(searchCondition.getCourseNo())) {
            searchCondition.setCourseNo(null);
        }

        if (StringUtils.isEmpty(searchCondition.getCourseLevel())) {
            searchCondition.setCourseLevel(null);
        }

        if (StringUtils.isEmpty(searchCondition.getCourseMajor())) {
            searchCondition.setCourseMajor(null);
        }

        if (StringUtils.isEmpty(String.valueOf(searchCondition.getPublicity()))) {
            searchCondition.setPublicity(null);
        }

        if (StringUtils.isEmpty(searchCondition.getCoursePropertyName())) {
            searchCondition.setCoursePropertyName(null);
        }

        if (StringUtils.isEmpty(searchCondition.getFirstPropertyId())) {
            searchCondition.setFirstPropertyId(null);
        }

        if (StringUtils.isEmpty(searchCondition.getSecondPropertyId())) {
            searchCondition.setSecondPropertyId(null);
        }

        if (StringUtils.isEmpty(searchCondition.getDifficulty())) {
            searchCondition.setDifficulty(null);
        }
    }

    /**
     * 查询按ID过滤的试题
     *
     * @param idSet
     * @param curPage
     * @param pageSize
     * @return
     */
    public Page<Question> findByIdExclude(Set<String> idSet, String courseNo, QuesStructType quesType, int curPage,
            int pageSize, Long orgId, String quesBody,UserDataRule ud) {
    	if (ud.assertEmptyQueryResult()) {
    		return Page.empty();
    	}
    	
    	Query query = new Query();
        query.addCriteria(Criteria.where("orgId").is(orgId + ""));
        if(ud.assertNeedQueryRefIds()) {
        	query.addCriteria(Criteria.where("course.id").in(ud.stringRefIds()));
        }
        query.addCriteria(Criteria.where("course.enable").is("true"));
        if (quesType != null) {
            query.addCriteria(Criteria.where("questionType").is(quesType));
        }
        query.addCriteria(Criteria.where("course.code").is(courseNo));
        query.addCriteria(Criteria.where("id").nin(idSet));
        // 模糊匹配
        if (StringUtils.isNotBlank(quesBody)) {
            Pattern pattern = Pattern.compile("^.*" + quesBody + ".*$", Pattern.CASE_INSENSITIVE);
            query.addCriteria(Criteria.where("quesBody").regex(pattern));
        }
        long total = this.mongoTemplate.count(query, Question.class);
        query.with(Sort.by(new Order(Direction.DESC, "id")));
        query.limit(pageSize);
        query.skip((curPage - 1L) * pageSize);
        List<Question> questionList = this.mongoTemplate.find(query, Question.class);
        Page<Question> questionPageList = new PageImpl<Question>(questionList, PageRequest.of(curPage - 1, pageSize),
                total);
        for (Question question : questionPageList) {
            formatQues(question);
        }
        return questionPageList;
    }

    /**
     * 按ID获取试题
     *
     * @param id
     * @return
     */
    public Question findById(String id) {
        Question question = Model.of(quesRepo.findById(id));
        formatQues(question);
        return question;
    }

    /**
     * 去除试题中的word
     *
     * @param question
     */
    public void formatQues(Question question) {
        formatQuesUnit(question);
        if (question.getSubQuestions() != null && question.getSubQuestions().size() > 0) {
            question.getSubQuestions().stream().forEach(subQues -> {
                formatQuesUnit(subQues);
            });
        }
    }

    public void formatQuesUnit(Question question) {
        if (question != null) {
            question.setQuesBodyWord(null);
            question.setQuesAnswerWord(null);
            question.setQuesAnswerAnalysisWord(null);
            String newQuesBody = question.getQuesBody().replaceAll("<span>", "").replaceAll("</span>", "")
                    .replaceAll("###", "______");
            question.setQuesBody(newQuesBody);
            if (question.getQuesOptions() != null && question.getQuesOptions().size() > 0) {
                question.getQuesOptions().stream().forEach(quesOption -> {
                    quesOption.setOptionBodyWord(null);
                });
            }
        }
    }

    /**
     * 保存后更新word
     *
     * @param question
     */
//    public void updateQuesWord(Question question) {
//        try {
//            if (wordMLPackage == null) {
//                wordMLPackage = WordprocessingMLPackage.createPackage();
//            } else {
//                DocxProcessUtil.initTmpPackage(wordMLPackage);
//                wordMLPackage.getRelationshipsPart().remove();
//            }
//            updateQuesWordUnit(wordMLPackage, question);
//            List<Question> subQuesList = question.getSubQuestions();
//            if (subQuesList != null && subQuesList.size() > 0) {
//                for (Question subQues : subQuesList) {
//                    updateQuesWordUnit(wordMLPackage, subQues);
//                }
//            }
//            byte[] pkgByte = DocxProcessUtil.getPkgByte(wordMLPackage);
//            if (question.getQuesPkgPathId() == null) {
//                QuestionPkgPath quesPkgPath = new QuestionPkgPath(pkgByte);
//                QuestionPkgPath returnQuesPkgPath = quesPkgPathRepo.save(quesPkgPath);
//                question.setQuesPkgPathId(returnQuesPkgPath.getId());
//                quesRepo.save(question);
//            } else {
//                QuestionPkgPath quesPkgPath = quesPkgPathRepo.findFirstById(question.getQuesPkgPathId());
//                quesPkgPath.setQuesPkg(pkgByte);
//                quesPkgPathRepo.save(quesPkgPath);
//            }
//            pkgByte = null;
//        } catch (Exception e) {
//            log.error(e.getMessage(), e);
//        }
//    }

//    public void updateQuesWordUnit(WordprocessingMLPackage wordMLPackage, Question question) throws Exception {
//        String quesBody = question.getQuesBody();
//        String quesAnswer = question.getQuesAnswer();
//        if (!StringUtils.isEmpty(quesBody)) {
//            StringBuffer pWordMl = new StringBuffer();
//            question.setQuesBodyWord(reduceImage(quesBody, pWordMl, wordMLPackage));
//        }
//        if (!StringUtils.isEmpty(quesAnswer) && (question.getQuestionType() == QuesStructType.FILL_BLANK_QUESTION
//                || question.getQuestionType() == QuesStructType.TEXT_ANSWER_QUESTION)) {
//            // question.setQuesAnswerWord(DocxProcessUtil.html2Docx(wordMLPackage,
//            // CommonUtils.formatHtml(quesAnswer)));
//            StringBuffer pWordMl = new StringBuffer();
//            question.setQuesAnswerWord(reduceImage(quesAnswer, pWordMl, wordMLPackage));
//        }
//        if (!StringUtils.isEmpty(quesAnswer) && question.getQuestionType() == QuesStructType.BOOL_ANSWER_QUESTION) {
//            quesAnswer = "<p>" + quesAnswer + "</p>";
//            question.setQuesAnswerWord(DocxProcessUtil.html2Docx(wordMLPackage, CommonUtils.formatHtml(quesAnswer)));
//        }
//        if (!StringUtils.isEmpty(quesAnswer) && (question.getQuestionType() == QuesStructType.SINGLE_ANSWER_QUESTION
//                || question.getQuestionType() == QuesStructType.MULTIPLE_ANSWER_QUESTION)) {
//            question.setQuesAnswerWord(makeQuesAnswerWord(quesAnswer));
//        }
//        List<QuesOption> quesOptions = question.getQuesOptions();
//        if (quesOptions != null && quesOptions.size() > 0) {
//            for (QuesOption quesOption : quesOptions) {
//                if (StringUtils.isBlank(quesOption.getOptionBody())) {
//                    quesOption.setOptionBody("<p></p>");
//                }
//                StringBuffer pWordMl = new StringBuffer();
//                // quesOption.setOptionBodyWord(DocxProcessUtil.html2Docx(wordMLPackage,CommonUtils.formatHtml(quesOption.getOptionBody())));
//                quesOption.setOptionBodyWord(reduceImage(quesOption.getOptionBody(), pWordMl, wordMLPackage));
//            }
//        }
//    }

    // 如果图片过大，改变图片大小
//    private String reduceImage(String html, StringBuffer pWordMl, WordprocessingMLPackage wordMLPackage)
//            throws Exception {
//        String bodyString = DocxProcessUtil.html2Docx(wordMLPackage, CommonUtils.formatHtml(html));
//        if (bodyString.indexOf("cx") > -1 || bodyString.indexOf("cy") > -1) {
//            String tmpStr = DocxProcessUtil.BODY_HEADER + bodyString + DocxProcessUtil.BODY_TAIL;
//            Body body = (Body) XmlUtils.unmarshalString(tmpStr, Context.jc, Body.class);
//            List<Object> pList = body.getContent();
//            for (Object op : pList) {
//                P p = (P) op;
//                List<Object> rList = p.getContent();
//                for (Object or : rList) {
//                    if (or instanceof R) {
//                        R r = (R) or;
//                        List<Object> draList = r.getContent();
//                        for (Object odra : draList) {
//                            if (odra instanceof JAXBElement) {
//                                JAXBElement<?> jaxbElement = (JAXBElement<?>) odra;
//                                if (jaxbElement.getValue() instanceof Drawing) {
//                                    Drawing drawing = (Drawing) jaxbElement.getValue();
//                                    List<Object> inList = drawing.getAnchorOrInline();
//                                    for (Object oin : inList) {
//                                        Inline inline = (Inline) oin;
//                                        CTPositiveSize2D extent = inline.getExtent();
//                                        if (extent.getCx() > 6000000) {
//                                            long cx = extent.getCx();
//                                            long cy = extent.getCy();
//                                            Double ncy = (cy * 6000000D) / cx;
//                                            extent.setCx(6000000L);
//                                            extent.setCy(ncy.longValue());
//                                        }
//                                        if (extent.getCy() > 6000000) {
//                                            long cx = extent.getCx();
//                                            long cy = extent.getCy();
//                                            Double ncx = (cx * 6000000D) / cy;
//                                            extent.setCy(6000000L);
//                                            extent.setCx(ncx.longValue());
//                                        }
//                                    }
//                                }
//                            }
//                        }
//                    }
//                }
//            }
//            for (Object pObj : pList) {
//                if (pObj instanceof P) {
//                    pWordMl.append(DocxProcessUtil.formatPWordMl(XmlUtils.marshaltoString(pObj)));
//                }
//            }
//            return pWordMl.toString();
//        }
//        return bodyString;
//    }

//    private String makeQuesAnswerWord(String quesAnswer) {
//        String template = "<w:p xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" w:rsidR=\"00F65544\" w:rsidP=\"00F65544\" w:rsidRDefault=\"001738E2\">"
//                + "<w:r w:rsidR=\"00F65544\">" + "<w:rPr>" + "<w:rFonts w:hint=\"eastAsia\"/>"
//                + "<w:szCs w:val=\"21\"/>" + "</w:rPr>" + "<w:t>quesAnswer</w:t>" + "</w:r>" + "</w:p>";
//        return template.replace("quesAnswer", quesAnswer);
//    }

    /**
     * 获取试题有效文本
     *
     * @param question
     * @return
     */
    public String getExtractText(Question question) {
        StringBuilder quesText = new StringBuilder();
        if (question == null) {
            return quesText.toString();
        }

        if (!StringUtils.isEmpty(question.getQuesBody())) {
            quesText.append(DocxProcessUtil.getTextInHtml(question.getQuesBody()));
        }

        List<QuesOption> quesOptionList = question.getQuesOptions();
        if (quesOptionList != null && quesOptionList.size() > 0) {
            for (QuesOption quesOption : quesOptionList) {
                if (!StringUtils.isEmpty(quesOption.getOptionBody())) {
                    quesText.append(DocxProcessUtil.getTextInHtml(quesOption.getOptionBody()));
                }
            }
        }

        return quesText.toString();
    }

    @Override
    public void setSelectQuestionAnswer(Question question, String optionOrder) {
        if (question.getQuestionType() == QuesStructType.SINGLE_ANSWER_QUESTION
                || question.getQuestionType() == QuesStructType.MULTIPLE_ANSWER_QUESTION) {
            question.setQuesAnswer(getSelectQuestionAnswer(question, optionOrder));
        } else if (question.getQuestionType() == QuesStructType.NESTED_ANSWER_QUESTION) {
            List<Question> subQuestions = question.getSubQuestions();
            int index = 0;
            for (int k = 0; k < subQuestions.size(); k++) {
                Question subQuestion = subQuestions.get(k);
                if (subQuestion.getQuestionType() == QuesStructType.SINGLE_ANSWER_QUESTION
                        || subQuestion.getQuestionType() == QuesStructType.MULTIPLE_ANSWER_QUESTION) {
                    if (StringUtils.isNotEmpty(optionOrder) && optionOrder.contains(";")) {
                        subQuestion.setQuesAnswer(getSelectQuestionAnswer(subQuestion, optionOrder.split(";")[index]));
                    } else {
                        subQuestion.setQuesAnswer(getSelectQuestionAnswer(subQuestion, ""));
                    }
                    index++;
                }
            }
        }
    }

    private String getSelectQuestionAnswer(Question question, String optionOrder) {
        String answer = "";
        List<QuesOption> quesOptions = question.getQuesOptions();
        if (quesOptions == null || quesOptions.size() == 0) {
            return "";
        }
        if (StringUtils.isEmpty(optionOrder)) {
            int j = 0;
            for (QuesOption quesOption : quesOptions) {
                if (quesOption.getIsCorrect() == 1) {
                    answer += CommonUtils.getOptionNum(j);
                }
                j++;
            }
        } else {
            String[] order = optionOrder.split(",");
            for (int i = 0; i < order.length; i++) {
                for (QuesOption quesOption : quesOptions) {
                    if (order[i].equals(quesOption.getNumber()) && quesOption.getIsCorrect() == 1) {
                        answer += CommonUtils.getOptionNum(i);
                        break;
                    }
                }
            }
        }
        //逗号分隔
        if(StringUtils.isNotBlank(answer)) {
        	String[] sarr=new String[answer.length()];
        	for(int i=0;i<sarr.length;i++) {
                sarr[i]=String.valueOf(answer.charAt(i));
            }
        	answer=StringUtils.join(sarr, ",");
        }
        return answer;
    }

    @Override
    public long findQuesCount(QuestionSearchCondition searchCondition) {
        formatQuesCondition(searchCondition);

        Query query = new Query();
        query.addCriteria(Criteria.where("orgId").is(searchCondition.getOrgId()));
        query.addCriteria(Criteria.where("course.enable").is("true"));

        if (StringUtils.isNotBlank(searchCondition.getCourseNo())) {
            query.addCriteria(Criteria.where("course.code").is(searchCondition.getCourseNo()));
        }

        if (searchCondition.getQuestionType() != null) {
            query.addCriteria(Criteria.where("questionType").is(searchCondition.getQuestionType()));
        }

        if (searchCondition.getPublicity() != null) {
            query.addCriteria(Criteria.where("publicity").is(searchCondition.getPublicity()));
        }

        if (searchCondition.getCoursePropertyName() != null) {
            query.addCriteria(
                    Criteria.where("quesProperties.coursePropertyName").is(searchCondition.getCoursePropertyName()));
        }

        if (searchCondition.getDifficulty() != null) {
            query.addCriteria(Criteria.where("difficulty").is(searchCondition.getDifficulty()));
        }

        // 二级属性不为空，那么一级属性也不为空
        if (StringUtils.isNotEmpty(searchCondition.getSecondPropertyId())) {
            query.addCriteria(Criteria.where("quesProperties")
                    .elemMatch(Criteria.where("firstProperty.id").is(searchCondition.getFirstPropertyId())
                            .and("secondProperty.id").is(searchCondition.getSecondPropertyId())));
        } else {
            if (searchCondition.getFirstPropertyId() != null) {
                query.addCriteria(Criteria.where("quesProperties")
                        .elemMatch(Criteria.where("firstProperty.id").is(searchCondition.getFirstPropertyId())));
            }
        }

        long count = 0;
        List<Question> questionList = this.mongoTemplate.find(query, Question.class);
        if (questionList == null || questionList.size() < 1) {
            return count;
        }

        List<String> oIds = new ArrayList<>();
        for (Question unit : questionList) {
            oIds.add(unit.getId());
        }

        List<ObjectId> objectIds = new ArrayList<>();
        for (String id : oIds) {
            objectIds.add(new ObjectId(id));
        }

        Query query2 = new Query();
        query2.addCriteria(Criteria.where("question.$id").in(objectIds));
        query2.addCriteria(Criteria.where("paperType").is(PaperType.IMPORT));
        List<PaperDetailUnit> paperDetailUnits = this.mongoTemplate.find(query2, PaperDetailUnit.class);
        String quesNames = searchCondition.getQuesNames();
        List<String> list = Arrays.asList(quesNames.split(","));// [单选题] 单选
        for (PaperDetailUnit unit : paperDetailUnits) {
            if (list.contains(unit.getPaperDetail().getName())) {
                count++;
            }
        }

        return count;
    }

    @Override
    public void updateProByPapers(List<String> paperList, Double difficultyDegree, Boolean publicity, User user) {
        List<Paper> papers = new ArrayList<>();
        String difficulty = "";
        if (difficultyDegree != null) {
            if (difficultyDegree > 0 && difficultyDegree < 0.4) {
                difficulty = "难";
            } else if (difficultyDegree > 0.3 && difficultyDegree < 0.8) {
                difficulty = "中";
            } else {
                difficulty = "易";
            }
        }
        List<String> quesIds = new ArrayList<>();
        List<Question> subQues = new ArrayList<>();
        for (String id : paperList) {
            Paper paper = Model.of(paperRepo.findById(id));
            if(PaperType.GENERATE.equals(paper.getPaperType())) {
            	paper.setAuditStatus(false);
            }
            List<PaperDetailUnit> paperDetailUnits = unitRepo.findByPaper(paper);
            for (PaperDetailUnit unit : paperDetailUnits) {
                Question question = unit.getQuestion();
                if (question.getSubQuestions() != null && question.getSubQuestions().size() > 0) {
                    List<Question> subQuestions = question.getSubQuestions();
                    for (Question subQuestion : subQuestions) {
                        if (difficultyDegree != null) {
                            subQuestion.setDifficultyDegree(difficultyDegree);
                            subQuestion.setDifficulty(difficulty);
                        }
                        if (publicity != null) {
                            subQuestion.setPublicity(publicity);
                        }
                        question.setSubQuestions(subQuestions);
                    }
                    subQues.add(question);
                }
                quesIds.add(question.getId());
            }
            papers.add(paper);
        }
        quesRepo.saveAll(subQues);
        if (quesIds != null && quesIds.size() > 0) {
            Query query = new Query();
            query.addCriteria(Criteria.where("id").in(quesIds));
            Update update = null;
            if (difficultyDegree != null) {
                update = Update.update("difficultyDegree", difficultyDegree).set("difficulty", difficulty);
            }
            if (publicity != null) {
                if (difficultyDegree != null) {
                    update = update.set("publicity", publicity);
                } else {
                    update = Update.update("publicity", publicity);
                }
            }
            this.mongoTemplate.updateMulti(query, update, Question.class);
        }
        for (Paper paper : papers) {
            paperService.formatPaper(paper, user);
        }
        paperRepo.saveAll(papers);
    }

    @Override
    public void updateProByCourse(String courseCode, Double difficultyDegree, Boolean publicity, String orgId) {
        String difficulty = "";
        if (difficultyDegree > 0 && difficultyDegree < 0.4) {
            difficulty = "难";
        } else if (difficultyDegree > 0.3 && difficultyDegree < 0.8) {
            difficulty = "中";
        } else {
            difficulty = "易";
        }
        Query query = new Query();
        query.addCriteria(Criteria.where("orgId").is(orgId + ""));
        query.addCriteria(Criteria.where("course.enable").is("true"));
        query.addCriteria(Criteria.where("course.code").is(courseCode));
        List<Question> questionList = this.mongoTemplate.find(query, Question.class);
        if (questionList != null && questionList.size() > 0) {
            for (Question question : questionList) {
                question.setDifficultyDegree(difficultyDegree);
                question.setDifficulty(difficulty);
                question.setPublicity(publicity);
                if (question.getSubQuestions() != null && question.getSubQuestions().size() > 0) {
                    for (Question subQues : question.getSubQuestions()) {
                        subQues.setDifficultyDegree(difficultyDegree);
                        subQues.setDifficulty(difficulty);
                        subQues.setPublicity(publicity);
                    }
                }
            }
        }
        quesRepo.saveAll(questionList);
    }

    @Override
    public QuestionAnswerBean findQuestionAnswer(String questionId) {
        Optional<Question> optional = quesRepo.findById(questionId);
        if (!optional.isPresent()) {
            log.error("question is not exist, id = {}", questionId);
            throw new StatusException("500", "当前试题已不存在！");
        }

        Question question = optional.get();
        QuestionAnswerBean bean = new QuestionAnswerBean();
        List<String> answers = new ArrayList<>();

        if (QuesStructType.NESTED_ANSWER_QUESTION == question.getQuestionType()) {
            List<Question> subQuestions = question.getSubQuestions();
            for (Question subQuestion : subQuestions) {
                if (QuesStructType.SINGLE_ANSWER_QUESTION == subQuestion.getQuestionType()
                        || QuesStructType.MULTIPLE_ANSWER_QUESTION == subQuestion.getQuestionType()) {
                    List<String> values = QuestionAnswerConvert
                            .parseQuestionOptionAnswerList(subQuestion.getQuesOptions());
                    // 选择题 - 转换为新答案格式
                    answers.add(StringUtils.join(values, ""));
                } else {
                    List<String> values = QuestionAnswerConvert.parseQuestionAnswerList(subQuestion);
                    answers.add(StringUtils.join(values, ""));
                }
            }
        } else {
            if (QuesStructType.SINGLE_ANSWER_QUESTION == question.getQuestionType()
                    || QuesStructType.MULTIPLE_ANSWER_QUESTION == question.getQuestionType()) {
                List<String> values = QuestionAnswerConvert.parseQuestionOptionAnswerList(question.getQuesOptions());
                // 选择题 - 转换为新答案格式
                answers.add(StringUtils.join(values, ""));
            } else {
                List<String> values = QuestionAnswerConvert.parseQuestionAnswerList(question);
                answers.add(StringUtils.join(values, ""));
            }
        }

        bean.setRightAnswers(answers);
        bean.setQuestionId(question.getId());
        return bean;
    }

}