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

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;

import cn.com.qmth.stmms.biz.exam.dao.ExamStudentDao;
import cn.com.qmth.stmms.biz.exam.model.ExamStudent;
import cn.com.qmth.stmms.biz.report.model.ReportSubjectClass;
import cn.com.qmth.stmms.biz.report.service.ReportSubjectClassService;
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;

public class SubjectClassRangeModule implements Module {

    private Map<String, RangeCounter> counters;

    private ReportContext context;

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

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

    public String getKey(ExamStudent student) {
        return student.getSubjectCode() + "\t" + StringUtils.trimToEmpty(student.getClassName());
    }

    public void save() {
        ReportSubjectClassService service = SpringContextHolder.getBean(ReportSubjectClassService.class);
        for (String key : this.counters.keySet()) {
            RangeCounter counter = counters.get(key);
            String s[] = key.split("\t");
            if (s.length > 1) {
                String subjectCode = s[0];
                String className = s[1];
                ReportSubjectClass r = service.findOne(this.context.getExamId(), subjectCode, className);
                ExamStudentDao studentDao = SpringContextHolder.getBean(ExamStudentDao.class);
                JSONObject rangeLevel = new JSONObject();
                double highCount = Math.ceil(context.getHighValueConfig() * r.getRealityCount() * 0.01);
                double lowCount = Math.ceil(context.getLowValueConfig() * r.getRealityCount() * 0.01);
                List<BigDecimal> highScore = studentDao.findHighCountTotalSocreByExamIdAndSubjectCodeAndClass(
                        context.getExamId(), subjectCode, className, (int) highCount);
                List<BigDecimal> lowScore = studentDao.findLowCountTotalSocreByExamIdAndSubjectCodeAndClass(
                        context.getExamId(), subjectCode, className, (int) lowCount);
                rangeLevel.accumulate("highScore", highScore.isEmpty() ? 0 : highScore.get(highScore.size() - 1)
                        .doubleValue());
                rangeLevel.accumulate("lowScore", lowScore.isEmpty() ? 0 : lowScore.get(lowScore.size() - 1)
                        .doubleValue());
                r.setRangeLevel(rangeLevel.toString());

                JSONObject scoreRange = new JSONObject();
                for (int i = 0; i < context.getSubject(subjectCode).getTotalScore() + 1; i++) {
                    scoreRange.accumulate(String.valueOf(i), counter.countGtAndLe((double) (i - 1), (double) i));
                }
                r.setScoreRange(scoreRange.toString());
                service.save(r);
            }
        }

    }

    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;
    }

}
