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

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

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.ReportSubject;
import cn.com.qmth.stmms.biz.report.service.ReportSubjectService;
import cn.com.qmth.stmms.biz.report.utils.Module;
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.report.utils.unit.BaseCounter;
import cn.com.qmth.stmms.biz.utils.SpringContextHolder;

public class SubjectModule implements Module {

    protected Map<String, BaseCalculatorUnit> units;

    protected Map<String, BaseCounter> counters;

    protected ReportContext context;

    public SubjectModule(ReportContext context) {
        this.units = new HashMap<String, BaseCalculatorUnit>();
        this.counters = new HashMap<String, BaseCounter>();
        this.context = context;
    }

    public void process(ExamStudent student) {
        ExamSubject subject = student.getSubject();
        if (subject != null) {
            String key = getKey(student);
            if (student.isUpload() && !student.isAbsent() && !student.isBreach()) {
                findUnit(key).process(student.getTotalScore(), subject.getTotalScore(), student.getTotalScore());
            }
            findCounter(key).process(student);
        }
    }

    public String getKey(ExamStudent student) {
        return student.getSubjectCode();
    }

    public void save() {
        ReportSubjectService service = SpringContextHolder.getBean(ReportSubjectService.class);
        for (String subjectCode : this.counters.keySet()) {
            BaseCounter counter = counters.get(subjectCode);
            BaseCalculatorUnit unit = units.get(subjectCode);
            ReportSubject subject = new ReportSubject();
            subject.setExamId(this.context.getExamId());
            subject.setSubjectCode(subjectCode);
            subject.setSubjectName(context.getSubject(subjectCode).getName());
            subject.setTotalCount(counter.totalCount);
            subject.setAbsentCount(counter.absentCount);
            subject.setBreachCount(counter.breachCount);
            subject.setRealityCount(counter.realityCount);
            if (unit != null) {
                subject.setMaxScore(unit.maxScore);
                subject.setMinScore(unit.minScore);
                subject.setAvgScore(unit.avgScore);
                subject.setPassCount(unit.passCount);
                subject.setPassRate(unit.passRate);
            } else {
                subject.setMaxScore(0d);
                subject.setMinScore(0d);
                subject.setAvgScore(0d);
                subject.setPassCount(0);
                subject.setPassRate(0d);
            }
            service.save(subject);
        }
    }

    protected BaseCalculatorUnit findUnit(String key) {
        BaseCalculatorUnit unit = units.get(key);
        if (unit == null) {
            unit = new BaseCalculatorUnit();
            unit.passScore = context.getPassScore();
            unit.excellentScore = context.getExcellentScore();
            units.put(key, unit);
        }
        return unit;
    }

    private BaseCounter findCounter(String key) {
        BaseCounter counter = counters.get(key);
        if (counter == null) {
            counter = new BaseCounter();
            counters.put(key, counter);
        }
        return counter;
    }

}
