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.report.model.ReportSubjectRange;
import cn.com.qmth.stmms.biz.report.service.ReportSubjectRangeService;
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.RangeCounter;
import cn.com.qmth.stmms.biz.utils.SpringContextHolder;
import net.sf.json.JSONObject;

public class SubjectObjectiveRangeModule implements Module {

    private Map<String, RangeCounter> counters;

    private ReportContext context;

    public SubjectObjectiveRangeModule(ReportContext context) {
        this.counters = new HashMap<String, RangeCounter>();
        this.context = context;
    }

    @Override
    public void process(ExamStudent student) {
        if (student.isUpload() && !student.isAbsent() && !student.isBreach() && student.getSubject() != null) {
            findCounter(getKey(student)).process(student.getObjectiveScore());
        }
    }

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

    @Override
    public void save() {
        ReportSubjectRangeService service = SpringContextHolder.getBean(ReportSubjectRangeService.class);
        for (String subjectCode : this.counters.keySet()) {
            RangeCounter counter = counters.get(subjectCode);
            ReportSubjectRange subjectRange = new ReportSubjectRange();
            subjectRange.setExamId(this.context.getExamId());
            subjectRange.setSubjectCode(subjectCode);
            subjectRange.setSubjectName(context.getSubject(subjectCode).getName());
            subjectRange.setObjectiveScore(context.getSubject(subjectCode).getObjectiveScore());
            subjectRange.setRealityCount(counter.totalCount);
            JSONObject scoreRange = new JSONObject();
            for (int i = 0; i < subjectRange.getObjectiveScore() + 1; i++) {
                scoreRange.accumulate(String.valueOf(i), counter.countGeAndLt((double) i, (double) (i + 1)));
            }
            subjectRange.setObjectiveScoreRange(scoreRange.toString());
            service.save(subjectRange);
        }

    }

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

}
