package cn.com.qmth.scancentral.controller.admin;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.Collection;
import java.util.List;

import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
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.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.qmth.boot.api.annotation.Aac;
import com.qmth.boot.api.constant.ApiConstant;
import com.qmth.boot.core.collection.PageResult;
import com.qmth.boot.tools.excel.ExcelWriter;
import com.qmth.boot.tools.excel.enums.ExcelType;
import com.qmth.boot.tools.iterator.PageListIterator;

import cn.com.qmth.scancentral.bean.AnswerDeleteDomain;
import cn.com.qmth.scancentral.bean.AnswerQueryDomain;
import cn.com.qmth.scancentral.bean.BatchQueryDomain;
import cn.com.qmth.scancentral.bean.MismatchQueryDomain;
import cn.com.qmth.scancentral.bean.MismatchToggleDomain;
import cn.com.qmth.scancentral.bean.PageDeleteDomain;
import cn.com.qmth.scancentral.bean.omredit.OmrEditDomain;
import cn.com.qmth.scancentral.bean.omredit.OmrFieldEditDomain;
import cn.com.qmth.scancentral.bean.papermigrate.PaperMigrateDomain;
import cn.com.qmth.scancentral.bean.refix.AnswerRefixDomain;
import cn.com.qmth.scancentral.controller.BaseController;
import cn.com.qmth.scancentral.entity.ExamEntity;
import cn.com.qmth.scancentral.entity.ExamSummaryEntity;
import cn.com.qmth.scancentral.enums.ExamMode;
import cn.com.qmth.scancentral.service.BatchService;
import cn.com.qmth.scancentral.service.ExamService;
import cn.com.qmth.scancentral.service.ExamSummaryService;
import cn.com.qmth.scancentral.service.PaperService;
import cn.com.qmth.scancentral.service.StudentService;
import cn.com.qmth.scancentral.vo.AnswerDeleteVo;
import cn.com.qmth.scancentral.vo.AnswerExportK12Vo;
import cn.com.qmth.scancentral.vo.AnswerExportVo;
import cn.com.qmth.scancentral.vo.AnswerRefixVo;
import cn.com.qmth.scancentral.vo.BatchQueryVo;
import cn.com.qmth.scancentral.vo.MismatchToggleVo;
import cn.com.qmth.scancentral.vo.PaperDeleteVo;
import cn.com.qmth.scancentral.vo.PaperMigrateVo;
import cn.com.qmth.scancentral.vo.ScanAnswerInfoVo;
import cn.com.qmth.scancentral.vo.UpdateTimeVo;
import cn.com.qmth.scancentral.vo.UriVo;
import cn.com.qmth.scancentral.vo.answerquery.AnswerQueryVo;
import cn.com.qmth.scancentral.vo.batchdetail.BatchDetailVo;
import cn.com.qmth.scancentral.vo.mismatchquery.MismatchQueryVo;
import cn.com.qmth.scancentral.vo.student.StudentExamRoomVo;
import cn.com.qmth.scancentral.vo.student.StudentVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

@RestController
@Api(tags = "扫描管理-答题卡接口")
@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + "/admin/scan/answer")
@Aac(strict = false, auth = true)
public class ScanAnswerController extends BaseController {

    @Autowired
    private BatchService batchService;

    @Autowired
    private PaperService paperService;

    @Autowired
    private ExamService examService;

    @Autowired
    private StudentService studentService;

    @Autowired
    private ExamSummaryService examSummaryService;

    @ApiOperation(value = "查询答题卡扫描批次所有关联的扫描员")
    @RequestMapping(value = "batch/scanner", method = RequestMethod.POST)
    public List<String> batchScanner(@RequestParam Long examId) {
        return batchService.batchScanner(examId);
    }

    @ApiOperation(value = "查询答题卡扫描批次信息")
    @RequestMapping(value = "batch/query", method = RequestMethod.POST)
    public PageResult<BatchQueryVo> batchQuery(@Validated BatchQueryDomain query) {
        return batchService.batchQuery(query);
    }

    @ApiOperation(value = "查询答题卡扫描批次概要")
    @RequestMapping(value = "batch/summary", method = RequestMethod.POST)
    public List<Long> batchSummary(@Validated BatchQueryDomain query) {
        return batchService.batchSummary(query);
    }

    @ApiOperation(value = "查询答题卡扫描批次详情")
    @RequestMapping(value = "batch/detail", method = RequestMethod.POST)
    public BatchDetailVo batchDetail(@RequestParam Long id) {
        return batchService.batchDetail(id);
    }

    @ApiOperation(value = "查询异常答题卡信息")
    @RequestMapping(value = "mismatch/query", method = RequestMethod.POST)
    public PageResult<MismatchQueryVo> mismatchQuery(@Validated MismatchQueryDomain query) {
        return paperService.mismatchQuery(query);
    }

    @ApiOperation(value = "修改异常答题卡标记")
    @RequestMapping(value = "mismatch/toggle", method = RequestMethod.POST)
    public MismatchToggleVo mismatchToggle(@Validated MismatchToggleDomain domain) {
        return paperService.mismatchToggle(domain);
    }

    @ApiOperation(value = "答题卡扫描汇总")
    @PostMapping("info")
    public ScanAnswerInfoVo scanAnswerInfo(@RequestParam Long examId) {
        ExamSummaryEntity es = examSummaryService.find(examId);
        ScanAnswerInfoVo vo = new ScanAnswerInfoVo();
        vo.setTotalCount(es.getStudentCount());
        vo.setScannedCount(es.getAnswerScannedCount());
        vo.setUnexistCount(es.getAnswerUnexistCount());
        vo.setManualAbsentCount(es.getAnswerManualAbsentCount());
        vo.setOmrAbsentCount(es.getAnswerOmrAbsentCount());
        vo.setAbsentSuspectCount(es.getAnswerAbsentSuspectCount());
        vo.setAssignedCount(es.getAnswerAssignedCount());
        vo.setIncompleteCount(es.getAnswerIncompleteCount());
        return vo;
    }

    @ApiOperation(value = "查询答题卡扫描详情")
    @RequestMapping(value = "query", method = RequestMethod.POST)
    public PageResult<AnswerQueryVo> query(@Validated AnswerQueryDomain query) {
        return studentService.query(query);
    }

    @ApiOperation(value = "查询答题卡扫描概要")
    @RequestMapping(value = "summary", method = RequestMethod.POST)
    public List<String> summary(@Validated AnswerQueryDomain query) {
        return studentService.summary(query);
    }

    @ApiOperation(value = "导出答题卡扫描详情")
    @RequestMapping(value = "export", method = RequestMethod.POST)
    public void export(@Validated AnswerQueryDomain query, HttpServletResponse response) throws IOException {
        String fileName = URLEncoder.encode("答题卡扫描详情", "UTF-8");
        response.setHeader("Content-Disposition", "inline; filename=" + fileName + ".xlsx");
        response.setContentType("application/vnd.ms-excel");
        ExcelWriter writer = ExcelWriter.create(ExcelType.XLSX);
        ExamEntity exam = examService.getById(query.getExamId());
        if (ExamMode.K12.equals(exam.getMode())) {
            PageListIterator<AnswerExportK12Vo> iterator = new PageListIterator<AnswerExportK12Vo>(5000) {

                @Override
                public Collection<AnswerExportK12Vo> getPageList(int pageNumber, int pageSize) {
                    query.setPageNumber(pageNumber);
                    query.setPageSize(pageSize);
                    return studentService.exportListK12(query);
                }
            };
            writer.writeObjects("扫描详情", null, AnswerExportK12Vo.class, iterator);
            writer.output(response.getOutputStream());
        } else {
            PageListIterator<AnswerExportVo> iterator = new PageListIterator<AnswerExportVo>(5000) {

                @Override
                public Collection<AnswerExportVo> getPageList(int pageNumber, int pageSize) {
                    query.setPageNumber(pageNumber);
                    query.setPageSize(pageSize);
                    return studentService.exportList(query);
                }
            };
            writer.writeObjects("扫描详情", null, AnswerExportVo.class, iterator);
            writer.output(response.getOutputStream());

        }

    }

    @ApiOperation(value = "修改答题卡识别结果")
    @RequestMapping(value = "omr/edit", method = RequestMethod.POST)
    public UpdateTimeVo omrEdit(@Validated @RequestBody OmrEditDomain domain) {
        return studentService.omrEdit(getAccessUser(), domain);
    }

    @ApiOperation(value = "按类型修改卷型、识别结果等")
    @RequestMapping(value = "omr/field/edit", method = RequestMethod.POST)
    public UpdateTimeVo omrFieldEdit(@Validated @RequestBody OmrFieldEditDomain domain) {
        return studentService.omrFieldEdit(getAccessUser(), domain);
    }

    @ApiOperation(value = "更新答题卡裁切图")
    @RequestMapping(value = "slice/update", method = RequestMethod.POST)
    public UriVo sliceUpdate(@RequestParam Long paperId, @RequestParam Integer pageIndex, @RequestParam Integer index,
            @RequestParam MultipartFile file, @RequestParam String md5) {
        return paperService.adminSliceUpdate(paperId, pageIndex, index, file, md5);
    }

    @ApiOperation(value = "更新答题卡原图")
    @RequestMapping(value = "sheet/update", method = RequestMethod.POST)
    public UriVo sheetUpdate(@RequestParam Long paperId, @RequestParam Integer pageIndex,
            @RequestParam MultipartFile file, @RequestParam String md5) {
        return paperService.adminSheetUpdate(paperId, pageIndex, file, md5);
    }

    @ApiOperation(value = "上传答题卡裁切图")
    @RequestMapping(value = "slice/upload", method = RequestMethod.POST)
    public UriVo sliceUpload(@RequestParam Long paperId, @RequestParam Integer pageIndex, @RequestParam Integer index,
            @RequestParam MultipartFile file, @RequestParam String md5) {
        return paperService.adminSliceUpload(paperId, pageIndex, index, file, md5);
    }

    @ApiOperation(value = "修改答题卡扫描图片绑定考生")
    @RequestMapping(value = "paper/migrate", method = RequestMethod.POST)
    public PaperMigrateVo paperMigrate(@Validated @RequestBody PaperMigrateDomain domain) {
        return paperService.paperMigrate(getAccessUser(), domain);
    }

    @ApiOperation(value = "删除答题卡单页扫描结果")
    @RequestMapping(value = "paper/delete", method = RequestMethod.POST)
    public PaperDeleteVo paperDelete(@Validated PageDeleteDomain domain) {
        return studentService.paperDelete(getAccessUser(), domain);
    }

    @ApiOperation(value = "删除答题卡扫描结果")
    @RequestMapping(value = "delete", method = RequestMethod.POST)
    public AnswerDeleteVo answerDelete(@Validated AnswerDeleteDomain domain) {
        return studentService.answerDelete(getAccessUser(), domain);
    }

    @ApiOperation(value = "答题卡二次识别")
    @RequestMapping(value = "refix", method = RequestMethod.POST)
    public AnswerRefixVo refix(@Validated @RequestBody AnswerRefixDomain query) {
        return studentService.answerRefix(getAccessUser(), query);
    }

    @ApiOperation(value = "按考生导出答题卡扫描详情")
    @PostMapping(value = "student/export")
    public void studentExport(@Validated AnswerQueryDomain query, HttpServletResponse response) throws IOException {
        String fileName = URLEncoder.encode("按考生导出", "UTF-8");
        response.setHeader("Content-Disposition", "inline; filename=" + fileName + ".xlsx");
        response.setContentType("application/vnd.ms-excel");
        ExcelWriter writer = ExcelWriter.create(ExcelType.XLSX);
        PageListIterator<StudentVo> iterator = new PageListIterator<StudentVo>(5000) {

            @Override
            public Collection<StudentVo> getPageList(int pageNumber, int pageSize) {
                query.setPageNumber(pageNumber);
                query.setPageSize(pageSize);
                return studentService.studentExportList(query);
            }
        };
        writer.writeObjects("按考生导出", null, StudentVo.class, iterator);
        writer.output(response.getOutputStream());

    }

    @ApiOperation(value = "按考场导出答题卡扫描详情")
    @PostMapping(value = "exam-room/export")
    public void studentExamRoomExport(@Validated AnswerQueryDomain query, HttpServletResponse response)
            throws IOException {
        String fileName = URLEncoder.encode("按考场导出", "UTF-8");
        response.setHeader("Content-Disposition", "inline; filename=" + fileName + ".xlsx");
        response.setContentType("application/vnd.ms-excel");
        ExcelWriter writer = ExcelWriter.create(ExcelType.XLSX);
        PageListIterator<StudentExamRoomVo> iterator = new PageListIterator<StudentExamRoomVo>(5000) {

            @Override
            public Collection<StudentExamRoomVo> getPageList(int pageNumber, int pageSize) {
                query.setPageNumber(pageNumber);
                query.setPageSize(pageSize);
                return studentService.studentExamRoomExportList(query);
            }
        };
        writer.writeObjects("按考场导出", null, StudentExamRoomVo.class, iterator);
        writer.output(response.getOutputStream());

    }

}