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

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

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

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
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.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import cn.com.qmth.stmms.admin.dto.MarkInfoDTO;
import cn.com.qmth.stmms.admin.dto.MarkerInfoDTO;
import cn.com.qmth.stmms.admin.exam.parameter.BaseParameterController;
import cn.com.qmth.stmms.admin.vo.SubjectLibraryVO;
import cn.com.qmth.stmms.biz.exam.model.ExamSubject;
import cn.com.qmth.stmms.biz.exam.model.Marker;
import cn.com.qmth.stmms.biz.exam.service.ExamSubjectService;
import cn.com.qmth.stmms.biz.exam.service.MarkerService;
import cn.com.qmth.stmms.biz.exam.service.query.ExamSubjectSearchQuery;
import cn.com.qmth.stmms.biz.mark.query.MarkLibrarySearchQuery;
import cn.com.qmth.stmms.biz.mark.service.MarkLibraryService;
import cn.com.qmth.stmms.biz.mark.service.TaskService;
import cn.com.qmth.stmms.common.enums.ExamSubjectStatus;
import cn.com.qmth.stmms.common.enums.LibraryStatus;
import cn.com.qmth.stmms.common.utils.DateUtils;
import cn.com.qmth.stmms.common.utils.ExportExcel;
import cn.com.qmth.stmms.common.utils.RequestUtils;

@Controller("markInfoController")
@RequestMapping("/admin/exam/mark")
public class MarkController extends BaseParameterController {

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

    @Autowired
    private ExamSubjectService subjectService;

    @Autowired
    private MarkLibraryService libraryService;

    @Autowired
    private MarkerService markerService;

    @Autowired
    private TaskService taskService;

    /**
     * 评卷进度
     * 
     * @param request
     * @param model
     * @param query
     * @return
     */
    @RequestMapping
    public String progress(HttpServletRequest request, Model model, ExamSubjectSearchQuery query,
            @RequestParam(required = false) String sortField, @RequestParam(required = false) Boolean sortOrder) {
        int examId = getSessionExamId(request);
        String subjectCode = RequestUtils.getSession(request).getParameter("subjectCode");
        if (examId > 0) {
            query.setExamId(examId);
            if(subjectCode!=null){
            	query.setCode(subjectCode);
            }
            query.setSubjectiveScoreNotEqual(0d);
            query.setLibraryCountGt(0);
            if (StringUtils.isNotBlank(sortField) && sortOrder != null) {
                query.setSort(new Sort(sortOrder.booleanValue() ? Direction.ASC : Direction.DESC, sortField));
            }
            query = subjectService.findByQuery(query);

            List<SubjectLibraryVO> list = new LinkedList<SubjectLibraryVO>();
            for (ExamSubject subject : query.getResult()) {
                SubjectLibraryVO vo = new SubjectLibraryVO();
                vo.setSubject(subject);
                vo.setTotalCount(subject.getLibraryCount());
                vo.setMarkedCount(subject.getMarkedCount());
                int percent = subject.getLibraryCount() > 0 ? (int) (subject.getMarkedCount() * 100.00 / subject.getLibraryCount()) : 0;
                vo.setLeftCount(subject.getLeftCount());
                vo.setCurrentCount(taskService.countCurrent(examId, subject.getCode()));
                vo.setPercent(percent);
                list.add(vo);
            }

            long total = subjectService.sumLibraryCount(examId, 0, 0);
            long finish = libraryService.countByExamAndStatus(examId, LibraryStatus.MARKED);
            int percent = total > 0 ? (int) (finish * 100.00 / total) : 0;
            model.addAttribute("percent", percent);

            model.addAttribute("resultList", list);
            model.addAttribute("query", query);
            model.addAttribute("sortField", sortField);
            model.addAttribute("sortOrder", sortOrder);
            model.addAttribute("subjectList", getMarkExamSubject(examId));
            model.addAttribute("levelList", subjectService.listLevel(examId));
            model.addAttribute("categoryList", subjectService.listCategory(examId));
            return "modules/exam/markInfo";
        }
        return "redirect:/admin/exam/list";
    }

    @RequestMapping("/toggle")
    public ModelAndView toggle(HttpServletRequest request, @RequestParam String subjectCode,
            @RequestParam boolean enable, @RequestParam(required = false) Integer pageNumber) {
        int examId = getSessionExamId(request);
        if (examId > 0) {
            ModelAndView view = new ModelAndView("redirect:/admin/exam/mark");
            ExamSubject subject = subjectService.find(examId, subjectCode);
            if (subject != null) {
                if (enable) {
                    subject.setStatus(ExamSubjectStatus.MARKING);
                } else {
                    subject.setStatus(ExamSubjectStatus.PAUSE);
                }
                subjectService.save(subject);
            }
            if (pageNumber != null) {
                view.addObject("pageNumber", pageNumber);
            }
            return view;
        } else {
            return new ModelAndView("redirect:/admin/exam/list");
        }
    }

    @RequestMapping("/release")
    public ModelAndView release(HttpServletRequest request, @RequestParam String subjectCode,
            @RequestParam(required = false) Integer pageNumber) {
        int examId = getSessionExamId(request);
        if (examId > 0) {
            ModelAndView view = new ModelAndView("redirect:/admin/exam/mark");
            ExamSubject subject = subjectService.find(examId, subjectCode);
            if (subject != null) {
                taskService.clearCurrent(examId, subject.getCode());
            }
            if (pageNumber != null) {
                view.addObject("pageNumber", pageNumber);
            }
            return view;
        } else {
            return new ModelAndView("redirect:/admin/exam/list");
        }
    }

    @RequestMapping("/reset")
    public ModelAndView reset(HttpServletRequest request, @RequestParam(required = false) String subjectCode,
            @RequestParam(required = false) Integer pageNumber) {
        int examId = getSessionExamId(request);
        if (examId > 0) {
            ModelAndView view = new ModelAndView("redirect:/admin/exam/mark");
            if (subjectCode != null) {
                ExamSubject subject = subjectService.find(examId, subjectCode);
                if (subject != null) {
                    int libraryCount = (int) libraryService.countByExamAndSubject(subject.getExamId(),
                            subject.getCode());
                    subjectService.updateLibraryCount(subject.getExamId(), subject.getCode(), libraryCount);
                    subjectService.updateMarkedCount(subject.getExamId(), subject.getCode(), 0);
                    libraryService.resetBySubject(subject);
                    taskService.clearCurrent(examId, subject.getCode());
                }
            } else {
                List<ExamSubject> list = getMarkExamSubject(examId);
                for (ExamSubject subject : list) {
                    int libraryCount = (int) libraryService.countByExamAndSubject(subject.getExamId(),
                            subject.getCode());
                    subjectService.updateLibraryCount(subject.getExamId(), subject.getCode(), libraryCount);
                    subjectService.updateMarkedCount(subject.getExamId(), subject.getCode(), 0);
                    libraryService.resetBySubject(subject);
                    taskService.clearCurrent(examId, subject.getCode());
                }
            }
            if (pageNumber != null) {
                view.addObject("pageNumber", pageNumber);
            }
            return view;
        } else {
            return new ModelAndView("redirect:/admin/exam/list");
        }
    }

    @RequestMapping(value = "/export", method = RequestMethod.POST)
    public String export(HttpServletRequest request, HttpServletResponse response,
            RedirectAttributes redirectAttributes) {
        int examId = getSessionExamId(request);
        if (examId > 0) {
            List<MarkInfoDTO> result = new LinkedList<MarkInfoDTO>();
            String subjectCode = RequestUtils.getSession(request).getParameter("subjectCode");
            List<ExamSubject> list = new ArrayList<ExamSubject>();
            if(subjectCode!=null){//科组长
            	list.add(subjectService.find(examId, subjectCode));
            }else{
            	list = getMarkExamSubject(examId);
            }
            for (ExamSubject subject : list) {
                if (subject.getLibraryCount() > 0) {
                    MarkInfoDTO dto = new MarkInfoDTO(subject);
                    dto.setTotalCount(subject.getLibraryCount());

                    MarkLibrarySearchQuery query = new MarkLibrarySearchQuery();
                    query.setExamId(examId);
                    query.setSubjectCode(subject.getCode());
                    query.setStatus(LibraryStatus.WAITING);
                    dto.setLeftCount(libraryService.countByQuery(query));
                    result.add(dto);
                }
            }

            try {
                String fileName = "评卷进度" + DateUtils.getDate("yyyyMMdd") + ".xlsx";
                new ExportExcel("评卷进度", MarkInfoDTO.class).setDataList(result).write(response, fileName).dispose();
                return null;
            } catch (Exception e) {
                addMessage(redirectAttributes, "导出评卷进度失败！" + e.getMessage());
                return "redirect:/admin/exam/mark";
            }
        } else {
            return "redirect:/admin/exam/list";
        }
    }

    @RequestMapping(value = "/export-marker", method = RequestMethod.POST)
    public String exportMarker(HttpServletRequest request, HttpServletResponse response,
            RedirectAttributes redirectAttributes) {
        int examId = getSessionExamId(request);
        if (examId > 0) {
            List<MarkerInfoDTO> result = new LinkedList<MarkerInfoDTO>();
            String subjectCode = RequestUtils.getSession(request).getParameter("subjectCode");
            List<Marker> list = null;
            if(subjectCode!=null){//科组长
            	list = markerService.findByExamAndSubject(examId, subjectCode);
            }else{
            	list = markerService.getMarkCount(examId);
            }
            for (Marker marker : list) {
                MarkerInfoDTO dto = new MarkerInfoDTO(marker,
                        subjectService.find(marker.getExamId(), marker.getSubjectCode()));
                result.add(dto);
            }

            try {
                String fileName = "评卷员工作量" + DateUtils.getDate("yyyyMMdd") + ".xlsx";
                new ExportExcel("评卷员工作量", MarkerInfoDTO.class).setDataList(result).write(response, fileName).dispose();
                return null;
            } catch (Exception e) {
                addMessage(redirectAttributes, "导出评卷员工作量失败！" + e.getMessage());
                return "redirect:/admin/exam/mark";
            }
        } else {
            return "redirect:/admin/exam/list";
        }
    }

    @RequestMapping(value = "/check-count")
    public String checkCount(HttpServletRequest request, HttpServletResponse response,
            RedirectAttributes redirectAttributes) {
        int examId = getSessionExamId(request);
        if (examId > 0) {
            subjectService.updateLibraryCount(examId);
            subjectService.updateMarkedCount(examId);
            subjectService.updateLeftCount(examId);
            return "redirect:/admin/exam/mark";
        } else {
            return "redirect:/admin/exam/list";
        }
    }
}
