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

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

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

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import cn.com.qmth.stmms.admin.dto.ExamQuestionDTO;
import cn.com.qmth.stmms.biz.campus.model.Campus;
import cn.com.qmth.stmms.biz.campus.service.CampusService;
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.model.ExamSubject;
import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
import cn.com.qmth.stmms.biz.exam.query.ExamStudentSearchQuery;
import cn.com.qmth.stmms.biz.exam.service.ExamQuestionService;
import cn.com.qmth.stmms.biz.exam.service.ExamStudentService;
import cn.com.qmth.stmms.biz.exam.service.ExamSubjectService;
import cn.com.qmth.stmms.biz.exam.service.MarkGroupService;
import cn.com.qmth.stmms.biz.exam.service.MarkerService;
import cn.com.qmth.stmms.biz.lock.LockService;
import cn.com.qmth.stmms.biz.mark.model.PictureConfigItem;
import cn.com.qmth.stmms.biz.mark.service.MarkService;
import cn.com.qmth.stmms.common.auth.annotation.RoleRequire;
import cn.com.qmth.stmms.common.domain.WebUser;
import cn.com.qmth.stmms.common.enums.LockType;
import cn.com.qmth.stmms.common.enums.MarkMode;
import cn.com.qmth.stmms.common.enums.MarkStatus;
import cn.com.qmth.stmms.common.enums.Role;
import cn.com.qmth.stmms.common.enums.ScorePolicy;
import cn.com.qmth.stmms.common.utils.PictureUrlBuilder;
import cn.com.qmth.stmms.common.utils.RequestUtils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

@Controller("markGroupController")
@RequestMapping("/admin/exam/group")
public class MarkGroupController extends BaseExamController {

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

    @Autowired
    private ExamSubjectService subjectService;

    @Autowired
    private ExamQuestionService questionService;

    @Autowired
    private MarkGroupService groupService;

    @Autowired
    private MarkerService markerService;

    @Autowired
    private ExamStudentService studentService;

    @Autowired
    private CampusService campusService;

    @Autowired
    private MarkService markService;

    @Autowired
    private LockService lockService;

    @Value("${slice.image.server}")
    private String imageServer;

    @RequestMapping
    public String list(HttpServletRequest request, Model model, @RequestParam String subjectCode) {
        WebUser wu = RequestUtils.getWebUser(request);
        int examId = getSessionExamId(request);
        ExamSubject subject = subjectService.find(examId, subjectCode);
        if (subject == null) {
            return "redirect:/admin/exam/mark";
        }
        if (wu.isSubjectHeader() && !subjectCode.equals(wu.getUser().getSubjectCode())) {
            return "redirect:/admin/exam/mark";
        }
        List<MarkGroup> list = groupService.findByExamAndSubject(examId, subjectCode);
        for (MarkGroup group : list) {
            group.setQuestionList(questionService.findByExamAndSubjectAndObjectiveAndGroupNumber(examId, subjectCode,
                    false, group.getNumber()));
            group.setMarkerCount(markerService.countByExamAndSubjectAndGroup(examId, subjectCode, group.getNumber()));
            group.setCurrentCount(markService.applyCount(group));
            int percent = group.getLibraryCount() > 0 ? (int) (group.getMarkedCount() * 100.00 / group
                    .getLibraryCount()) : 0;
            group.setPercent(percent);
        }
        model.addAttribute("resultList", list);
        model.addAttribute("subject", subject);
        model.addAttribute("subjectList", getExamSubject(examId, wu));
        return "modules/exam/groupList";
    }

    @RequestMapping("/query")
    @ResponseBody
    public JSONArray query(HttpServletRequest request, @RequestParam String subjectCode,
            @RequestParam(required = false) Boolean withDouble, @RequestParam(required = false) MarkStatus status) {
        int examId = getSessionExamId(request);
        JSONArray array = new JSONArray();
        List<MarkGroup> list = withDouble != null && withDouble ? groupService.findByExamAndSubjectWithDouble(examId,
                subjectCode) : (status != null ? groupService
                .findByExamAndSubjectAndStatus(examId, subjectCode, status) : groupService.findByExamAndSubject(examId,
                subjectCode));
        for (MarkGroup group : list) {
            group.setQuestionList(questionService.findByExamAndSubjectAndObjectiveAndGroupNumber(examId, subjectCode,
                    false, group.getNumber()));
            JSONObject obj = new JSONObject();
            obj.accumulate("number", group.getNumber());
            obj.accumulate("title", group.getTitle());
            obj.accumulate("score", group.getTotalScore());
            array.add(obj);
        }
        return array;
    }

    @RequestMapping("/check-count")
    @RoleRequire(Role.SCHOOL_ADMIN)
    public String ckeckCount(HttpServletRequest request, Model model, RedirectAttributes redirectAttributes,
            @RequestParam String subjectCode) {
        int examId = getSessionExamId(request);
        ExamSubject subject = subjectService.find(examId, subjectCode);
        if (subject == null) {
            return "redirect:/admin/exam/mark";
        }
        markService.updateAllCount(examId, subjectCode);

        redirectAttributes.addAttribute("subjectCode", subjectCode);
        return "redirect:/admin/exam/group";
    }

    @RequestMapping("/release")
    @RoleRequire(Role.SCHOOL_ADMIN)
    public String release(HttpServletRequest request, Model model, RedirectAttributes redirectAttributes,
            @RequestParam String subjectCode, @RequestParam Integer number) {
        int examId = getSessionExamId(request);
        MarkGroup group = groupService.findOne(examId, subjectCode, number);
        if (group == null) {
            return "redirect:/admin/exam/mark";
        }
        try {
            lockService.waitlock(LockType.GROUP, group.getExamId(), group.getSubjectCode(), group.getNumber());
            markService.releaseByGroup(group);
        } finally {
            lockService.unlock(LockType.GROUP, group.getExamId(), group.getSubjectCode(), group.getNumber());
        }
        redirectAttributes.addAttribute("subjectCode", subjectCode);
        return "redirect:/admin/exam/group";
    }

    @RequestMapping("/reset")
    @RoleRequire(Role.SCHOOL_ADMIN)
    public String reset(HttpServletRequest request, Model model, RedirectAttributes redirectAttributes,
            @RequestParam String subjectCode, @RequestParam Integer number) {
        int examId = getSessionExamId(request);
        MarkGroup group = groupService.findOne(examId, subjectCode, number);
        if (group == null) {
            return "redirect:/admin/exam/mark";
        }
        try {
            lockService.waitlock(LockType.GROUP, group.getExamId(), group.getSubjectCode(), group.getNumber());
            markService.resetByGroup(group);
        } catch (Exception e) {
            log.error("reset group error", e);
            throw new RuntimeException("重置大题失败", e);
        } finally {
            lockService.unlock(LockType.GROUP, group.getExamId(), group.getSubjectCode(), group.getNumber());
        }

        redirectAttributes.addAttribute("subjectCode", subjectCode);
        return "redirect:/admin/exam/group";
    }

    @RequestMapping("/changeStatus")
    @RoleRequire(Role.SCHOOL_ADMIN)
    public String changeStatus(HttpServletRequest request, Model model, RedirectAttributes redirectAttributes,
            @RequestParam String subjectCode, @RequestParam Integer number, @RequestParam MarkStatus status) {
        int examId = getSessionExamId(request);
        MarkGroup group = groupService.findOne(examId, subjectCode, number);
        if (group == null) {
            return "redirect:/admin/exam/mark";
        }
        try {
            lockService.waitlock(LockType.GROUP, group.getExamId(), group.getSubjectCode(), group.getNumber());
            boolean allow = false;
            if (group.getStatus() == MarkStatus.TRIAL && status == MarkStatus.FORMAL) {
                allow = true;
            } else if (group.getStatus() == MarkStatus.FORMAL && status == MarkStatus.FINISH
                    && group.getLeftCount() == 0) {
                allow = true;
            } else if (group.getStatus() == MarkStatus.FINISH && status == MarkStatus.FORMAL) {
                allow = true;
            }
            if (allow) {
                if (groupService.updateStatus(examId, subjectCode, number, status, group.getStatus())
                        && status == MarkStatus.FORMAL) {
                    // 切换到正评成功后刷新任务数量
                    group.setStatus(status);
                    markService.updateLibraryCount(group);
                    markService.updateMarkedCount(group);
                }
            } else {
                redirectAttributes.addAttribute("message", "不能切换到指定的评卷状态");
            }
        } finally {
            lockService.unlock(LockType.GROUP, group.getExamId(), group.getSubjectCode(), group.getNumber());
        }
        redirectAttributes.addAttribute("subjectCode", subjectCode);
        return "redirect:/admin/exam/group";
    }

    @RequestMapping("/add")
    @RoleRequire(Role.SCHOOL_ADMIN)
    public String add(HttpServletRequest request, Model model, @RequestParam String subjectCode) {
        int examId = getSessionExamId(request);
        ExamSubject subject = subjectService.find(examId, subjectCode);
        if (subject == null) {
            return "redirect:/admin/exam/mark";
        }
        MarkGroup group = new MarkGroup();
        group.setSubjectCode(subjectCode);
        model.addAttribute("group", group);
        model.addAttribute("markModeList", MarkMode.values());
        model.addAttribute("scorePolicyList", ScorePolicy.values());
        return "modules/exam/groupAdd";
    }

    @RequestMapping("/edit-simple")
    @RoleRequire(Role.SCHOOL_ADMIN)
    public String editSimple(HttpServletRequest request, Model model, RedirectAttributes redirectAttributes,
            @RequestParam String subjectCode, @RequestParam Integer number) {
        int examId = getSessionExamId(request);
        MarkGroup group = groupService.findOne(examId, subjectCode, number);
        if (group != null) {
            String pictureConfig = buildPictureConfig(group);
            group.setPicList(pictureConfig);
            group.setQuestionList(questionService.findByExamAndSubjectAndObjectiveAndGroupNumber(examId, subjectCode,
                    false, group.getNumber()));
            model.addAttribute("group", group);
            model.addAttribute(
                    "questions",
                    questionService.findByExamAndSubjectAndObjectiveAndGroupNumber(group.getExamId(),
                            group.getSubjectCode(), false, group.getNumber()));
            model.addAttribute("pictureConfig", pictureConfig);
            model.addAttribute("markModeList", MarkMode.values());
            model.addAttribute("scorePolicyList", ScorePolicy.values());
            return "modules/exam/groupEditSimple";
        } else {
            redirectAttributes.addAttribute("subjectCode", subjectCode);
            return "redirect:/admin/exam/group";
        }
    }

    @RequestMapping("/edit-full")
    @RoleRequire(Role.SCHOOL_ADMIN)
    public String editFull(HttpServletRequest request, Model model, RedirectAttributes redirectAttributes,
            @RequestParam String subjectCode, @RequestParam Integer number) {
        int examId = getSessionExamId(request);
        MarkGroup group = groupService.findOne(examId, subjectCode, number);
        if (group != null) {
            String pictureConfig = buildPictureConfig(group);
            group.setPicList(pictureConfig);
            group.setQuestionList(questionService.findByExamAndSubjectAndObjectiveAndGroupNumber(examId, subjectCode,
                    false, number));
            List<MarkGroup> questionList = new ArrayList<MarkGroup>();
            String[] mainNumbers = group.getMainNumber().split(",");
            for (String mainNumber : mainNumbers) {
                List<ExamQuestion> list = questionService.findByExamAndSubjectAndObjectiveAndMainNumber(examId,
                        subjectCode, false, Integer.parseInt(mainNumber));
                StringBuilder score = new StringBuilder();
                DecimalFormat format = new DecimalFormat("###.#");
                String title = "";
                for (ExamQuestion question : list) {
                    if (score.length() > 0) {
                        score.append(",");
                    }
                    score.append(format.format(question.getTotalScore()));
                    title = question.getMainTitle();
                }
                MarkGroup question = new MarkGroup();
                question.setMainNumber(mainNumber);
                question.setTitle(title);
                question.setScoreList(score.toString());
                questionList.add(question);
            }
            model.addAttribute("group", group);
            model.addAttribute("questionList", questionList);
            model.addAttribute("pictureConfig", pictureConfig);
            model.addAttribute("markModeList", MarkMode.values());
            model.addAttribute("scorePolicyList", ScorePolicy.values());
            return "modules/exam/groupEditFull";
        } else {
            redirectAttributes.addAttribute("subjectCode", subjectCode);
            return "redirect:/admin/exam/group";
        }
    }

    @RequestMapping("/delete")
    @RoleRequire(Role.SCHOOL_ADMIN)
    public String delete(HttpServletRequest request, Model model, RedirectAttributes redirectAttributes,
            @RequestParam String subjectCode, @RequestParam Integer number) {
        int examId = getSessionExamId(request);
        MarkGroup group = groupService.findOne(examId, subjectCode, number);
        if (group == null) {
            redirectAttributes.addAttribute("subjectCode", subjectCode);
            return "redirect:/admin/exam/group";
        }
        try {
            lockService.waitlock(LockType.GROUP, group.getExamId(), group.getSubjectCode(), group.getNumber());
            markService.deleteGroup(group);
        } catch (Exception e) {
            log.error("delete group error", e);
            throw new RuntimeException("删除大题失败", e);
        } finally {
            lockService.unlock(LockType.GROUP, group.getExamId(), group.getSubjectCode(), group.getNumber());
        }

        redirectAttributes.addAttribute("subjectCode", subjectCode);
        redirectAttributes.addAttribute("number", number);
        return "redirect:/admin/exam/group";
    }

    @SuppressWarnings("unchecked")
    @RequestMapping("/save")
    @RoleRequire(Role.SCHOOL_ADMIN)
    @Transactional
    public String save(HttpServletRequest request, Model model, RedirectAttributes redirectAttributes,
            @RequestParam String subjectCode, @RequestParam Integer number, @RequestParam Boolean reset,
            @RequestParam(required = false) String picList, @RequestParam(required = false) Double doubleRate,
            @RequestParam(required = false) Double arbitrateThreshold,
            @RequestParam(required = false) Integer scorePolicy, @RequestParam(required = false) MarkMode markMode,
            @RequestParam(required = false) Integer trialCount, @RequestParam(required = false) boolean sheetView,
            @RequestParam(required = false) String questionDetail,
            @RequestParam(required = false) String intervalScoreList) {
        int examId = getSessionExamId(request);
        MarkGroup group = groupService.findOne(examId, subjectCode, number);
        if (group != null) {
            try {
                if (questionDetail != null && reset.booleanValue()) {
                    // advance update
                    questionDetail = StringEscapeUtils.unescapeHtml(questionDetail);
                    JSONArray array = JSONArray.fromObject(questionDetail);
                    List<ExamQuestionDTO> detailList = JSONArray.toList(array, new ExamQuestionDTO(), new JsonConfig());
                    List<ExamQuestion> all = questionService.findByExamAndSubjectAndObjective(examId, subjectCode, false);
                    List<ExamQuestion> old = questionService.findByExamAndSubjectAndObjectiveAndGroupNumber(examId,
                            subjectCode, false, number);
                    Set<Integer> mainNumbers = new HashSet<Integer>();
                    for (ExamQuestion examQuestion : all) {
                        mainNumbers.add(examQuestion.getMainNumber());
                    }
                    for (ExamQuestion examQuestion : old) {
                        mainNumbers.remove(examQuestion.getMainNumber());
                    }
                    for (int i = 0; i < detailList.size(); i++) {
                        ExamQuestionDTO dto = detailList.get(i);
                        if (mainNumbers.contains(dto.getMainNumber())) {
                            addMessage(redirectAttributes, "大题号不能重复");
                            redirectAttributes.addAttribute("subjectCode", subjectCode);
                            redirectAttributes.addAttribute("number", number);
                            return "redirect:/admin/exam/group/edit-full";
                        }
                        Object scoreListArray[] = array.getJSONObject(i).getJSONArray("scoreList").toArray();
                        List<Double> scoreList = new ArrayList<Double>();
                        for (int j = 0; j < scoreListArray.length; j++) {
                            scoreList.add(Double.parseDouble(scoreListArray[j].toString()));
                        }
                        dto.setScoreList(scoreList);
                    }
                    if (detailList != null && detailList.size() > 0) {
                        ScorePolicy policy = scorePolicy != null ? ScorePolicy.findByValue(scorePolicy) : null;
                        try {
                            lockService.waitlock(LockType.GROUP, true, group.getExamId(), group.getSubjectCode(),
                                    group.getNumber());
                            markService.updateGroup(group, buildQuestionList(group, detailList), policy);
                        } catch (Exception e) {
                            log.error("update group error", e);
                            throw new RuntimeException("重置更新大题失败", e);
                        } finally {
                            lockService.unlock(LockType.GROUP, true, group.getExamId(), group.getSubjectCode(),
                                    group.getNumber());
                        }
                    }
                } else {
                    // simple update
                    List<Double> intervalScores = buildDoubleList(intervalScoreList);
                    List<ExamQuestion> questionList = questionService.findByExamAndSubjectAndObjectiveAndGroupNumber(
                            examId, subjectCode, false, number);
                    if (intervalScores.size() == questionList.size()) {
                        for (int i = 0; i < questionList.size(); i++) {
                            ExamQuestion q = questionList.get(i);
                            q.setIntervalScore(intervalScores.get(i));
                            questionService.save(q);
                        }
                    }
                }
                // quick update
                picList = StringEscapeUtils.unescapeHtml(picList);
                JSONArray array = JSONArray.fromObject(picList);
                List<PictureConfigItem> list = JSONArray.toList(array, new PictureConfigItem(), new JsonConfig());
                if (list != null && !list.isEmpty()) {
                    groupService.updatePicList(examId, subjectCode, number, list);
                }
                if (doubleRate != null) {
                    groupService.updateDoubleRate(examId, subjectCode, number, doubleRate);
                }
                if (arbitrateThreshold != null) {
                    groupService.updateArbitrateThreshold(examId, subjectCode, number, arbitrateThreshold);
                }
                groupService.updateMarkMode(examId, subjectCode, number, markMode);
                if (trialCount != null && trialCount > 0 && group.getStatus() == MarkStatus.TRIAL) {
                    groupService.updateTrialCount(examId, subjectCode, number, trialCount);
                }
                groupService.updateSheetView(examId, subjectCode, number, sheetView);
                redirectAttributes.addAttribute("subjectCode", subjectCode);
                redirectAttributes.addAttribute("number", number);
                return "redirect:/admin/exam/group";
            
            } catch (Exception e) {
                log.error("edit markgroup error", e);
                addMessage(redirectAttributes, "参数有误");
                redirectAttributes.addAttribute("subjectCode", subjectCode);
                redirectAttributes.addAttribute("number", number);
                return "redirect:/admin/exam/group";
            }
        } else {
            addMessage(redirectAttributes, "找不到对应大题");
            redirectAttributes.addAttribute("subjectCode", subjectCode);
            redirectAttributes.addAttribute("number", number);
            return "redirect:/admin/exam/group";
        }
    }

    @SuppressWarnings("unchecked")
    @RequestMapping("/insert")
    @RoleRequire(Role.SCHOOL_ADMIN)
    @Transactional
    public String insert(HttpServletRequest request, Model model, RedirectAttributes redirectAttributes,
            @RequestParam String subjectCode, @RequestParam Integer number, @RequestParam String questionDetail,
            @RequestParam String picList, @RequestParam(required = false) Double doubleRate,
            @RequestParam(required = false) Double arbitrateThreshold,
            @RequestParam(required = false) Integer scorePolicy, @RequestParam(required = false) String markMode,
            @RequestParam(required = false) Integer trialCount, @RequestParam(required = false) boolean sheetView) {
        int examId = getSessionExamId(request);
        MarkGroup group = groupService.findOne(examId, subjectCode, number);
        if (group != null) {
            addMessage(redirectAttributes, "评卷分组序号不能重复");
            redirectAttributes.addAttribute("subjectCode", subjectCode);
            return "redirect:/admin/exam/group/add";
        } else if (StringUtils.isBlank(questionDetail)) {
            addMessage(redirectAttributes, "大题详情必须设置");
            redirectAttributes.addAttribute("subjectCode", subjectCode);
            return "redirect:/admin/exam/group/add";
        } else if (StringUtils.isBlank(picList)) {
            addMessage(redirectAttributes, "图片范围必须设置");
            redirectAttributes.addAttribute("subjectCode", subjectCode);
            return "redirect:/admin/exam/group/add";
        } else {
            try {
                // create group
                // build picList
                picList = StringEscapeUtils.unescapeHtml(picList);
                JSONArray array = JSONArray.fromObject(picList);
                List<PictureConfigItem> picConfigList = JSONArray.toList(array, new PictureConfigItem(), new JsonConfig());
                // build questionDetail
                questionDetail = StringEscapeUtils.unescapeHtml(questionDetail);
                array = JSONArray.fromObject(questionDetail);
                List<ExamQuestionDTO> detailList = JSONArray.toList(array, new ExamQuestionDTO(), new JsonConfig());
                for (int i = 0; i < detailList.size(); i++) {
                    ExamQuestionDTO dto = detailList.get(i);
                    Object o[] = array.getJSONObject(i).getJSONArray("scoreList").toArray();
                    List<Double> scoreList = new ArrayList<Double>();
                    for (int j = 0; j < o.length; j++) {
                        scoreList.add(Double.parseDouble(o[j].toString()));
                    }
                    dto.setScoreList(scoreList);
                }
                if (picConfigList != null && detailList != null && picConfigList.size() > 0 && detailList.size() > 0) {
                    for (ExamQuestionDTO detail : detailList) {
                        if (questionService.countByExamAndSubjectAndObjectiveAndMainNumber(examId, subjectCode, false,
                                detail.getMainNumber()) > 0) {
                            addMessage(redirectAttributes, "大题号不能重复");
                            redirectAttributes.addAttribute("subjectCode", subjectCode);
                            return "redirect:/admin/exam/group/add";
                        }
                    }
                    group = new MarkGroup(examId, subjectCode, number, picConfigList, 0d, doubleRate, arbitrateThreshold,
                            scorePolicy, markMode, trialCount, sheetView);
                    // clear and replace exam_question
                    questionService.deleteByExamAndSubjectAndObjectiveAndGroupNumber(examId, subjectCode, false, number);
                    List<ExamQuestion> list = buildQuestionList(group, detailList);
                    questionService.save(list);
                    groupService.save(group);
                    subjectService.updateScore(examId, subjectCode, false, groupService.sumTotalScore(examId, subjectCode));
                    redirectAttributes.addAttribute("subjectCode", subjectCode);
                    return "redirect:/admin/exam/group";
                } else {
                    addMessage(redirectAttributes, "参数有误");
                    redirectAttributes.addAttribute("subjectCode", subjectCode);
                    return "redirect:/admin/exam/group/add";
                }
            } catch (Exception e) {
                log.error("add markgroup error", e);
                addMessage(redirectAttributes, "参数有误");
                redirectAttributes.addAttribute("subjectCode", subjectCode);
                return "redirect:/admin/exam/group/add";
            }
        }
    }

    @RequestMapping("/getPictureConfig")
    @RoleRequire(Role.SCHOOL_ADMIN)
    public String get(HttpServletRequest request, Model model, RedirectAttributes redirectAttributes,
            @RequestParam String subjectCode, @RequestParam Integer number) {
        int examId = getSessionExamId(request);
        ExamStudentSearchQuery query = new ExamStudentSearchQuery();
        query.setExamId(examId);
        query.setSubjectCode(subjectCode);
        query.setUpload(true);
        List<ExamStudent> examStudents = studentService.findByQuery(query).getResult();
        MarkGroup group = null;
        if (number != null) {
            group = groupService.findOne(examId, subjectCode, number);
        }
        if (examStudents.size() > 0) {
            model.addAttribute("picUrls", buildPicUrl(examStudents.get(0)));
            model.addAttribute("pictureConfig", buildPictureConfig(group));
            model.addAttribute("imageServer", imageServer);
            return "modules/mark/picConfig";
        } else {
            addMessage(redirectAttributes, "参数有误");
            redirectAttributes.addAttribute("subjectCode", subjectCode);
            return "redirect:/admin/exam/group";
        }
    }

    private String buildPictureConfig(MarkGroup group) {
        String json = "";
        if (group != null) {
            try {
                ObjectMapper mapper = new ObjectMapper();
                json = mapper.writeValueAsString(group.getPictureConfigList());
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
        }
        return json;
    }

    private List<String> buildPicUrl(ExamStudent examStudent) {
        Campus campus = campusService.findBySchoolAndName(examStudent.getSchoolId(), examStudent.getCampusName());
        List<String> picUrls = PictureUrlBuilder.getSliceUrls(examStudent.getExamId(), campus.getId(),
                examStudent.getSubjectCode(), examStudent.getExamNumber(), examStudent.getSliceCount());
        return picUrls;
    }

    private List<ExamQuestion> buildQuestionList(MarkGroup group, List<ExamQuestionDTO> detailList) {
        List<ExamQuestion> list = new LinkedList<>();
        double totalScore = 0d;
        for (ExamQuestionDTO detail : detailList) {
            int i = 0;
            for (double score : detail.getScoreList()) {
                i++;
                totalScore += score;
                ExamQuestion question = new ExamQuestion();
                question.setExamId(group.getExamId());
                question.setSubjectCode(group.getSubjectCode());
                question.setMainTitle(detail.getMainTitle());
                question.setMainNumber(detail.getMainNumber());
                question.setSubNumber(i);
                question.setGroupNumber(group.getNumber());
                question.setObjective(false);
                question.setTotalScore(score);
                question.setIntervalScore(1d);
                list.add(question);
            }
        }
        group.setTotalScore(totalScore);
        return list;
    }

    private List<Double> buildDoubleList(String content) {
        List<Double> list = new ArrayList<Double>();
        content = StringUtils.trimToNull(content);
        if (content != null) {
            String[] values = StringUtils.split(content, ",");
            if (values != null) {
                for (String value : values) {
                    try {
                        Double number = Double.valueOf(value);
                        if (number != null) {
                            list.add(number);
                        }
                    } catch (Exception e) {
                        continue;
                    }
                }
            }
        }
        return list;
    }
}
