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

import cn.com.qmth.stmms.admin.dto.ExceptionQuestionDTO;
import cn.com.qmth.stmms.admin.thread.ScoreCheckThread;
import cn.com.qmth.stmms.biz.exam.model.ExamQuestion;
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.query.ExamQuestionSearchQuery;
import cn.com.qmth.stmms.common.annotation.RoleRequire;
import cn.com.qmth.stmms.common.domain.WebUser;
import cn.com.qmth.stmms.common.enums.Role;
import cn.com.qmth.stmms.common.utils.ExportExcel;
import cn.com.qmth.stmms.common.utils.RequestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

@Controller
@RequestMapping("/admin/exam/check/score")
public class ScoreCheckController extends BaseExamController {

    @Autowired
    private ExamStudentService studentService;

    @Autowired
    private ExamQuestionService questionService;

    @Autowired
    private ExamSubjectService subjectService;

    @Qualifier("task-executor")
    @Autowired
    private AsyncTaskExecutor taskExecutor;

    private AtomicBoolean running = new AtomicBoolean(false);

    @RequestMapping
    public ModelAndView list(HttpServletRequest request, ExamQuestionSearchQuery query) {
        WebUser wu = RequestUtils.getWebUser(request);
        int examId = getSessionExamId(request);
        ModelAndView view = new ModelAndView("modules/exam/checkScore");
        query.setExamId(examId);
        query.setTotalScoreGt(0d);
        query.setTotalCountGt(0);
        query.orderBySubjectAndNumber();
        if (query.getZeroRateGt() == null) {
            query.setZeroRateGt(1.0);
        }
        query = questionService.findByQuery(query);

        for (ExamQuestion q : query.getResult()) {
            q.setSubject((subjectService.find(q.getExamId(), q.getSubjectCode())));
        }

        view.addObject("query", query);
        view.addObject("subjectList", getExamSubject(examId, wu));
        view.addObject("running", running.get());
        return view;
    }

    @RequestMapping("/run")
    @RoleRequire(Role.SCHOOL_ADMIN)
    public ModelAndView checkScore(HttpServletRequest request) {
        int examId = getSessionExamId(request);
        if (running.compareAndSet(false, true) == true) {
            ScoreCheckThread thread = new ScoreCheckThread(examId, running, studentService, questionService);
            taskExecutor.submit(thread);
        }
        return new ModelAndView("redirect:/admin/exam/check/score");
    }

    @RequestMapping("/export")
    public String export(ExamQuestionSearchQuery query, HttpServletRequest request, HttpServletResponse response,
            RedirectAttributes redirectAttributes) {
        int examId = getSessionExamId(request);
        List<ExceptionQuestionDTO> list = new LinkedList<ExceptionQuestionDTO>();
        query.setExamId(examId);
        query.setTotalCountGt(0);
        query.orderBySubjectAndNumber();
        query.setPageNumber(1);
        query.setPageSize(Integer.MAX_VALUE);
        query = questionService.findByQuery(query);
        for (ExamQuestion question : query.getResult()) {
            if (question.getTotalScore() > 0) {
                ExceptionQuestionDTO dto = new ExceptionQuestionDTO(question, subjectService.find(question.getExamId(),
                        question.getSubjectCode()));
                list.add(dto);
            }
        }
        String fileName = "异常试题.xlsx";
        try {
            new ExportExcel("异常试题", ExceptionQuestionDTO.class).setDataList(list).write(response, fileName).dispose();
            return null;
        } catch (Exception e) {
            addMessage(redirectAttributes, "导出失败！" + e.getMessage());
            return "redirect:/admin/exam/check/score";
        }
    }
}
