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.service.ReportSubjectTeacherClassService;
import cn.com.qmth.stmms.biz.report.service.ReportSubjectTeacherService;
import cn.com.qmth.stmms.biz.report.utils.module.SubjectClassModule;
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.SubjectQuestionModule;
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.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;

    public ReportContext(Exam exam) {
        this.exam = exam;
        this.modules = new LinkedList<Module>();

        this.modules.add(new SubjectRangeModule(this));
        this.modules.add(new SubjectModule(this));
        this.modules.add(new SubjectClassModule(this));
        this.modules.add(new SubjectCollegeModule(this));
        this.modules.add(new SubjectTeacherModule(this));
        this.modules.add(new SubjectTeacherClassModule(this));
        this.modules.add(new SubjectQuestionModule(this));
        this.modules.add(new SubjectGroupModule(this));

        this.subjectMap = new HashMap<String, ExamSubject>();
        this.questionMap = new HashMap<String, ExamQuestion>();
        this.groupMap = new HashMap<String, ExamQuestion>();
    }

    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" + 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() {
        return exam.getPassScore();
    }

    public Double getExcellentScore() {
        return exam.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);
    }
}
