package cn.com.qmth.stmms.admin.thread;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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.service.ExamQuestionService;
import cn.com.qmth.stmms.biz.exam.service.ExamStudentService;
import cn.com.qmth.stmms.biz.utils.ScoreItem;

public class ScoreCheckThread implements Runnable {

    protected static Logger log = LoggerFactory.getLogger(ScoreCheckThread.class);

    private int examId;

    private AtomicBoolean running;

    private ExamStudentService studentService;

    private ExamQuestionService questionService;

    private Map<String, List<ExamQuestion>> objectiveMap;

    private Map<String, List<ExamQuestion>> subjectiveMap;

    public ScoreCheckThread(int examId, AtomicBoolean running, ExamStudentService studentService,
            ExamQuestionService questionService) {
        this.examId = examId;
        this.running = running;
        this.studentService = studentService;
        this.questionService = questionService;

        this.objectiveMap = new HashMap<String, List<ExamQuestion>>();
        this.subjectiveMap = new HashMap<String, List<ExamQuestion>>();
    }

    @Override
    public void run() {
        log.info("start check score for examId=" + examId);
        try {
            int pageNumber = 1;
            int pageSize = 500;
            while (true) {
                // 循环获取已上传非缺考的考生
                List<ExamStudent> list = studentService.findByExamIdAndUploadAndAbsent(examId, true, false, pageNumber,
                        pageSize);
                if (list == null || list.isEmpty()) {
                    break;
                }

                for (ExamStudent student : list) {
                    checkStudent(student);
                }

                pageNumber++;
            }

            onFinish();
        } catch (Exception e) {
            log.error("check score exception for examId=" + examId, e);
        } finally {
            running.set(false);
            log.info("finish check score for examId=" + examId);
        }
    }

    private void checkStudent(ExamStudent student) {
        // 依次检查客观题与主观题分数
        checkQuestionScore(findExamQuestion(student.getSubjectCode(), true), student.getScoreList(true));
        checkQuestionScore(findExamQuestion(student.getSubjectCode(), false), student.getScoreList(false));
    }

    private void checkQuestionScore(List<ExamQuestion> questionList, List<ScoreItem> scoreList) {
        for (int i = 0; i < questionList.size(); i++) {
            ExamQuestion question = questionList.get(i);

            // double score = 0;
            // try {
            // score = scoreList.get(i).getScore();
            // } catch (Exception e) {
            // }
            // 针对每道小题分别统计零分人数与满分人数
            // if (score == 0) {
            // question.setZeroCount(question.getZeroCount() + 1);
            // } else if (score == question.getTotalScore().doubleValue()) {
            // question.setFullCount(question.getFullCount() + 1);
            // }
            // 统计考生总数
            // question.setTotalCount(question.getTotalCount() + 1);
        }
    }

    private List<ExamQuestion> findExamQuestion(String subjectCode, boolean isObjective) {
        List<ExamQuestion> list = isObjective ? objectiveMap.get(subjectCode) : subjectiveMap.get(subjectCode);
        if (list == null) {
            list = questionService.findByExamAndSubjectAndObjective(examId, subjectCode, isObjective);
            if (list == null) {
                list = new LinkedList<ExamQuestion>();
            }
            // 从数据库读取后，首先将人数清零
            for (ExamQuestion q : list) {
                // q.setTotalCount(0);
                // q.setZeroCount(0);
                // q.setFullCount(0);
            }
            if (isObjective) {
                objectiveMap.put(subjectCode, list);
            } else {
                subjectiveMap.put(subjectCode, list);
            }
        }
        return list;
    }

    private void onFinish() {
        // 人数回写数据库
        for (List<ExamQuestion> list : objectiveMap.values()) {
            for (ExamQuestion q : list) {
                questionService.save(q);
            }
        }
        for (List<ExamQuestion> list : subjectiveMap.values()) {
            for (ExamQuestion q : list) {
                questionService.save(q);
            }
        }

        objectiveMap.clear();
        subjectiveMap.clear();
    }
}
