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

import java.util.LinkedList;
import java.util.List;

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.common.enums.ObjectivePolicy;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

public class ScoreCalculateUtil {

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

    private ExamStudent student;

    private ScoreCalculateUtil(ExamStudent student) {
        this.student = student;
    }

    public ScoreInfo calculate(List<ExamQuestion> oList, List<ExamQuestion> sList) {
        // log.debug("start calculate, examId=" + student.getExamId() +
        // ", examNumber=" + student.getExamNumber());

        ScoreInfo info = new ScoreInfo();
        if (oList != null && oList.size() > 0) {
            calculateObjective(oList, info);
        }
        if (sList != null && sList.size() > 0) {
            calculateSubjective(sList, info);
        }
        return info;
    }

    private void calculateObjective(List<ExamQuestion> questionList, ScoreInfo scoreInfo) {
        // log.debug("start calculate objective score");
        List<String> answerList = student.getAnswerList();
        // Map<String, Integer> config = exam.getObjectiveBlockMap();

        // log.debug("student answers: " + student.getAnswers());
        // log.debug("exam objective config: " + exam.getObjectiveBlock());

        int index = -1;
        int lastMainNumber = 0;
        for (ExamQuestion question : questionList) {
            // log.debug("find objective block for " + block.getTitle() +
            // ", question start=" + start);
            if (question.getMainNumber() != lastMainNumber) {
                scoreInfo.incrMainNumber(question.getMainTitle());
            }

            index++;
            String answer = "#";
            double score = 0d;
            try {
                answer = answerList.get(index);
            } catch (Exception e) {
                continue;
            }

            boolean correct = true;

            // 客观题判分策略
            // 任选给分
            if (ObjectivePolicy.ALL.equals(question.getObjectivePolicy())) {
                score = answer.length() == 0 || answer.equals("#") ? 0 : question.getTotalScore();
            } else if(ObjectivePolicy.PROPORTION.equals(question.getObjectivePolicy())){
                for (int i = 0; i < answer.length(); i++) {
                    if (!question.getAnswer().contains(String.valueOf(answer.charAt(i)))) {
                        correct = false;
                        break;
                    }
                }
                if (correct) {
                    score = DoubleUtil.div(DoubleUtil.mul(question.getTotalScore(),answer.length()),question.getAnswer().length(),2);
                }
            } else if(ObjectivePolicy.CUSTOMIZE.equals(question.getObjectivePolicy())){
            	for (int i = 0; i < answer.length(); i++) {
                    if (!question.getAnswer().contains(String.valueOf(answer.charAt(i)))) {
                        correct = false;
                        break;
                    }
                }
            	 if (correct) {
                     score = getScore(answer.length(),question.getCustomizePolicy());
                 }
            } else {
                for (int i = 0; i < answer.length(); i++) {
                    if (!question.getAnswer().contains(String.valueOf(answer.charAt(i)))) {
                        correct = false;
                        break;
                    }
                }
                if (correct & ObjectivePolicy.LEAK.equals(question.getObjectivePolicy())) {
                    score = answer.length() < question.getAnswer().length() ? question.getTotalScore() / 2 : question
                            .getTotalScore();
                }
                if (correct
                        & (question.getObjectivePolicy() == null || ObjectivePolicy.NONE.equals(question
                                .getObjectivePolicy()))) {
                    score = answer.length() < question.getAnswer().length() ? 0 : question.getTotalScore();
                }
            }

            // log.debug("question result: " + question.getNumber() + ", " +
            // answer + ", " + score);
            scoreInfo.addScore(null, question.getSubNumber(), score, answer, true);
        }
    }

    private double getScore(int length, String customizePolicy) {
    	JSONArray ja=JSONArray.fromObject(customizePolicy);
    	for(int i=0;i<ja.size();i++) {
    		JSONObject jo=ja.getJSONObject(i);
    		int count=Integer.valueOf(jo.getString("answerCount"));
    		if(length==count) {
    			double score=Double.valueOf(jo.getString("answerScore"));
    			return score;
    		}
    	}
		return 0;
	}

	private void calculateSubjective(List<ExamQuestion> sList, ScoreInfo scoreInfo) {

    }

    public static ScoreCalculateUtil instance(ExamStudent student) {
        return new ScoreCalculateUtil(student);
    }

    public static void main(String[] args) {
        ExamStudent student = new ExamStudent();
        student.setAnswers("A,B,AB,C,#,#,#,#");
        ScoreCalculateUtil util = ScoreCalculateUtil.instance(student);

        List<ExamQuestion> oList = new LinkedList<ExamQuestion>();
        // ExamQuestion q = new ExamQuestion();
        // q.setMainNumber(1);
        // q.setMainTitle("单选");
        // q.setSubNumber(1);
        // q.setAnswer("B");
        // q.setTotalScore(2d);
        // oList.add(q);
        //
        // q = new ExamQuestion();
        // q.setMainNumber(1);
        // q.setMainTitle("单选");
        // q.setSubNumber(2);
        // q.setAnswer("B");
        // q.setTotalScore(2d);
        // oList.add(q);
        //
        // q = new ExamQuestion();
        // q.setMainNumber(2);
        // q.setMainTitle("多选");
        // q.setSubNumber(1);
        // q.setAnswer("AC");
        // q.setTotalScore(3d);
        // oList.add(q);
        //
        // q = new ExamQuestion();
        // q.setMainNumber(2);
        // q.setMainTitle("多选");
        // q.setSubNumber(2);
        // q.setAnswer("C");
        // q.setTotalScore(3d);
        // oList.add(q);

        ScoreInfo info = util.calculate(oList, null);
        System.out.println(info.getObjectiveScore());
        for (ScoreItem item : info.getScoreList()) {
            System.out.println(item.getTitle() + ": " + item.toString());
        }
    }
}
