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

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

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 org.springframework.web.servlet.mvc.support.RedirectAttributes;

import cn.com.qmth.stmms.biz.config.service.impl.SystemCache;
import cn.com.qmth.stmms.biz.exam.bean.ScoreVerifyInfo;
import cn.com.qmth.stmms.biz.exam.bean.ScoreVerifyVo;
import cn.com.qmth.stmms.biz.exam.model.Exam;
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.query.ScoreVerifyQuery;
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.ExamSubjectService;
import cn.com.qmth.stmms.biz.exam.service.ScoreVerifyService;
import cn.com.qmth.stmms.biz.exception.StatusException;
import cn.com.qmth.stmms.biz.file.service.FileService;
import cn.com.qmth.stmms.biz.mark.model.Task;
import cn.com.qmth.stmms.biz.mark.service.TaskService;
import cn.com.qmth.stmms.biz.school.model.School;
import cn.com.qmth.stmms.biz.school.service.SchoolService;
import cn.com.qmth.stmms.common.domain.WebUser;
import cn.com.qmth.stmms.common.enums.ExamType;
import cn.com.qmth.stmms.common.utils.ExportExcel;
import cn.com.qmth.stmms.common.utils.RequestUtils;
import net.sf.json.JSONObject;

@Controller("scoreVerifyController")
@RequestMapping("/admin/exam/score/verify")
public class ScoreVerifyController extends BaseExamController {

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

    @Autowired
    private ExamStudentService studentService;

    @Autowired
    private ScoreVerifyService scoreVerifyService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private FileService fileService;

    @Autowired
    private ExamService examService;

    @Autowired
    private SystemCache systemCache;

    @Autowired
    private SchoolService schoolService;

    @Autowired
    private ExamSubjectService subjectService;

    @RequestMapping(value = "reset")
    public String reset(Model model, HttpServletRequest request) {
        Integer examId = getSessionExamId(request);
        Exam exam = examService.findById(examId);
        if (ExamType.MULTI_MEDIA.equals(exam.getType())) {
            return "modules/exam/permission";
        }
        WebUser wu = RequestUtils.getWebUser(request);
        if (!scoreVerifyService.existByExamIdAndUserId(examId, wu.getId())) {
            model.addAttribute("errmsg", "没有数据需要重置");
            model.addAttribute("showType", "query");
            return "modules/exam/scoreVerify";
        } else {
            scoreVerifyService.reset(examId, wu.getId());
            model.addAttribute("showType", "query");
            return "modules/exam/scoreVerify";
        }
    }

    @RequestMapping(value = "init")
    public String init(Model model, HttpServletRequest request, ScoreVerifyQuery query) {
        Integer examId = getSessionExamId(request);
        Exam exam = examService.findById(examId);
        if (ExamType.MULTI_MEDIA.equals(exam.getType())) {
            return "modules/exam/permission";
        }
        WebUser wu = RequestUtils.getWebUser(request);
        query.setExamId(examId);
        query.setUserId(wu.getId());
        if (!scoreVerifyService.existByExamIdAndUserId(examId, wu.getId())) {
            model.addAttribute("showType", "query");
            return "modules/exam/scoreVerify";
        } else {
            model.addAttribute("fileServer", fileService.getFileServer());
            model.addAttribute("examType", exam.getType());
            return query(model, request, query);
        }
    }

    @RequestMapping(value = "page")
    public String page(Model model, HttpServletRequest request, ScoreVerifyQuery query) {
        Integer examId = getSessionExamId(request);
        Exam exam = examService.findById(examId);
        if (ExamType.MULTI_MEDIA.equals(exam.getType())) {
            return "modules/exam/permission";
        }
        WebUser wu = RequestUtils.getWebUser(request);
        query.setExamId(examId);
        query.setUserId(wu.getId());
        model.addAttribute("fileServer", fileService.getFileServer());
        model.addAttribute("examType", exam.getType());
        if (!scoreVerifyService.existByExamIdAndUserId(examId, wu.getId())) {
            return createAndQuery(model, request, query);
        } else {
            return query(model, request, query);
        }

    }

    private String createAndQuery(Model model, HttpServletRequest request, ScoreVerifyQuery query) {
        try {
            scoreVerifyService.createQuery(query);
            Integer totalCount = scoreVerifyService.countByQuery(query.getExamId(), query.getUserId());
            if (totalCount > 0) {
                List<ScoreVerifyVo> list = scoreVerifyService.findByQuery(query);
                Integer needVerifyCount = scoreVerifyService.needVerifyCount(query.getExamId(), query.getUserId());
                query.setResult(list);
                query.setTotalCount(totalCount);
                model.addAttribute("needVerifyCount", needVerifyCount);
            } else {
                query.setResult(new ArrayList<>());
                query.setTotalCount(0);
                model.addAttribute("needVerifyCount", 0);
            }
        } catch (StatusException e) {
            model.addAttribute("errmsg", e.getDesc());
            model.addAttribute("showType", "query");
            return "modules/exam/scoreVerify";
        }
        model.addAttribute("showType", "page");
        model.addAttribute("query", query);
        return "modules/exam/scoreVerify";
    }

    private String query(Model model, HttpServletRequest request, ScoreVerifyQuery query) {
        Integer totalCount = scoreVerifyService.countByQuery(query.getExamId(), query.getUserId());
        if (totalCount > 0) {
            List<ScoreVerifyVo> list = scoreVerifyService.findByQuery(query);
            Integer needVerifyCount = scoreVerifyService.needVerifyCount(query.getExamId(), query.getUserId());
            query.setResult(list);
            query.setTotalCount(totalCount);
            model.addAttribute("needVerifyCount", needVerifyCount);
        } else {
            query.setResult(new ArrayList<>());
            query.setTotalCount(0);
            model.addAttribute("needVerifyCount", 0);
        }
        model.addAttribute("query", query);
        model.addAttribute("showType", "page");
        return "modules/exam/scoreVerify";
    }

    @RequestMapping(value = "export", method = RequestMethod.POST)
    public String exportFile(HttpServletRequest request, HttpServletResponse response,
            RedirectAttributes redirectAttributes) {
        Integer examId = getSessionExamId(request);
        Exam exam = examService.findById(examId);
        if (ExamType.MULTI_MEDIA.equals(exam.getType())) {
            return "modules/exam/permission";
        }
        WebUser wu = RequestUtils.getWebUser(request);
        if (!scoreVerifyService.existByExamIdAndUserId(examId, wu.getId())) {
            addMessage(redirectAttributes, "没有数据需要导出");
            return "redirect:/admin/exam/score/verify/init";
        }
        try {
            List<ScoreVerifyVo> list = scoreVerifyService.findFlagged(examId, wu.getId());
            String fileName = "标记卷数据.xlsx";
            new ExportExcel("标记卷数据", ScoreVerifyVo.class).setDataList(list).write(response, fileName).dispose();
            return null;
        } catch (Exception e) {
            addErrMessage(redirectAttributes, e, "导出数据失败");
        }
        return "redirect:/admin/exam/score/verify/init";
    }

    @ResponseBody
    @RequestMapping(value = "needverify", method = RequestMethod.POST)
    public JSONObject needVerify(HttpServletRequest request) {
        Integer examId = getSessionExamId(request);
        WebUser wu = RequestUtils.getWebUser(request);
        JSONObject ret = new JSONObject();
        Exam exam = examService.findById(examId);
        ret.accumulate("examType", exam.getType());
        ret.accumulate("fileServer", fileService.getFileServer());
        School school = schoolService.findById(exam.getSchoolId());
        ret.accumulate("doubleTrack", systemCache.isDoubleTrack() && school.isDoubleTrack());
        if (!scoreVerifyService.existByExamIdAndUserId(examId, wu.getId())) {
            return ret;
        }
        List<ScoreVerifyVo> temlist = scoreVerifyService.needVerify(examId, wu.getId());
        if (temlist == null || temlist.size() == 0) {
            return ret;
        }
        List<Integer> list = temlist.stream().map(e -> e.getStudentId()).collect(Collectors.toList());
        ret.accumulate("studentIds", list);
        return ret;
    }

    @RequestMapping("info")
    @ResponseBody
    public ScoreVerifyInfo info(HttpServletRequest request, @RequestParam Integer studentId) {
        ExamStudent student = studentService.findById(studentId);
        ScoreVerifyInfo info = new ScoreVerifyInfo();
        if (student != null) {
            Task task = taskService.build(student);
            info.setTask(task);
            info.setFlagged(student.getScoreVerifyFlagged());
            int examId = getSessionExamId(request);
            ExamSubject examSubject = subjectService.find(examId, student.getSubjectCode());
            examSubject.setPaperAnswerUrl(fileService);
            info.setPaperUrl(examSubject.getPaperUrl() == null ? "" : examSubject.getPaperUrl());
            WebUser wu = RequestUtils.getWebUser(request);
            scoreVerifyService.view(examId, wu.getId(), studentId);
        }
        return info;
    }

    @RequestMapping("tag")
    @ResponseBody
    public Object tag(HttpServletRequest request, @RequestParam Integer studentId, @RequestParam boolean isTag) {
        ExamStudent student = studentService.findById(studentId);
        JSONObject obj = new JSONObject();
        if (student != null) {
            int examId = getSessionExamId(request);
            WebUser wu = RequestUtils.getWebUser(request);
            scoreVerifyService.tag(examId, wu.getId(), studentId, isTag);
            obj.accumulate("success", true);
        } else {
            obj.accumulate("success", false);
            obj.accumulate("message", "无法标记，请刷新页面");
        }
        return obj;
    }
}
