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

import java.text.DecimalFormat;
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.apache.commons.lang.StringUtils;
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.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.com.qmth.stmms.biz.exam.model.Exam;
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.model.Marker;
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.ExamStudentService;
import cn.com.qmth.stmms.biz.exam.service.MarkGroupService;
import cn.com.qmth.stmms.biz.exam.service.MarkerService;
import cn.com.qmth.stmms.biz.file.enums.FormatType;
import cn.com.qmth.stmms.biz.file.service.FileService;
import cn.com.qmth.stmms.biz.lock.LockService;
import cn.com.qmth.stmms.biz.mark.model.TrialLibrary;
import cn.com.qmth.stmms.biz.mark.query.TrialLibrarySearchQuery;
import cn.com.qmth.stmms.biz.mark.service.MarkService;
import cn.com.qmth.stmms.biz.mark.service.TrialService;
import cn.com.qmth.stmms.biz.user.model.User;
import cn.com.qmth.stmms.biz.user.service.UserService;
import cn.com.qmth.stmms.common.annotation.Logging;
import cn.com.qmth.stmms.common.annotation.RoleRequire;
import cn.com.qmth.stmms.common.domain.WebUser;
import cn.com.qmth.stmms.common.enums.ExamType;
import cn.com.qmth.stmms.common.enums.LibraryStatus;
import cn.com.qmth.stmms.common.enums.LockType;
import cn.com.qmth.stmms.common.enums.LogType;
import cn.com.qmth.stmms.common.enums.MarkStatus;
import cn.com.qmth.stmms.common.enums.Role;
import cn.com.qmth.stmms.common.utils.DateUtils;
import cn.com.qmth.stmms.common.utils.RequestUtils;

@Controller("trialController")
@RequestMapping("/admin/exam/trial")
public class TrialController extends BaseExamController {

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

    @Autowired
    private ExamStudentService studentService;

    @Autowired
    private MarkGroupService groupService;

    @Autowired
    private TrialService trialService;

    @Autowired
    private MarkService markService;

    @Autowired
    private MarkerService markerService;

    @Autowired
    private LockService lockService;

    @Autowired
    private ExamQuestionService questionService;

    @Autowired
    private ExamService examService;

    @Autowired
    private UserService userService;

    @Autowired
    private FileService fileService;

    @Logging(menu = "试评管理查询", type = LogType.QUERY)
    @RequestMapping
    public String list(Model model, HttpServletRequest request, TrialLibrarySearchQuery query,
            @RequestParam(required = false) LibraryStatus status) {
        int examId = getSessionExamId(request);
        WebUser wu = RequestUtils.getWebUser(request);
        List<ExamSubject> subjectList = getExamSubject(examId, wu);
        if (subjectList.isEmpty()) {
            return "redirect:/admin/exam/mark";
        }
        query.setExamId(examId);
        if (StringUtils.isBlank(query.getSubjectCode()) && !subjectList.isEmpty()) {
            query.setSubjectCode(subjectList.get(0).getCode());
        }
        List<MarkGroup> groupList = groupService.findByExamAndSubjectAndStatus(examId, query.getSubjectCode(),
                MarkStatus.TRIAL);
        if (!groupList.isEmpty()) {
            query = trialService.findLibrary(query);
            for (TrialLibrary library : query.getResult()) {
                if (library.getMarkerId() != null) {
                    Marker marker = markerService.findById(library.getMarkerId());
                    library.setMarkerLoginName(userService.findById(marker.getUserId()).getLoginName());
                }
            }
            for (MarkGroup group : groupList) {
                group.setQuestionList(questionService.findByExamAndSubjectAndObjectiveAndGroupNumber(examId,
                        group.getSubjectCode(), false, group.getNumber()));
            }
        }
        model.addAttribute("query", query);
        model.addAttribute("subjectList", getExamSubject(examId, wu));
        model.addAttribute("groupList", groupList);
        return "modules/exam/trialList";
    }

    @Logging(menu = "重置试评任务", type = LogType.UPDATE)
    @RequestMapping(value = "/reset", method = RequestMethod.POST)
    @ResponseBody
    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
    public JSONObject reset(HttpServletRequest request, @RequestParam Integer libraryId) {
        JSONObject obj = new JSONObject();
        int examId = getSessionExamId(request);
        TrialLibrary library = trialService.findById(libraryId);
        if (library != null) {
            if (library.getExamId().equals(examId)
                    && subjectCheck(library.getSubjectCode(), RequestUtils.getWebUser(request))) {
                try {
                    lockService.watch(LockType.GROUP, library.getExamId(), library.getSubjectCode(),
                            library.getGroupNumber());
                    lockService.waitlock(LockType.TRIAL_LIBRARY, library.getId());
                    if (markService.resetLibrary(library)) {
                        obj.accumulate("success", true);
                    } else {
                        obj.accumulate("success", false);
                        obj.accumulate("message", "无法打回该评卷任务");
                    }
                } catch (Exception e) {
                    log.error("back trial library error", e);
                    obj.accumulate("success", false);
                    obj.accumulate("message", "无法打回该评卷任务");
                } finally {
                    lockService.unlock(LockType.TRIAL_LIBRARY, library.getId());
                    lockService.unwatch(LockType.GROUP, library.getExamId(), library.getSubjectCode(),
                            library.getGroupNumber());
                }
            } else {
                obj.accumulate("success", false);
                obj.accumulate("message", "没有操作该评卷任务的权限");
            }
        } else {
            obj.accumulate("success", false);
            obj.accumulate("message", "该评卷任务不存在");
        }
        return obj;
    }

    @Logging(menu = "试评详情", type = LogType.QUERY)
    @RequestMapping(value = "/detail")
    @ResponseBody
    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
    public JSONObject detail(HttpServletRequest request, @RequestParam Integer libraryId) {
        JSONObject obj = new JSONObject();
        TrialLibrary library = trialService.findById(libraryId);
        Exam exam = examService.findById(library.getExamId());
        if (library != null) {
            ExamStudent student = studentService.findById(library.getStudentId());
            MarkGroup group = groupService.findOne(library.getExamId(), library.getSubjectCode(),
                    library.getGroupNumber());
            if (group != null && student != null) {
                obj.accumulate("success", true);
                if (ExamType.MULTI_MEDIA.equals(exam.getType())) {
                    // 多媒体配置
                    obj.accumulate("fileServer", fileService.getFileServer());
                    obj.accumulate("urls", fileService.getJsonUri(student.getExamId(), student.getSecretNumber()));
                    obj.accumulate("paperUrl",
                            fileService.getPaperUri(student.getExamId(), student.getSubjectCode(), FormatType.JSON));
                    List<ExamQuestion> questions = questionService.findByExamAndSubjectAndObjectiveAndGroupNumber(
                            library.getExamId(), student.getSubjectCode(), false, group.getNumber());
                    List<String> strings = new ArrayList<String>();
                    for (ExamQuestion examQuestion : questions) {
                        strings.add(examQuestion.getQuestionNumber());
                    }
                    String questionNumbers = String.join(",", strings);
                    obj.accumulate("questionNumbers", questionNumbers);
                } else {
                    // 裁切图配置
                    obj.accumulate("fileServer", fileService.getFileServer());
                    obj.accumulate(
                            "urls",
                            fileService.getSliceUris(student.getExamId(), student.getSecretNumber(), 1,
                                    student.getSliceCount()));
                    obj.accumulate("pictureConfig", group.getPictureConfigList());
                }
                // 评卷记录集合
                JSONArray array = new JSONArray();
                DecimalFormat format = new DecimalFormat("####.###");
                if (library.getMarkerId() != null) {
                    Marker marker = markerService.findById(library.getMarkerId());
                    User user = userService.findById(marker.getUserId());
                    JSONObject item = new JSONObject();
                    item.accumulate("loginName", marker != null ? user.getLoginName() : "");
                    item.accumulate("name", marker != null ? user.getName() : "");
                    item.accumulate("score", format.format(library.getMarkerScore()));
                    item.accumulate("time", DateUtils.formatDateTime(library.getMarkerTime()));
                    array.add(item);
                }
                obj.accumulate("historyList", array);
            }
        }
        return obj;
    }

}
