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

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

import org.apache.commons.lang.StringUtils;

import cn.com.qmth.stmms.biz.exam.model.Exam;
import cn.com.qmth.stmms.biz.exam.model.ExamQuestion;
import cn.com.qmth.stmms.biz.exam.model.ExamStudent;
import cn.com.qmth.stmms.biz.exam.model.ExamSubject;
import cn.com.qmth.stmms.biz.report.model.SasConfigItem;
import cn.com.qmth.stmms.biz.report.service.ReportSubjectTeacherClassService;
import cn.com.qmth.stmms.biz.report.service.ReportSubjectTeacherService;
import cn.com.qmth.stmms.biz.report.utils.module.SubjectClassGroupModule;
import cn.com.qmth.stmms.biz.report.utils.module.SubjectClassModule;
import cn.com.qmth.stmms.biz.report.utils.module.SubjectClassQuestionLevelModule;
import cn.com.qmth.stmms.biz.report.utils.module.SubjectClassQuestionModule;
import cn.com.qmth.stmms.biz.report.utils.module.SubjectClassRangeModule;
import cn.com.qmth.stmms.biz.report.utils.module.SubjectCollegeModule;
import cn.com.qmth.stmms.biz.report.utils.module.SubjectGroupModule;
import cn.com.qmth.stmms.biz.report.utils.module.SubjectModule;
import cn.com.qmth.stmms.biz.report.utils.module.SubjectQuestionLevelModule;
import cn.com.qmth.stmms.biz.report.utils.module.SubjectQuestionModule;
import cn.com.qmth.stmms.biz.report.utils.module.SubjectQuestionOptionModule;
import cn.com.qmth.stmms.biz.report.utils.module.SubjectRangeModule;
import cn.com.qmth.stmms.biz.report.utils.module.SubjectTeacherClassModule;
import cn.com.qmth.stmms.biz.report.utils.module.SubjectTeacherModule;
import cn.com.qmth.stmms.biz.report.utils.unit.LevelRange;
import cn.com.qmth.stmms.biz.utils.SpringContextHolder;

public class ReportContext {

    private Exam exam;

    private List<Module> modules;

    private Map<String, ExamSubject> subjectMap;

    private Map<String, ExamQuestion> questionMap;

    private Map<String, ExamQuestion> groupMap;

    private SasConfigItem sasConfigItem;

    public ReportContext(Exam exam) {
        this.exam = exam;
        this.modules = new LinkedList<Module>();
        this.subjectMap = new HashMap<String, ExamSubject>();
        this.questionMap = new HashMap<String, ExamQuestion>();
        this.groupMap = new HashMap<String, ExamQuestion>();
        // 以下modules创建有顺序
        this.sasConfigItem = SpringContextHolder.getBean(SasConfigItem.class);
        this.modules.add(new SubjectModule(this));
        this.modules.add(new SubjectClassModule(this));
        this.modules.add(new SubjectRangeModule(this));
        this.modules.add(new SubjectClassRangeModule(this));

        this.modules.add(new SubjectCollegeModule(this));
        this.modules.add(new SubjectTeacherModule(this));
        this.modules.add(new SubjectTeacherClassModule(this));

        this.modules.add(new SubjectGroupModule(this));
        this.modules.add(new SubjectClassGroupModule(this));

        SubjectQuestionModule qm = new SubjectQuestionModule(this);
        this.modules.add(qm);
        this.modules.add(new SubjectQuestionLevelModule(this, qm));

        SubjectClassQuestionModule cqm = new SubjectClassQuestionModule(this);
        this.modules.add(cqm);
        this.modules.add(new SubjectClassQuestionLevelModule(this, cqm));

        this.modules.add(new SubjectQuestionOptionModule(this));

    }

    public void process(ExamStudent student) {
        for (Module module : modules) {
            putMap(student);
            module.process(student);
        }
    }

    private void putMap(ExamStudent student) {
        subjectMap.put(student.getSubjectCode(), student.getSubject());
        for (ExamQuestion question : student.getObjectiveQuestionList()) {
            String key = getQuestionKey(question);
            if (questionMap.get(key) == null) {
                questionMap.put(key, question);
            }
            String groupKey = getGroupKey(question);
            if (groupMap.get(groupKey) == null) {
                groupMap.put(groupKey, question);
            }
        }
        for (ExamQuestion question : student.getSubjectiveQuestionList()) {
            String questionKey = getQuestionKey(question);
            if (questionMap.get(questionKey) == null) {
                questionMap.put(questionKey, question);
            }
            String groupKey = getGroupKey(question);
            if (groupMap.get(groupKey) == null) {
                groupMap.put(groupKey, question);
            }
        }
    }

    private String getQuestionKey(ExamQuestion question) {
        return question.getSubjectCode() + "\t" + question.isObjective() + "\t"
                + StringUtils.trimToEmpty(question.getPaperType()) + "\t" + question.getMainNumber() + "\t"
                + question.getSubNumber();
    }

    private String getGroupKey(ExamQuestion question) {
        return question.getSubjectCode() + "\t" + question.isObjective() + "\t"
                + StringUtils.trimToEmpty(question.getPaperType()) + "\t" + question.getMainNumber();
    }

    public void save() {
        for (Module module : modules) {
            module.save();
        }
        ReportSubjectTeacherService teacherService = SpringContextHolder.getBean(ReportSubjectTeacherService.class);
        teacherService.updateRelativeAvgScore(this.getExamId());
        ReportSubjectTeacherClassService teacherClassService = SpringContextHolder
                .getBean(ReportSubjectTeacherClassService.class);
        teacherClassService.updateRelativeAvgScore(this.getExamId());
    }

    public Double getPassScore() {
        if (exam.getPassScore() != null) {
            return exam.getPassScore();
        }
        return sasConfigItem.getPassScore();
    }

    public Double getExcellentScore() {
        if (exam.getExcellentScore() != null) {
            return exam.getExcellentScore();
        }
        return sasConfigItem.getExcellentScore();
    }

    public double getRangeInterval() {
        return 1;
    }

    public Integer getExamId() {
        return exam.getId();
    }

    public ExamSubject getSubject(String subjectCode) {
        return subjectMap.get(subjectCode);
    }

    public ExamQuestion getExamQuestion(String key) {
        return questionMap.get(key);
    }

    public ExamQuestion getGroup(String key) {
        return groupMap.get(key);
    }

    public SasConfigItem getSasConfigItem() {
        sasConfigItem = SasConfigItem.parse(sasConfigItem, exam.getSasConfig());
        return sasConfigItem;
    }

    public LevelRange[] getDifficulityLevelConfig() {
        LevelRange[] levels = new LevelRange[3];
        levels[0] = new LevelRange(null, null, sasConfigItem.getDifficultyHighValue(), null);
        levels[1] = new LevelRange(null, sasConfigItem.getDifficultyHighValue(), null,
                sasConfigItem.getDifficultyMiddleValue());
        levels[2] = new LevelRange(sasConfigItem.getDifficultyLowValue(), null, null, null);
        return levels;
    }

    public LevelRange[] getDiscriminationLevelConfig() {
        LevelRange[] levels = new LevelRange[4];
        levels[0] = new LevelRange(null, sasConfigItem.getDiscriminationExcellentValue(), null, null);
        levels[1] = new LevelRange(null, sasConfigItem.getDiscriminationGoodValue(),
                sasConfigItem.getDiscriminationExcellentValue(), null);
        levels[2] = new LevelRange(null, sasConfigItem.getDiscriminationBadValue(),
                sasConfigItem.getDiscriminationGoodValue(), null);
        levels[3] = new LevelRange(null, null, sasConfigItem.getDiscriminationBadValue(), null);
        return levels;
    }

    public Double getHighValueConfig() {
        return sasConfigItem.getHighValue();
    }

    public Double getLowValueConfig() {
        return sasConfigItem.getHighValue();
    }
}
