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

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

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.RequestParam;

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.model.MarkerDTO;
import cn.com.qmth.stmms.biz.exam.query.MarkerSearchQuery;
import cn.com.qmth.stmms.biz.exam.service.ExamSubjectService;
import cn.com.qmth.stmms.biz.exam.service.MarkerService;
import cn.com.qmth.stmms.biz.mark.model.MarkLibrary;
import cn.com.qmth.stmms.biz.mark.query.MarkLibrarySearchQuery;
import cn.com.qmth.stmms.biz.mark.service.MarkLibraryService;
import cn.com.qmth.stmms.common.enums.LibraryStatus;

@Controller("examMarkerInfoController")
@RequestMapping("/admin/exam-param/markerInfo")
public class ExamMarkerInfoController extends BaseParameterController {

    @Autowired
    private MarkerService markerService;

    @Autowired
    ExamSubjectService examSubjectService;

    @Autowired
    MarkLibraryService markLibraryService;

    @RequestMapping
    public String list(Model model, HttpServletRequest request, MarkerSearchQuery query) {
        int examId = getSessionExamId(request);
        if (examId > 0) {
            query.setExamId(examId);
            query = markerService.findByQuery(query);
            List<MarkerDTO> MarkerDTOs = new ArrayList<MarkerDTO>();
            for (Marker marker : query.getResult()) {
                MarkerDTO markerDTO = new MarkerDTO(marker);
                long markedCount = getMarkedCount(marker.getId(), LibraryStatus.MARKED);
                markerDTO.setMarkedCount(markedCount);
                if (!marker.isCommon()) {
                    markerDTO.setSubjectCount(1l);
                    markerDTO.setFinishedCount(markedCount > 0 ? 1l : 0l);
                } else {
                    markerDTO.setSubjectCount(getSubjectCountByExamId(marker.getExamId()));
                    markerDTO.setFinishedCount(
                            markedCount > 0 ? getCodeListByMidGBCodeCount(marker.getId(), LibraryStatus.MARKED) : 0l);
                }
                List<Object[]> list = markLibraryService.getMarkerInfo(marker.getId(), LibraryStatus.MARKED);
                double maxScore = (Double) list.get(0)[0] == null ? 0 : (Double) list.get(0)[0];
                markerDTO.setMaxScore(maxScore);
                double minScore = (Double) list.get(0)[1] == null ? 0 : (Double) list.get(0)[1];
                markerDTO.setMinScore(minScore);
                double avgScore = (Double) list.get(0)[2] == null ? 0 : (Double) list.get(0)[2];
                if (avgScore >= 0) {
                    markerDTO.setAvgScore(new BigDecimal(avgScore).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                }
                MarkerDTOs.add(markerDTO);
            }
            model.addAttribute("MarkerDTOs", MarkerDTOs);
            model.addAttribute("query", query);
            return "modules/exam/param/markerInfo";
        } else {
            return "redirect:/admin/exam/list";
        }
    }

    @RequestMapping("/detail")
    public String detail(Model model, HttpServletRequest request, MarkLibrarySearchQuery query,
            @RequestParam(required = false) Integer markerId) {
        int examId = getSessionExamId(request);
        if (examId > 0) {
            query.setStatus(LibraryStatus.MARKED);
            if (markerId != null) {
                query.setMarkerId(markerId);
            }
            List<ExamSubject> examSubjects = examSubjectService.findExamSubjectByMarkerId(examId, markerId,
                    LibraryStatus.MARKED);
            List<MarkerDTO> MarkerDTOs = new ArrayList<MarkerDTO>();
            if (examSubjects != null && examSubjects.size() > 0) {
                // query = markLibraryService.findGroupByQuery(query);
                query = markLibraryService.getByCondition(query);
                for (MarkLibrary markLibrary : query.getResult()) {
                    MarkerDTO markerDTO = new MarkerDTO();
                    markerDTO.setSubjectCode(markLibrary.getSubjectCode());
                    for (ExamSubject examSubject : examSubjects) {
                        if (markLibrary.getSubjectCode().equals(examSubject.getCode())) {
                            markerDTO.setSubjectName(examSubject.getName());
                        }
                    }
                    markerDTO.setMarkedCount(
                            getMarkedCountByCode(markerId, markLibrary.getSubjectCode(), LibraryStatus.MARKED));
                    // markerDTO.setRejectCount(getMarkedCountByCode(markerId,markLibrary.getSubjectCode(),LibraryStatus.BACKED));
                    MarkerDTOs.add(markerDTO);
                }
            }
            model.addAttribute("query", query);
            model.addAttribute("MarkerDTOs", MarkerDTOs);
            model.addAttribute("subjectList", examSubjects);
            return "modules/exam/param/markerDetail";
        } else {
            return "redirect:/admin/exam/list";
        }
    }

    public long getSubjectCountByExamId(int examId) {
        return examSubjectService.count(examId);
    }

    public long getMarkedCount(int markerId, LibraryStatus status) {
        return markLibraryService.countByMidAndStatus(markerId, status);
    }

    public long getMarkedCountByCode(int markerId, String subjectCode, LibraryStatus status) {
        return markLibraryService.countByMidAndSubjectCodeStatus(markerId, subjectCode, status);
    }

    public long getCodeListByMidGBCodeCount(int markerId, LibraryStatus status) {
        long count = 0;
        List<String> codes = markLibraryService.getCodeListByMidGBCodeCount(markerId, status);
        if (codes != null && codes.size() > 0) {
            count = codes.size();
        }
        return count;
    }
}
