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

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

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.ReportSubjectGroup;
import cn.com.qmth.stmms.biz.report.service.ReportSubjectGroupService;
import cn.com.qmth.stmms.biz.report.utils.Module;
import cn.com.qmth.stmms.biz.report.utils.QuestionGroup;
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;

public class SubjectGroupModule implements Module {

    private Map<String, BaseCalculatorUnit> units;

    private ReportContext context;

    public SubjectGroupModule(ReportContext context) {
        this.units = 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.getScoreList(true), student.getObjectiveQuestionList(), student.getSubjectCode(),
                    totalScore, true);
            // 遍历主观题
            process(student.getScoreList(false), student.getSubjectiveQuestionList(), student.getSubjectCode(),
                    totalScore, false);
        }
    }

    private void process(List<ScoreItem> scoreList, List<ExamQuestion> questionList, String subjectCode,
            double totalScore, boolean objective) {
        if (scoreList == null || questionList == null) {
            return;
        }
        Map<Integer, QuestionGroup> map = new HashMap<Integer, QuestionGroup>();
        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;
            QuestionGroup group = map.get(question.getMainNumber());
            if (group == null) {
                group = new QuestionGroup(question.getMainNumber());
                map.put(question.getMainNumber(), group);
            }
            group.incrTotalScore(item != null ? item.getScore() : 0);
            group.incrFullScore(question.getTotalScore());
        }
        for (Entry<Integer, QuestionGroup> entry : map.entrySet()) {
            QuestionGroup group = entry.getValue();
            if (group.getFullScore() == 0) {
                continue;
            }
            findUnit(subjectCode + "\t" + objective + "\t" + entry.getKey()).process(group.getTotalScore(),
                    group.getFullScore(), totalScore);
        }
    }

    public void save() {
        ReportSubjectGroupService service = SpringContextHolder.getBean(ReportSubjectGroupService.class);
        for (String key : this.units.keySet()) {
            String s[] = key.split("\t");
            if (s.length > 2) {
                String subjectCode = s[0];
                Boolean objective = Boolean.parseBoolean(s[1]);
                Integer mainNumber = Integer.parseInt(s[2]);
                BaseCalculatorUnit unit = units.get(key);
                ReportSubjectGroup reportSubjectGroup = new ReportSubjectGroup();
                reportSubjectGroup.setExamId(this.context.getExamId());
                reportSubjectGroup.setSubjectCode(subjectCode);
                reportSubjectGroup.setSubjectName(context.getSubject(subjectCode).getName());
                reportSubjectGroup.setGroupName(context.getGroup(key).getMainTitle());
                reportSubjectGroup.setGroupNumber(mainNumber);
                reportSubjectGroup.setMaxScore(unit.maxScore);
                reportSubjectGroup.setMinScore(unit.minScore);
                reportSubjectGroup.setAvgScore(unit.avgScore);
                reportSubjectGroup.setTotalScore(unit.fullScore);
                reportSubjectGroup.setStdev(unit.stdev);
                reportSubjectGroup.setCoefficient(unit.coefficient);
                reportSubjectGroup.setScoreRate(unit.difficulty);
                reportSubjectGroup.setZeroCount(unit.zeroCount);
                reportSubjectGroup.setFullCount(unit.fullCount);
                reportSubjectGroup.setObjective(objective);
                service.save(reportSubjectGroup);

            }
        }
    }

    private BaseCalculatorUnit findUnit(String key) {
        BaseCalculatorUnit unit = units.get(key);
        if (unit == null) {
            unit = new BaseCalculatorUnit();
            units.put(key, unit);
        }
        return unit;
    }

}
