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

import cn.com.qmth.stmms.admin.utils.PageUtil;
import cn.com.qmth.stmms.admin.vo.ScanInfoVO;
import cn.com.qmth.stmms.biz.exam.model.ExamPackage;
import cn.com.qmth.stmms.biz.exam.model.ExamSubject;
import cn.com.qmth.stmms.biz.exam.query.ExamPackageSearchQuery;
import cn.com.qmth.stmms.biz.exam.query.ExamStudentSearchQuery;
import cn.com.qmth.stmms.biz.exam.service.ExamPackageService;
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.ExamSubjectSearchQuery;
import cn.com.qmth.stmms.biz.file.service.FileService;
import cn.com.qmth.stmms.common.annotation.Logging;
import cn.com.qmth.stmms.common.domain.WebUser;
import cn.com.qmth.stmms.common.enums.LogType;
import cn.com.qmth.stmms.common.utils.ExportExcel;
import cn.com.qmth.stmms.common.utils.RequestUtils;

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

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

import java.math.BigDecimal;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

@Controller("scanInfoController")
@RequestMapping("/admin/exam/scan")
public class ScanController extends BaseExamController {

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

    @Autowired
    private ExamStudentService studentService;

    @Autowired
    private ExamSubjectService subjectService;

    @Autowired
    private ExamPackageService packageService;

    @Autowired
    private FileService fileService;

    /**
     * 按科目统计扫描进度
     *
     * @param request
     * @param model
     * @param query
     * @return
     */
    @Logging(menu = "扫描进度-按科目查询", type = LogType.QUERY)
    @RequestMapping(value = { "", "/subject" })
    public ModelAndView progress(HttpServletRequest request, Model model, ExamSubjectSearchQuery query) {
        WebUser wu = RequestUtils.getWebUser(request);
        int examId = getSessionExamId(request);
        List<ScanInfoVO> list = new LinkedList<ScanInfoVO>();
        query.setExamId(examId);
        query = subjectService.findByQuery(query);
        for (ExamSubject subject : query.getResult()) {
            ScanInfoVO vo = new ScanInfoVO();
            vo.setName(subject.getCode()
                    + "-"
                    + subject.getName()
                    + (StringUtils.isNotBlank(subject.getRemark()) ? ("-" + StringUtils.trimToEmpty(subject.getRemark()))
                            : ""));
            vo.setTotalCount(studentService.countByExamIdAndSubjectCode(examId, subject.getCode()));
            vo.setScanCount(subject.getUploadCount());
            long sheetCount = studentService.countSheetCountByExamIdAndSubjectCode(examId, subject.getCode());
            long sheetCount2 = new BigDecimal(sheetCount).divide(new BigDecimal(2), 0, BigDecimal.ROUND_HALF_UP)
                    .longValue();
            vo.setScanSheetCount(sheetCount2);
            list.add(vo);
        }

        ModelAndView view = new ModelAndView("modules/exam/scanInfo");
        view.addObject("subjectList", getExamSubject(examId, wu));
        view.addObject("levelList", subjectService.listLevel(examId));
        view.addObject("categoryList", subjectService.listCategory(examId));
        view.addObject("infoList", list);
        view.addObject("query", query);
        view.addObject("type", "subject");
        return view;
    }

    /**
     * 按学习中心统计扫描进度
     *
     * @param request
     * @param query
     * @return
     */
    @Logging(menu = "扫描进度-按学习中心查询", type = LogType.QUERY)
    @RequestMapping("/campus")
    public ModelAndView campus(HttpServletRequest request, ExamStudentSearchQuery query) {
        int examId = getSessionExamId(request);
        List<ScanInfoVO> list = new LinkedList<ScanInfoVO>();
        if (StringUtils.isBlank(query.getCampusName())) {
            List<String> campusList = studentService.findDistinctCampusName(examId);
            for (String campus : campusList) {
                ScanInfoVO vo = new ScanInfoVO();
                vo.setName(campus);
                vo.setTotalCount(studentService.countByExamIdAndCampusName(examId, campus));
                vo.setScanCount(studentService.countByExamIdAndCampusName(examId, campus, true));
                list.add(vo);
            }
        } else {
            ScanInfoVO vo = new ScanInfoVO();
            vo.setName(query.getCampusName());
            vo.setTotalCount(studentService.countByExamIdAndCampusName(examId, query.getCampusName()));
            vo.setScanCount(studentService.countByExamIdAndCampusName(examId, query.getCampusName(), true));
            list.add(vo);

            query.setTotalCount(1);
            query.setTotalPage(1);
            query.setCurrentCount(1);
        }

        ModelAndView view = new ModelAndView("modules/exam/scanInfo");
        view.addObject("campusList", studentService.findDistinctCampusName(examId));
        view.addObject("infoList", list);
        view.addObject("query", query);
        view.addObject("type", "campus");
        return view;
    }

    /**
     * 统计签到表扫描进度
     *
     * @param request
     * @return
     */
    @Logging(menu = "扫描进度-按签到表查询", type = LogType.QUERY)
    @RequestMapping("/package")
    public ModelAndView packageProgress(HttpServletRequest request, ExamPackageSearchQuery query) {
        int examId = getSessionExamId(request);
        query.setExamId(examId);
        query = packageService.findByQuery(query);
        for (ExamPackage ep : query.getResult()) {
            ep.setUrls(fileService.getPackageUris(ep.getExamId(), ep.getCode(), 1, ep.getPicCount()));
        }
        ModelAndView view = new ModelAndView("modules/exam/scanPackage");
        view.addObject("packageList", query.getResult());
        view.addObject("query", query);
        view.addObject("totalCount", packageService.sumByExam(examId));
        view.addObject("fileServer", fileService.getFileServer());
        return view;
    }

    @Logging(menu = "扫描进度导出", type = LogType.EXPORT)
    @RequestMapping(value = "/subject/export", method = RequestMethod.POST)
    public String export(ExamSubjectSearchQuery query, HttpServletRequest request, HttpServletResponse response,
            RedirectAttributes redirectAttributes) {
        int examId = getSessionExamId(request);
        List<ScanInfoVO> list = new LinkedList<ScanInfoVO>();
        query.setExamId(examId);
        query.setPageNumber(1);
        query.setPageSize(Integer.MAX_VALUE);
        query = subjectService.findByQuery(query);
        for (ExamSubject subject : query.getResult()) {
            ScanInfoVO vo = new ScanInfoVO();
            vo.setName(subject.getCode()
                    + "-"
                    + subject.getName()
                    + (StringUtils.isNotBlank(subject.getRemark()) ? ("-" + StringUtils.trimToEmpty(subject.getRemark()))
                            : ""));
            vo.setTotalCount(studentService.countByExamIdAndSubjectCode(examId, subject.getCode()));
            vo.setScanCount(studentService.countByExamIdAndSubjectCode(examId, subject.getCode(), true));
            vo.setScanSheetCount(studentService.countSheetCountByExamIdAndSubjectCode(examId, subject.getCode()) / 2);
            list.add(vo);
        }
        try {
            String fileName = "扫描进度.xlsx";
            new ExportExcel("扫描进度", ScanInfoVO.class).setDataList(list).write(response, fileName).dispose();
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            addMessage(redirectAttributes, "导出扫描进度失败！" + e.getMessage());
            return "redirect:/admin/exam/scan/subject";
        }
    }

    @Logging(menu = "扫描进度-按考点查询", type = LogType.QUERY)
    @RequestMapping("/examSite")
    public ModelAndView examSite(HttpServletRequest request, ExamStudentSearchQuery query) {
        int examId = getSessionExamId(request);
        List<ScanInfoVO> list = new LinkedList<ScanInfoVO>();
        List<String> result = studentService.findDistinctExamSite(examId);
        result = result.stream().filter(s -> StringUtils.isNotBlank(s)).collect(Collectors.toList());
        if (StringUtils.isBlank(query.getExamSite())) {
            List<?> examSiteList = PageUtil.startPage(result, query.getPageNumber(), query.getPageSize());
            for (Object e : examSiteList) {
                ScanInfoVO vo = new ScanInfoVO();
                String examSite = (String) e;
                vo.setName(examSite);
                vo.setTotalCount(studentService.countByExamIdAndExamSite(examId, examSite));
                vo.setScanCount(studentService.countByExamIdAndExamSite(examId, examSite, true));
                vo.setScanSheetCount(studentService.countSheetCountByExamIdAndExamSite(examId, examSite) / 2);
                list.add(vo);
            }
            query.setTotalCount(result.size());
            query.setTotalPage(PageUtil.pageCount(result, query.getPageNumber(), query.getPageSize()));
            query.setCurrentCount(examSiteList.size());
        } else {
            ScanInfoVO vo = new ScanInfoVO();
            vo.setName(query.getExamSite());
            vo.setTotalCount(studentService.countByExamIdAndExamSite(examId, query.getExamSite()));
            vo.setScanCount(studentService.countByExamIdAndExamSite(examId, query.getExamSite(), true));
            vo.setScanSheetCount(studentService.countSheetCountByExamIdAndExamSite(examId, query.getExamSite()) / 2);
            list.add(vo);

            query.setTotalCount(1);
            query.setTotalPage(1);
            query.setCurrentCount(1);
        }

        ModelAndView view = new ModelAndView("modules/exam/scanInfo");
        view.addObject("examSiteList", result);
        view.addObject("infoList", list);
        view.addObject("query", query);
        view.addObject("type", "examSite");
        return view;
    }

    @Logging(menu = "扫描进度导出", type = LogType.EXPORT)
    @RequestMapping(value = "/examSite/export", method = RequestMethod.POST)
    public String examSiteExport(ExamStudentSearchQuery query, HttpServletRequest request,
            HttpServletResponse response, RedirectAttributes redirectAttributes) {
        int examId = getSessionExamId(request);
        List<ScanInfoVO> list = new LinkedList<ScanInfoVO>();
        List<String> result = studentService.findDistinctExamSite(examId);
        result = result.stream().filter(s -> StringUtils.isNotBlank(s)).collect(Collectors.toList());
        if (StringUtils.isBlank(query.getExamSite())) {
            for (String examSite : result) {
                ScanInfoVO vo = new ScanInfoVO();
                vo.setName(examSite);
                vo.setTotalCount(studentService.countByExamIdAndExamSite(examId, examSite));
                vo.setScanCount(studentService.countByExamIdAndExamSite(examId, examSite, true));
                vo.setScanSheetCount(studentService.countSheetCountByExamIdAndExamSite(examId, examSite) / 2);
                list.add(vo);
            }
        } else {
            ScanInfoVO vo = new ScanInfoVO();
            vo.setName(query.getExamSite());
            vo.setTotalCount(studentService.countByExamIdAndExamSite(examId, query.getExamSite()));
            vo.setScanCount(studentService.countByExamIdAndExamSite(examId, query.getExamSite(), true));
            vo.setScanSheetCount(studentService.countSheetCountByExamIdAndExamSite(examId, query.getExamSite()) / 2);
            list.add(vo);
        }
        try {
            String fileName = "扫描进度.xlsx";
            new ExportExcel("扫描进度", ScanInfoVO.class).setDataList(list).write(response, fileName).dispose();
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            addMessage(redirectAttributes, "导出扫描进度失败！" + e.getMessage());
            return "redirect:/admin/exam/scan/examSite";
        }
    }
}
