package cn.com.qmth.stmms.report;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import cn.com.qmth.stmms.biz.exam.model.Exam;
import cn.com.qmth.stmms.biz.exam.model.ExamSubject;
import cn.com.qmth.stmms.biz.exam.service.ExamQuestionService;
import cn.com.qmth.stmms.biz.exam.service.ExamService;
import cn.com.qmth.stmms.biz.exam.service.ExamSubjectService;
import cn.com.qmth.stmms.biz.report.model.ReportSubject;
import cn.com.qmth.stmms.biz.report.model.ReportSubjectClass;
import cn.com.qmth.stmms.biz.report.model.ReportSubjectClassGroup;
import cn.com.qmth.stmms.biz.report.model.ReportSubjectCollege;
import cn.com.qmth.stmms.biz.report.model.ReportSubjectGroup;
import cn.com.qmth.stmms.biz.report.model.ReportSubjectQuestion;
import cn.com.qmth.stmms.biz.report.model.ReportSubjectTeacher;
import cn.com.qmth.stmms.biz.report.model.ReportSubjectTeacherClass;
import cn.com.qmth.stmms.biz.report.query.ReportSubjectQuery;
import cn.com.qmth.stmms.biz.report.service.ReportSubjectClassGroupService;
import cn.com.qmth.stmms.biz.report.service.ReportSubjectClassService;
import cn.com.qmth.stmms.biz.report.service.ReportSubjectCollegeService;
import cn.com.qmth.stmms.biz.report.service.ReportSubjectGroupService;
import cn.com.qmth.stmms.biz.report.service.ReportSubjectQuestionService;
import cn.com.qmth.stmms.biz.report.service.ReportSubjectService;
import cn.com.qmth.stmms.biz.report.service.ReportSubjectTeacherClassService;
import cn.com.qmth.stmms.biz.report.service.ReportSubjectTeacherService;
import cn.com.qmth.stmms.biz.school.model.School;
import cn.com.qmth.stmms.biz.school.service.SchoolService;

@Controller("reportApiController")
@RequestMapping("/report")
public class ReportController {

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

    @Autowired
    private ExamService examService;

    @Autowired
    private SchoolService schoolService;

    @Autowired
    private ExamSubjectService subjectService;

    @Autowired
    private ReportSubjectQuestionService questionService;

    @Autowired
    private ReportSubjectClassService classService;

    @Autowired
    private ReportSubjectTeacherService teacherService;

    @Autowired
    private ReportSubjectCollegeService collegeService;

    @Autowired
    private ReportSubjectGroupService groupService;

    @Autowired
    private ReportSubjectTeacherClassService teacherClassService;

    @Autowired
    private ReportSubjectClassGroupService classGroupService;

    @Autowired
    private ReportSubjectService reportSubjectService;

    @Autowired
    private ExamQuestionService examQuestionService;

    public static final String ANSWER_SPLIT = ",";

    private static final String NULL_PAPER_TYPE_PLACEHOLDER = "#";

    @RequestMapping(value = "/teachAndResearch/{examId}/{subjectCode}", method = RequestMethod.GET)
    public String getSubject(Model model, HttpServletRequest request, @PathVariable Integer examId,
            @PathVariable String subjectCode) {
        JSONObject result = getJson(examId, subjectCode, NULL_PAPER_TYPE_PLACEHOLDER, true);
        model.addAttribute("data", result);
        return "modules/report/pdf";
    }

    @RequestMapping(value = "/teachAndResearch/{examId}/{subjectCode}/{paperType}", method = RequestMethod.GET)
    public String getSubjectByPaperType(Model model, HttpServletRequest request, @PathVariable Integer examId,
            @PathVariable String subjectCode, @PathVariable String paperType) {
        JSONObject result = getJson(examId, subjectCode, paperType, true);
        model.addAttribute("data", result);
        return "modules/report/pdf";
    }

    @RequestMapping(value = "/teachAndResearch/simple/{examId}/{subjectCode}", method = RequestMethod.GET)
    public String getSubjectSimple(Model model, HttpServletRequest request, @PathVariable Integer examId,
            @PathVariable String subjectCode) {
        JSONObject result = getJson(examId, subjectCode, NULL_PAPER_TYPE_PLACEHOLDER, false);
        model.addAttribute("data", result);
        return "modules/report/pdf";
    }

    @RequestMapping(value = "/teachAndResearch/simple/{examId}/{subjectCode}/{paperType}", method = RequestMethod.GET)
    public String getSubjectSimpleByPaperType(Model model, HttpServletRequest request, @PathVariable Integer examId,
            @PathVariable String subjectCode, @PathVariable String paperType) {
        JSONObject result = getJson(examId, subjectCode, paperType, false);
        model.addAttribute("data", result);
        return "modules/report/pdf";
    }

    private JSONObject getJson(Integer examId, String subjectCode, String paperType, boolean isFull) {
        JSONObject result = new JSONObject();
        ExamSubject subject = subjectService.find(examId, subjectCode);
        if (subject == null) {
            result.accumulate("code", "500");
            result.accumulate("message", "找不到对应科目");
            return result;
        }
        List<String> paperTypes = examQuestionService.getPaperType(examId, subjectCode);
        if (!contains(subject.getObjectiveScore() > 0, paperTypes, paperType)) {
            result.accumulate("code", "500");
            result.accumulate("message", "试卷结构中没有对应的卷型");
            return result;
        }
        try {
            Exam exam = examService.findById(examId);
            School school = schoolService.findById(exam.getSchoolId());
            result.accumulate("examName", exam.getName());
            result.accumulate("schoolName", school.getName());
            result.accumulate("subjectName", paperType == null ? subject.getName() : subject.getName() + "_"
                    + paperType);
            ReportSubjectQuery query = new ReportSubjectQuery();
            query.setExamId(examId);
            query.setSubjectCode(subjectCode);
            query.setPaperType(paperType);
            query.setPageSize(Integer.MAX_VALUE);
            ReportSubject reportSubject = reportSubjectService.findOne(query.getExamId(), query.getSubjectCode());
            List<ReportSubjectClass> subjectClasses = classService.findByQuery(query);
            List<ReportSubjectGroup> subjectGroups = new ArrayList<ReportSubjectGroup>();
            List<ReportSubjectGroup> objectiveGroup = groupService.findByExamIdAndSubjectCodeAndObjectiveAndPaperType(
                    examId, subjectCode, true, paperType);
            List<ReportSubjectGroup> subjectiveGroup = groupService.findByExamIdAndSubjectCodeAndObjectiveAndPaperType(
                    examId, subjectCode, false, NULL_PAPER_TYPE_PLACEHOLDER);
            subjectGroups.addAll(objectiveGroup);
            subjectGroups.addAll(subjectiveGroup);
            result.accumulate("basic_paper", getPaperJson(reportSubject));
            result.accumulate("basic_question_subjective",
                    getQuestionJson(examId, subjectCode, false, NULL_PAPER_TYPE_PLACEHOLDER));
            result.accumulate("basic_question_objective", getQuestionJson(examId, subjectCode, true, paperType));
            result.accumulate("basic_class", getClassJson(subjectClasses));
            result.accumulate("basic_teacher", getTeacerJson(query));
            result.accumulate("basic_college", getCollegeJson(query));
            result.accumulate("basic_main_question", getGroupJson(subjectGroups));
            result.accumulate("basic_question_option", getOptionJson(reportSubject, paperType));
            result.accumulate("discrimination_level",
                    getDiscrimination(examId, subjectCode, paperType, reportSubject, subjectClasses, subjectGroups));
            result.accumulate("difficulty_level",
                    getDifficulty(examId, subjectCode, paperType, reportSubject, subjectClasses, subjectGroups));
            result.accumulate("range_level", getRangeLevel(query, reportSubject, subjectClasses));
            result.accumulate("range_10_totalScore", getRange10(reportSubject, subjectClasses, isFull));
            result.accumulate("range_1_totalScore", getRange1(reportSubject, subjectClasses, false));
            result.accumulate("range_segment_6", getRange6(reportSubject, subjectClasses));
            return result;
        } catch (Exception e) {
            log.error("report for examId=" + examId + "&subjectCode=" + subjectCode + "&paperType=" + paperType, e);
            result.accumulate("code", "500");
            result.accumulate("message", "系统异常");
            return result;
        }
    }

    private boolean contains(boolean objective, List<String> paperTypes, String paperType) {
        if (NULL_PAPER_TYPE_PLACEHOLDER.equals(paperType)) {
            if (!objective) {
                // 纯主观题
                return true;
            }
        }
        for (String s : paperTypes) {
            if (paperType.equalsIgnoreCase(s)) {
                return true;
            }
        }
        return false;
    }

    private String getPaperJson(ReportSubject r) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.accumulate("fullScore", r.getTotalScore());
        jsonObject.accumulate("maxScore", r.getMaxScore());
        jsonObject.accumulate("minScore", r.getMinScore());
        jsonObject.accumulate("avgScore", r.getAvgScore());
        jsonObject.accumulate("stdevScore", r.getStdev());
        jsonObject.accumulate("coefficient", r.getCoefficient());
        jsonObject.accumulate("difficulty", r.getDifficulty());
        jsonObject.accumulate("discrimination", r.getDiscrimination());
        jsonObject.accumulate("totalCount", r.getRealityCount());
        jsonObject.accumulate("zeroCount", r.getZeroCount());
        jsonObject.accumulate("fullCount", r.getFullCount());
        return jsonObject.toString();
    }

    private String getRange6(ReportSubject subject, List<ReportSubjectClass> list) {
        JSONArray result = new JSONArray();
        JSONObject jsonObject = new JSONObject();
        jsonObject.accumulate("name", "全卷");
        JSONArray groups = new JSONArray();
        JSONObject value = new JSONObject();
        value.accumulate("name", "全体");
        value.accumulate("segments",
                getScoreRange6(subject.getScoreRange(), subject.getTotalScore(), subject.getRealityCount()));
        groups.add(value);
        for (ReportSubjectClass c : list) {
            JSONObject classValue = new JSONObject();
            classValue.accumulate("name", c.getClassName());
            classValue.accumulate("segments",
                    getScoreRange6(c.getScoreRange(), subject.getTotalScore(), c.getRealityCount()));
            groups.add(classValue);
        }
        jsonObject.accumulate("groups", groups);
        result.add(jsonObject);
        return result.toString();
    }

    private String getRange1(ReportSubject subject, List<ReportSubjectClass> list, boolean isFull) {
        JSONObject result = new JSONObject();
        result.accumulate("total",
                getScoreRange1(subject.getScoreRange(), subject.getTotalScore(), subject.getRealityCount()));
        JSONArray classes = new JSONArray();
        if (isFull) {
            for (ReportSubjectClass c : list) {
                JSONObject classValue = new JSONObject();
                classValue.accumulate("name", c.getClassName());
                classValue.accumulate("ranges",
                        getScoreRange1(c.getScoreRange(), subject.getTotalScore(), c.getRealityCount()));
                classes.add(classValue);
            }
        }
        result.accumulate("classes", classes);
        return result.toString();
    }

    private String getRange10(ReportSubject subject, List<ReportSubjectClass> list, boolean isFull) {
        JSONObject result = new JSONObject();
        result.accumulate("total",
                getScoreRange10(subject.getScoreRange(), subject.getTotalScore(), subject.getRealityCount()));
        JSONArray classes = new JSONArray();
        if (isFull) {
            for (ReportSubjectClass r : list) {
                JSONObject classValue = new JSONObject();
                classValue.accumulate("name", r.getClassName());
                classValue.accumulate("ranges",
                        getScoreRange10(r.getScoreRange(), subject.getTotalScore(), r.getRealityCount()));
                classes.add(classValue);
            }
        }
        result.accumulate("classes", classes);
        return result.toString();
    }

    private JSONArray getScoreRange1(String scoreRange, double totalScore, Integer totalCount) {
        JSONArray result = new JSONArray();
        JSONObject jsonObject = JSONObject.fromObject(scoreRange);
        int rangeCount = 0;
        int sumCount = 0;
        int total = (int) Math.ceil(totalScore);
        for (int i = total; i >= 0; i--) {
            rangeCount = jsonObject.getInt(String.valueOf(i));
            sumCount = sumCount + rangeCount;
            result.add(getRangeJson(totalCount, rangeCount, sumCount, i));
        }
        return result;
    }

    private JSONArray getScoreRange10(String scoreRange, double totalScore, Integer totalCount) {
        JSONArray result = new JSONArray();
        JSONObject jsonObject = JSONObject.fromObject(scoreRange);
        int rangeCount = 0;
        int sumCount = 0;
        int range = 10;
        int total = (int) Math.ceil(totalScore / range);
        for (int i = total; i >= 0; i--) {
            // int start = i * range;
            // int end = (i - 1) * range + 1;
            // if (start > totalScore) {
            // start = (int) Math.ceil(totalScore);
            // }
            // if (end < 0) {
            // end = 0;
            // }
            // rangeCount = getSumCount(jsonObject, start, end);
            // sumCount = sumCount + rangeCount;
            // result.add(getRangeJson(totalCount, rangeCount, sumCount, i *
            // range));
            int start = i * range;
            int end = (i + 1) * range;
            if (end > totalScore) {
                end = (int) Math.ceil(totalScore);
            }
            if (end < 0) {
                end = 0;
            }
            rangeCount = getSumCount(jsonObject, start, end);
            sumCount = sumCount + rangeCount;
            result.add(getRangeJson(totalCount, rangeCount, sumCount, i * range));
        }
        return result;
    }

    private JSONArray getScoreRange6(String scoreRange, double totalScore, Integer totalCount) {
        JSONArray result = new JSONArray();
        JSONObject jsonObject = JSONObject.fromObject(scoreRange);
        int rangeCount = jsonObject.getInt(String.valueOf(0));
        int sumCount = rangeCount;
        int range = (int) Math.floor(totalScore / 5);
        int remainder = (int) Math.ceil(totalScore % 5);
        int start = 0;
        int end = 0;
        result.add(getRangeJson(totalCount, rangeCount, sumCount, start, end));
        for (int i = 1; i <= 5; i++) {
            end = i * range + remainder;
            rangeCount = getSumCount(jsonObject, start, end);
            sumCount = sumCount + rangeCount;
            result.add(getRangeJson(totalCount, rangeCount, sumCount, start, end));
            start = end + 1;
        }
        return result;
    }

    private JSONObject getRangeJson(Integer totalCount, int rangeCount, int sumCount, int score) {
        JSONObject value = new JSONObject();
        value.accumulate("score", score);
        value.accumulate("rangeCount", rangeCount);
        value.accumulate("rangeRate", rangeCount * 100.0 / totalCount);
        value.accumulate("sumCount", sumCount);
        value.accumulate("sumRate", sumCount * 100.0 / totalCount);
        return value;
    }

    private JSONObject getRangeJson(Integer totalCount, int rangeCount, int sumCount, int start, int end) {
        JSONObject value = new JSONObject();
        if (start == 0 && end == 0) {
            value.accumulate("score", 0);
        } else if (start == 0 && end != 0) {
            value.accumulate("score", start + "~" + end);
        } else {
            value.accumulate("score", (start - 0.5) + "~" + end);
        }
        value.accumulate("rangeCount", rangeCount);
        value.accumulate("rangeRate", rangeCount * 100.0 / totalCount);
        value.accumulate("sumCount", sumCount);
        value.accumulate("sumRate", sumCount * 100.0 / totalCount);
        return value;
    }

    private int getSumCount(JSONObject jsonObject, int start, int end) {
        int sumCount = 0;
        int currentCount = 0;
        if (start < end) {
            for (int i = start; i <= end; i++) {
                currentCount = jsonObject.getInt(String.valueOf(i));
                sumCount = sumCount + currentCount;
            }
        } else if (start >= end) {
            for (int i = end; i <= start; i++) {
                currentCount = jsonObject.getInt(String.valueOf(i));
                sumCount = sumCount + currentCount;
            }
        } else {
            sumCount = jsonObject.getInt(String.valueOf(start));
        }
        return sumCount;
    }

    private String getRangeLevel(ReportSubjectQuery query, ReportSubject reportSubject, List<ReportSubjectClass> classes) {
        JSONArray array = new JSONArray();
        JSONObject value = JSONObject.fromObject(reportSubject.getRangeLevel());
        value.accumulate("name", "全部");
        value.accumulate("totalCount", reportSubject.getRealityCount());
        array.add(value);
        for (ReportSubjectClass reportSubjectClass : classes) {
            JSONObject classValue = JSONObject.fromObject(reportSubjectClass.getRangeLevel());
            classValue.accumulate("name", reportSubjectClass.getClassName());
            classValue.accumulate("totalCount", reportSubjectClass.getRealityCount());
            array.add(classValue);
        }
        return array.toString();
    }

    private String getDifficulty(Integer examId, String subjectCode, String paperType, ReportSubject reportSubject,
            List<ReportSubjectClass> subjectClasses, List<ReportSubjectGroup> subjectGroups) {
        JSONObject defaultLevels = new JSONObject();
        JSONObject content = new JSONObject();
        content.accumulate("questionCount", 0);
        content.accumulate("fullScore", 0);
        defaultLevels.accumulate("high", content);
        defaultLevels.accumulate("middle", content);
        defaultLevels.accumulate("low", content);

        JSONArray result = new JSONArray();
        // 全部
        JSONObject obj = new JSONObject();
        JSONArray groups = new JSONArray();
        JSONObject value = new JSONObject();
        value.accumulate("name", "全卷");
        value.accumulate("questionCount", reportSubject.getQuestionCount());
        value.accumulate("fullScore", reportSubject.getTotalScore());
        value.accumulate("difficulty", reportSubject.getDifficulty());
        value.accumulate("levels", reportSubject.getDifficulityLevel() == null ? defaultLevels.toString()
                : reportSubject.getDifficulityLevel());
        groups.add(value);
        for (ReportSubjectGroup r : subjectGroups) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.accumulate("name", r.getGroupName());
            jsonObject.accumulate("questionCount", r.getQuestionCount());
            jsonObject.accumulate("fullScore", r.getTotalScore());
            jsonObject.accumulate("difficulty", r.getDifficulty());
            jsonObject.accumulate("levels",
                    r.getDifficulityLevel() == null ? defaultLevels.toString() : r.getDifficulityLevel());
            groups.add(jsonObject);
        }
        obj.accumulate("name", "全部");
        obj.accumulate("groups", groups);
        result.add(obj);
        // 机组
        for (ReportSubjectClass reportSubjectClass : subjectClasses) {
            JSONObject classValue = new JSONObject();
            classValue.accumulate("name", reportSubjectClass.getClassName());
            JSONArray classGroups = new JSONArray();
            JSONObject group = new JSONObject();
            group.accumulate("name", "全卷");
            group.accumulate("questionCount", reportSubject.getQuestionCount());
            group.accumulate("fullScore", reportSubject.getTotalScore());
            group.accumulate("difficulty", reportSubjectClass.getDifficulty());
            group.accumulate("levels", reportSubjectClass.getDifficulityLevel() == null ? defaultLevels.toString()
                    : reportSubjectClass.getDifficulityLevel());
            classGroups.add(group);
            List<ReportSubjectClassGroup> classGroupsList = new ArrayList<ReportSubjectClassGroup>();
            List<ReportSubjectClassGroup> classGroupsListO = classGroupService
                    .findByExamIdAndSubjectCodeAndObjectiveAndPaperType(examId, subjectCode, true, paperType,
                            reportSubjectClass.getClassName());
            List<ReportSubjectClassGroup> classGroupsListS = classGroupService
                    .findByExamIdAndSubjectCodeAndObjectiveAndPaperType(examId, subjectCode, false,
                            NULL_PAPER_TYPE_PLACEHOLDER, reportSubjectClass.getClassName());
            classGroupsList.addAll(classGroupsListO);
            classGroupsList.addAll(classGroupsListS);
            for (ReportSubjectClassGroup r : classGroupsList) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.accumulate("name", r.getGroupName());
                jsonObject.accumulate("questionCount", r.getQuestionCount());
                jsonObject.accumulate("fullScore", r.getTotalScore());
                jsonObject.accumulate("difficulty", r.getDifficulty());
                jsonObject.accumulate("levels",
                        r.getDifficulityLevel() == null ? defaultLevels.toString() : r.getDifficulityLevel());
                classGroups.add(jsonObject);
            }
            classValue.accumulate("groups", classGroups);
            result.add(classValue);
        }
        return result.toString();
    }

    private String getDiscrimination(Integer examId, String subjectCode, String paperType, ReportSubject reportSubject,
            List<ReportSubjectClass> subjectClasses, List<ReportSubjectGroup> subjectGroups) {
        JSONObject defaultLevels = new JSONObject();
        JSONObject content = new JSONObject();
        content.accumulate("questionCount", 0);
        content.accumulate("fullScore", 0);
        defaultLevels.accumulate("excellent", content);
        defaultLevels.accumulate("good", content);
        defaultLevels.accumulate("general", content);
        defaultLevels.accumulate("bad", content);

        JSONArray result = new JSONArray();
        // 全部
        JSONObject obj = new JSONObject();
        JSONArray groups = new JSONArray();
        JSONObject value = new JSONObject();
        value.accumulate("name", "全卷");
        value.accumulate("questionCount", reportSubject.getQuestionCount());
        value.accumulate("fullScore", reportSubject.getTotalScore());
        value.accumulate("coefficient", reportSubject.getCoefficient());
        value.accumulate("levels", reportSubject.getDiscriminationLevel() == null ? defaultLevels.toString()
                : reportSubject.getDiscriminationLevel());
        groups.add(value);
        for (ReportSubjectGroup r : subjectGroups) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.accumulate("name", r.getGroupName());
            jsonObject.accumulate("questionCount", r.getQuestionCount());
            jsonObject.accumulate("fullScore", r.getTotalScore());
            jsonObject.accumulate("coefficient", r.getCoefficient());
            jsonObject.accumulate("levels",
                    r.getDiscriminationLevel() == null ? defaultLevels.toString() : r.getDiscriminationLevel());
            groups.add(jsonObject);
        }
        obj.accumulate("name", "全部");
        obj.accumulate("groups", groups);
        result.add(obj);
        // 机组
        for (ReportSubjectClass reportSubjectClass : subjectClasses) {
            JSONObject classValue = new JSONObject();
            classValue.accumulate("name", reportSubjectClass.getClassName());
            JSONArray classGroups = new JSONArray();
            JSONObject group = new JSONObject();
            group.accumulate("name", "全卷");
            group.accumulate("questionCount", reportSubject.getQuestionCount());
            group.accumulate("fullScore", reportSubject.getTotalScore());
            group.accumulate("coefficient", reportSubjectClass.getCoefficient());
            group.accumulate("levels", reportSubjectClass.getDiscriminationLevel() == null ? defaultLevels.toString()
                    : reportSubjectClass.getDiscriminationLevel());
            classGroups.add(group);
            List<ReportSubjectClassGroup> classGroupsList = new ArrayList<ReportSubjectClassGroup>();
            List<ReportSubjectClassGroup> classGroupsListO = classGroupService
                    .findByExamIdAndSubjectCodeAndObjectiveAndPaperType(examId, subjectCode, true, paperType,
                            reportSubjectClass.getClassName());
            List<ReportSubjectClassGroup> classGroupsListS = classGroupService
                    .findByExamIdAndSubjectCodeAndObjectiveAndPaperType(examId, subjectCode, false,
                            NULL_PAPER_TYPE_PLACEHOLDER, reportSubjectClass.getClassName());
            classGroupsList.addAll(classGroupsListO);
            classGroupsList.addAll(classGroupsListS);
            for (ReportSubjectClassGroup r : classGroupsList) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.accumulate("name", r.getGroupName());
                jsonObject.accumulate("questionCount", r.getQuestionCount());
                jsonObject.accumulate("fullScore", r.getTotalScore());
                jsonObject.accumulate("coefficient", r.getCoefficient());
                jsonObject.accumulate("levels",
                        r.getDiscriminationLevel() == null ? defaultLevels.toString() : r.getDiscriminationLevel());
                classGroups.add(jsonObject);
            }
            classValue.accumulate("groups", classGroups);
            result.add(classValue);
        }
        return result.toString();
    }

    private String getOptionJson(ReportSubject reportSubject, String paperType) {
        JSONObject value = new JSONObject();
        value.accumulate("options", reportSubject.getOptions() == null ? new JSONArray().toString() : reportSubject
                .getOptions().split(ANSWER_SPLIT));
        List<ReportSubjectQuestion> list = questionService.findByExamIdAndSubjectCodeAndObjectiveAndPaperType(
                reportSubject.getExamId(), reportSubject.getSubjectCode(), true, paperType);
        JSONArray array = new JSONArray();
        for (ReportSubjectQuestion r : list) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.accumulate("number", r.getMainNumber() + "-" + r.getSubNumber());
            jsonObject.accumulate("totalCount", r.getRealityCount());
            jsonObject.accumulate("correctCount", r.getFullCount());
            jsonObject.accumulate("difficulty", r.getDifficulty());
            jsonObject.accumulate("discrimination", r.getDiscrimination());
            jsonObject.accumulate("answer", r.getAnswer());
            jsonObject.accumulate("options", r.getOptions());
            array.add(jsonObject);
        }
        value.accumulate("questions", array);
        return value.toString();
    }

    private String getGroupJson(List<ReportSubjectGroup> list) {
        JSONArray array = new JSONArray();
        for (ReportSubjectGroup r : list) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.accumulate("name", r.getGroupName());
            jsonObject.accumulate("objective", r.getObjective());
            jsonObject.accumulate("fullScore", r.getTotalScore());
            jsonObject.accumulate("maxScore", r.getMaxScore());
            jsonObject.accumulate("minScore", r.getMinScore());
            jsonObject.accumulate("avgScore", r.getAvgScore());
            jsonObject.accumulate("stdevScore", r.getStdev());
            jsonObject.accumulate("coefficient", r.getCoefficient());
            jsonObject.accumulate("difficulty", r.getDifficulty());
            jsonObject.accumulate("discrimination", r.getDiscrimination());
            jsonObject.accumulate("totalCount", r.getRealityCount());
            jsonObject.accumulate("zeroCount", r.getZeroCount());
            jsonObject.accumulate("fullCount", r.getFullCount());
            array.add(jsonObject);
        }
        return array.toString();
    }

    private String getCollegeJson(ReportSubjectQuery query) {
        JSONArray array = new JSONArray();
        List<ReportSubjectCollege> list = collegeService.findByQuery(query);
        for (ReportSubjectCollege r : list) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.accumulate("name", r.getCollegeName());
            jsonObject.accumulate("maxScore", r.getMaxScore());
            jsonObject.accumulate("minScore", r.getMinScore());
            jsonObject.accumulate("avgScore", r.getAvgScore());
            jsonObject.accumulate("excellentCount", r.getExcellentCount());
            jsonObject.accumulate("excellentRate", r.getExcellentRate());
            jsonObject.accumulate("passCount", r.getPassCount());
            jsonObject.accumulate("passRate", r.getPassRate());
            array.add(jsonObject);
        }
        return array.toString();
    }

    private String getTeacerJson(ReportSubjectQuery query) {
        JSONArray array = new JSONArray();
        List<ReportSubjectTeacher> list = teacherService.findByQuery(query);
        for (ReportSubjectTeacher r : list) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.accumulate("name", r.getTeacherName());
            jsonObject.accumulate("totalCount", r.getRealityCount());
            jsonObject.accumulate("maxScore", r.getMaxScore());
            jsonObject.accumulate("minScore", r.getMinScore());
            jsonObject.accumulate("avgScore", r.getAvgScore());
            jsonObject.accumulate("excellentCount", r.getExcellentCount());
            jsonObject.accumulate("excellentRate", r.getExcellentRate());
            jsonObject.accumulate("passCount", r.getPassCount());
            jsonObject.accumulate("passRate", r.getPassRate());
            jsonObject.accumulate("relativeAvgScore", r.getRelativeAvgScore());
            JSONArray classes = new JSONArray();
            query.setTeacherName(r.getTeacherName());
            List<ReportSubjectTeacherClass> teacherClasses = teacherClassService.findByQuery(query);
            for (ReportSubjectTeacherClass teacherClass : teacherClasses) {
                JSONObject value = new JSONObject();
                value.accumulate("name", teacherClass.getClassName());
                value.accumulate("totalCount", teacherClass.getRealityCount());
                value.accumulate("maxScore", teacherClass.getMaxScore());
                value.accumulate("minScore", teacherClass.getMinScore());
                value.accumulate("avgScore", teacherClass.getAvgScore());
                value.accumulate("excellentCount", teacherClass.getExcellentCount());
                value.accumulate("excellentRate", teacherClass.getExcellentRate());
                value.accumulate("passCount", teacherClass.getPassCount());
                value.accumulate("passRate", teacherClass.getPassRate());
                value.accumulate("relativeAvgScore", teacherClass.getRelativeAvgScore());
                classes.add(value);
            }
            jsonObject.accumulate("classes", classes);
            array.add(jsonObject);
        }
        return array.toString();
    }

    private String getClassJson(List<ReportSubjectClass> list) {
        JSONArray array = new JSONArray();
        for (ReportSubjectClass r : list) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.accumulate("name", r.getClassName());
            jsonObject.accumulate("maxScore", r.getMaxScore());
            jsonObject.accumulate("minScore", r.getMinScore());
            jsonObject.accumulate("avgScore", r.getAvgScore());
            jsonObject.accumulate("stdevScore", r.getStdev());
            jsonObject.accumulate("excellentCount", r.getExcellentCount());
            jsonObject.accumulate("excellentRate", r.getExcellentRate());
            jsonObject.accumulate("passCount", r.getPassCount());
            jsonObject.accumulate("passRate", r.getPassRate());
            jsonObject.accumulate("coefficient", r.getCoefficient());
            jsonObject.accumulate("difficulty", r.getDifficulty());
            array.add(jsonObject);
        }
        return array.toString();
    }

    private String getQuestionJson(Integer examId, String subjectCode, boolean isObjective, String paperType) {
        JSONArray array = new JSONArray();
        List<ReportSubjectQuestion> list = questionService.findByExamIdAndSubjectCodeAndObjectiveAndPaperType(examId,
                subjectCode, isObjective, paperType);
        for (ReportSubjectQuestion r : list) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.accumulate("name", r.getQuestionName());
            jsonObject.accumulate("number", r.getMainNumber() + "-" + r.getSubNumber());
            jsonObject.accumulate("fullScore", r.getTotalScore());
            jsonObject.accumulate("maxScore", r.getMaxScore());
            jsonObject.accumulate("minScore", r.getMinScore());
            jsonObject.accumulate("avgScore", r.getAvgScore());
            jsonObject.accumulate("stdevScore", r.getStdev());
            jsonObject.accumulate("coefficient", r.getCoefficient());
            jsonObject.accumulate("difficulty", r.getDifficulty());
            jsonObject.accumulate("discrimination", r.getDiscrimination());
            jsonObject.accumulate("totalCount", r.getRealityCount());
            jsonObject.accumulate("zeroCount", r.getZeroCount());
            jsonObject.accumulate("fullCount", r.getFullCount());
            jsonObject.accumulate("fullRate", r.getFullScoreRate());
            jsonObject.accumulate("scoreRate", r.getScoreRate());
            array.add(jsonObject);
        }
        return array.toString();
    }
}
