package cn.com.qmth.stmms.biz.report.utils.module;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import cn.com.qmth.stmms.biz.exam.model.ExamQuestion;
import cn.com.qmth.stmms.biz.exam.model.ExamStudent;
import cn.com.qmth.stmms.biz.report.model.ReportSubjectQuestion;
import cn.com.qmth.stmms.biz.report.service.ReportSubjectQuestionService;
import cn.com.qmth.stmms.biz.report.utils.Module;
import cn.com.qmth.stmms.biz.report.utils.QuestionCalculatorProvider;
import cn.com.qmth.stmms.biz.report.utils.ReportContext;
import cn.com.qmth.stmms.biz.report.utils.unit.BaseCalculatorUnit;
import cn.com.qmth.stmms.biz.utils.ScoreItem;
import cn.com.qmth.stmms.biz.utils.SpringContextHolder;

/**
 * 按科目统计全样本小题指标
 * 
 * @author luoshi
 *
 */
public class SubjectQuestionModule implements Module, QuestionCalculatorProvider {

    protected Map<String, BaseCalculatorUnit> calculators;

    protected ReportContext context;

    public static final int UN_SELECTIVE_SCORE = -1;

    public SubjectQuestionModule(ReportContext context) {
        this.calculators = new HashMap<String, BaseCalculatorUnit>();
        this.context = context;
    }

    public void process(ExamStudent student) {
        if (student.isUpload() && !student.isAbsent() && !student.isBreach() && student.getSubject() != null) {
            double totalScore = student.getTotalScore();
            // 遍历客观题
            process(student, student.getScoreList(true), student.getObjectiveQuestionList(), totalScore);
            // 遍历主观题
            process(student, student.getScoreList(false), student.getSubjectiveQuestionList(), totalScore);
        }
    }

    private void process(ExamStudent student, List<ScoreItem> scoreList, List<ExamQuestion> questionList,
            double totalScore) {
        if (scoreList == null || questionList == null) {
            return;
        }
        int scoreCount = scoreList.size();
        for (int i = 0; i < questionList.size(); i++) {
            ExamQuestion question = questionList.get(i);
            if (question.getTotalScore() == null || question.getTotalScore() == 0) {
                continue;
            }
            ScoreItem item = scoreCount > i ? scoreList.get(i) : null;
            double score = item != null && item.getScore() != UN_SELECTIVE_SCORE ? item.getScore() : 0;
            process(student, question, score, totalScore);
        }
    }

    protected void process(ExamStudent student, ExamQuestion question, double score, double totalScore) {
        findCalculator(getKey(question)).process(score, question.getTotalScore(), totalScore);
    }

    protected String getKey(ExamQuestion question, Object... parameter) {
        return question.getSubjectCode() + "\t" + question.isObjective() + "\t"
                + StringUtils.trimToEmpty(question.getPaperType()) + "\t" + question.getMainNumber() + "\t"
                + question.getSubNumber();
    }

    public void save() {
        ReportSubjectQuestionService service = SpringContextHolder.getBean(ReportSubjectQuestionService.class);
        for (String key : this.calculators.keySet()) {
            String s[] = key.split("\t");
            if (s.length > 4) {
                String subjectCode = s[0];
                Boolean objective = Boolean.parseBoolean(s[1]);
                String paperType = StringUtils.trimToNull(s[2]);
                Integer mainNumber = Integer.parseInt(s[3]);
                String subNumber = StringUtils.trimToEmpty(s[4]);
                BaseCalculatorUnit unit = calculators.get(key);
                ReportSubjectQuestion r = new ReportSubjectQuestion();
                r.setExamId(this.context.getExamId());
                r.setSubjectCode(subjectCode);
                r.setSubjectName(context.getSubject(subjectCode).getName());
                r.setObjective(objective);
                r.setQuestionName(context.getExamQuestion(key).getMainTitle());
                r.setMainNumber(mainNumber);
                r.setSubNumber(subNumber);
                r.setTotalScore(unit.fullScore);
                r.setAvgScore(unit.avgScore);
                r.setScoreRate(unit.difficulty);
                r.setStdev(unit.stdev);
                r.setFullScoreRate(unit.fullScoreRate);
                r.setPaperType(paperType);
                r.setCoefficient(unit.coefficient);
                r.setDifficulty(unit.difficulty);
                r.setDiscrimination(unit.discrimination);
                r.setMaxScore(unit.maxScore);
                r.setMinScore(unit.minScore);
                r.setRealityCount(unit.count);
                r.setZeroCount(unit.zeroCount);
                r.setFullCount(unit.fullCount);
                r.setAnswer(context.getExamQuestion(key).getAnswer());
                service.save(r);
            }
        }
    }

    protected BaseCalculatorUnit findCalculator(String key) {
        BaseCalculatorUnit unit = calculators.get(key);
        if (unit == null) {
            unit = new BaseCalculatorUnit();
            calculators.put(key, unit);
        }
        return unit;
    }

    @Override
    public BaseCalculatorUnit getCalculator(ExamQuestion question, Object... parameter) {
        return calculators.get(getKey(question, parameter));
    }

}
