package com.qmth.distributed.print.api.client;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.qmth.boot.api.annotation.Aac;
import com.qmth.boot.api.constant.ApiConstant;
import com.qmth.distributed.print.business.bean.dto.*;
import com.qmth.distributed.print.business.bean.dto.client.PrintSingleDto;
import com.qmth.distributed.print.business.service.ClientService;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.entity.BasicSchool;
import com.qmth.teachcloud.common.util.Result;
import com.qmth.teachcloud.common.util.ResultUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 客户端接口（打印端）
 */
@Api(tags = "客户端Controller")
@RestController
@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + SystemConstant.PREFIX_URL_CLIENT)
//@Validated
public class PrintController {

    @Resource
    ClientService clientService;

    @ApiOperation(value = "试卷打样-列表")
    @PostMapping("/paper_try/list")
    public Result paperTryList(@ApiParam(value = "机器唯一码", required = true) @RequestParam("machineCode") String machineCode,
                               @ApiParam(value = "机构ID") @RequestParam("orgId") Long orgId,
                               @ApiParam(value = "学期ID") @RequestParam(value = "semesterId", required = false) Long semesterId,
                               @ApiParam(value = "考试ID") @RequestParam(value = "examId", required = false) Long examId,
                               @ApiParam(value = "印刷计划ID") @RequestParam(value = "printPlanId", required = false) Long printPlanId,
                               @ApiParam(value = "课程代码") @RequestParam(value = "courseCode", required = false) String courseCode,
                               @ApiParam(value = "试卷编号") @RequestParam(value = "paperNumber", required = false) String paperNumber,
                               @ApiParam(value = "是否打样") @RequestParam(value = "isTry", required = false) Boolean isTry,
                               @ApiParam(value = "是否合格") @RequestParam(value = "isPass", required = false) Boolean isPass,
                               @ApiParam(value = "分页参数") @RequestParam Integer pageNumber,
                               @ApiParam(value = "分页参数") @RequestParam Integer pageSize) {
        IPage<ClientExamTaskDto> examTasks = clientService.listTryTask(machineCode, orgId, semesterId, examId, printPlanId, courseCode, paperNumber, isTry, isPass, pageNumber, pageSize);
        return ResultUtil.ok(examTasks);
    }

    @ApiOperation(value = "试卷打样-查看/试印/重印")
    @PostMapping("/paper_try/print")
    public Result paperTryPrint(@ApiParam(value = "多任务集合", required = true) @RequestParam("data") String data) {
        List<JSONObject> objects = JSON.parseArray(data, JSONObject.class);
        List<Map<String, Object>> list = clientService.getPaperUrl(objects);
        return ResultUtil.ok(list);
    }

    @ApiOperation(value = "试卷打样-批量试印")
    @PostMapping("/paper_try/print_batch")
    public Result printBatch(@ApiParam(value = "机器码", required = true) @RequestParam("machineCode") String machineCode,
                             @ApiParam(value = "机构ID", required = true) @RequestParam("orgId") Long orgId,
                             @ApiParam(value = "学期ID") @RequestParam(value = "semesterId", required = false) Long semesterId,
                             @ApiParam(value = "考试ID") @RequestParam(value = "examId", required = false) Long examId,
                             @ApiParam(value = "印刷计划ID") @RequestParam(value = "printPlanId", required = false) Long printPlanId,
                             @ApiParam(value = "课程代码") @RequestParam(value = "courseCode", required = false) String courseCode,
                             @ApiParam(value = "试卷编号") @RequestParam(value = "paperNumber", required = false) String paperNumber,
                             @ApiParam(value = "是否打样") @RequestParam(value = "isTry", required = false) Boolean isTry,
                             @ApiParam(value = "是否通过") @RequestParam(value = "isPass", required = false) Boolean isPass) {
        List<Map<String, Object>> urls = clientService.getBatchUrl(machineCode, orgId, semesterId, examId, printPlanId, courseCode, paperNumber, isTry, isPass);
        return ResultUtil.ok(urls);
    }

    @ApiOperation(value = "试卷打样-标记合格状态")
    @PostMapping("/paper_try/tag_pass")
    public Result paperTryTagPass(@ApiParam(value = "印刷计划ID", required = true) @RequestParam("printPlanId") Long printPlanId,
                                  @ApiParam(value = "课程代码", required = true) @RequestParam("courseCode") String courseCode,
                                  @ApiParam(value = "课程名称", required = true) @RequestParam("courseName") String courseName,
                                  @ApiParam(value = "试卷编号", required = true) @RequestParam("paperNumber") String paperNumber,
                                  @ApiParam(value = "机器码", required = true) @RequestParam("machineCode") String machineCode,
                                  @ApiParam(value = "是否通过", required = true) @RequestParam("isPass") Boolean isPass,
                                  @ApiParam(value = "用户ID", required = true) @RequestParam("userId") Long userId) {
        Boolean isSuccess = clientService.tagPass(printPlanId, courseCode, courseName, paperNumber, machineCode, isPass, userId);
        return ResultUtil.ok(isSuccess);
    }

    @ApiOperation(value = "印刷管理-查询列表")
    @PostMapping("/print/task_list")
    public Result printTaskList(@ApiParam(value = "机器码", required = true) @RequestParam("machineCode") String machineCode,
                                @ApiParam(value = "机构ID", required = true) @RequestParam("orgId") Long orgId,
                                @ApiParam(value = "学期ID") @RequestParam(value = "semesterId", required = false) Long semesterId,
                                @ApiParam(value = "考试ID") @RequestParam(value = "examId", required = false) Long examId,
                                @ApiParam(value = "印刷计划ID") @RequestParam(value = "printPlanId", required = false) String printPlanId,
                                @ApiParam(value = "状态") @RequestParam(value = "status", required = false) String status,
                                @ApiParam(value = "课程代码") @RequestParam(value = "courseCode", required = false) String courseCode,
                                @ApiParam(value = "试卷编号") @RequestParam(value = "paperNumber", required = false) String paperNumber,
                                @ApiParam(value = "考点") @RequestParam(value = "examPlace", required = false) String examPlace,
                                @ApiParam(value = "考场") @RequestParam(value = "examRoom", required = false) String examRoom,
                                @ApiParam(value = "考试时间（开始）") @RequestParam(value = "examStartTime", required = false) Long examStartTime,
                                @ApiParam(value = "考试时间（结束）") @RequestParam(value = "examEndTime", required = false) Long examEndTime,
                                @ApiParam(value = "是否缓存") @RequestParam(value = "isDownload", required = false) Boolean isDownload,
                                @ApiParam(value = "是否校验") @RequestParam(value = "validate", required = false) Boolean validate,
                                @ApiParam(value = "分页参数") @RequestParam Integer pageNumber,
                                @ApiParam(value = "分页参数") @RequestParam Integer pageSize) {
        IPage<ClientPrintTaskDto> printTaskDtoIPage = clientService.listClientPrintTask(machineCode, orgId, semesterId, examId, printPlanId, status, courseCode, paperNumber, examPlace, examRoom, examStartTime, examEndTime, isDownload, validate, pageNumber, pageSize);
        return ResultUtil.ok(printTaskDtoIPage);
    }

    @ApiOperation(value = "印刷管理-导出")
    @PostMapping("/print/task_list_export")
    public void printTaskListExport(HttpServletResponse response,
                                    @ApiParam(value = "机器码", required = true) @RequestParam("machineCode") String machineCode,
                                    @ApiParam(value = "机构ID", required = true) @RequestParam("orgId") Long orgId,
                                    @ApiParam(value = "学期ID") @RequestParam(value = "semesterId", required = false) Long semesterId,
                                    @ApiParam(value = "考试ID") @RequestParam(value = "examId", required = false) Long examId,
                                    @ApiParam(value = "印刷计划ID") @RequestParam(value = "printPlanId", required = false) String printPlanId,
                                    @ApiParam(value = "状态") @RequestParam(value = "status", required = false) String status,
                                    @ApiParam(value = "课程代码") @RequestParam(value = "courseCode", required = false) String courseCode,
                                    @ApiParam(value = "试卷编号") @RequestParam(value = "paperNumber", required = false) String paperNumber,
                                    @ApiParam(value = "考点") @RequestParam(value = "examPlace", required = false) String examPlace,
                                    @ApiParam(value = "考场") @RequestParam(value = "examRoom", required = false) String examRoom,
                                    @ApiParam(value = "考试时间（开始）") @RequestParam(value = "examStartTime", required = false) Long examStartTime,
                                    @ApiParam(value = "考试时间（结束）") @RequestParam(value = "examEndTime", required = false) Long examEndTime,
                                    @ApiParam(value = "是否缓存") @RequestParam(value = "isDownload", required = false) Boolean isDownload,
                                    @ApiParam(value = "是否校验") @RequestParam(value = "validate", required = false) Boolean validate) throws Exception {
        clientService.exportClientPrintTask(response, machineCode, orgId, semesterId, examId, printPlanId, status, courseCode, paperNumber, examPlace, examRoom, examStartTime, examEndTime, isDownload, validate);
    }

    @ApiOperation(value = "印刷管理-汇总数据查询")
    @PostMapping("/print/task_total_data")
    public Result printTaskTotalData(@ApiParam(value = "机器码", required = true) @RequestParam("machineCode") String machineCode,
                                     @ApiParam(value = "机构ID", required = true) @RequestParam("orgId") Long orgId,
                                     @ApiParam(value = "学期ID") @RequestParam(value = "semesterId", required = false) Long semesterId,
                                     @ApiParam(value = "考试ID") @RequestParam(value = "examId", required = false) Long examId,
                                     @ApiParam(value = "印刷计划ID") @RequestParam(value = "printPlanId", required = false) String printPlanId,
                                     @ApiParam(value = "状态") @RequestParam(value = "status", required = false) String status,
                                     @ApiParam(value = "课程代码") @RequestParam(value = "courseCode", required = false) String courseCode,
                                     @ApiParam(value = "试卷编号") @RequestParam(value = "paperNumber", required = false) String paperNumber,
                                     @ApiParam(value = "考点") @RequestParam(value = "examPlace", required = false) String examPlace,
                                     @ApiParam(value = "考场") @RequestParam(value = "examRoom", required = false) String examRoom,
                                     @ApiParam(value = "考试时间（开始）") @RequestParam(value = "examStartTime", required = false) Long examStartTime,
                                     @ApiParam(value = "考试时间（结束）") @RequestParam(value = "examEndTime", required = false) Long examEndTime,
                                     @ApiParam(value = "是否缓存") @RequestParam(value = "isDownload", required = false) Boolean isDownload,
                                     @ApiParam(value = "是否校验") @RequestParam(value = "validate", required = false) Boolean validate) {
        ClientPrintTaskTotalDto clientPrintTaskTotalDto = clientService.taskTotalData(semesterId, examId, printPlanId, orgId, status, courseCode, paperNumber, examPlace, examRoom, examStartTime, examEndTime, isDownload, validate, machineCode);
        return ResultUtil.ok(clientPrintTaskTotalDto);
    }

    @ApiOperation(value = "印刷管理-查看")
    @PostMapping("/print/preview")
    public Result printPreview(@ApiParam(value = "命题任务ID", required = true) @RequestParam("examDetailId") Long examDetailId) {
        Map<String, Object> map = clientService.getUrlByExamDetailId(examDetailId);
        return ResultUtil.ok(map);
    }

    @ApiOperation(value = "印刷管理-印刷/缓存数据")
    @PostMapping("/print/get_print_data")
    public Result printGetPrintData(@ApiParam(value = "考场ID", required = true) @RequestParam("examDetailId") String examDetailId,
                                    @ApiParam(value = "机器码", required = true) @RequestParam("machineCode") String machineCode,
                                    @ApiParam(value = "是否打印", required = true) @RequestParam("isPrint") Boolean isPrint,
                                    @ApiParam(value = "打印员") @RequestParam(value = "printUser", required = false) String printUser) {
        List<Map<String, Object>> mapList = clientService.getPrintData(examDetailId, machineCode, isPrint, printUser);
        return ResultUtil.ok(mapList);
    }

    @ApiOperation(value = "印刷管理-批量缓存数据")
    @PostMapping("/print/get_print_data_batch")
    public Result printGetPrintDataBatch(@ApiParam(value = "机器码", required = true) @RequestParam("machineCode") String machineCode,
                                         @ApiParam(value = "机构ID", required = true) @RequestParam("orgId") Long orgId,
                                         @ApiParam(value = "学期ID") @RequestParam(value = "semesterId", required = false) Long semesterId,
                                         @ApiParam(value = "考试ID") @RequestParam(value = "examId", required = false) Long examId,
                                         @ApiParam(value = "印刷计划ID") @RequestParam(value = "printPlanId", required = false) String printPlanId,
                                         @ApiParam(value = "状态") @RequestParam(value = "status", required = false) String status,
                                         @ApiParam(value = "课程代码") @RequestParam(value = "courseCode", required = false) String courseCode,
                                         @ApiParam(value = "试卷编号") @RequestParam(value = "paperNumber", required = false) String paperNumber,
                                         @ApiParam(value = "考点") @RequestParam(value = "examPlace", required = false) String examPlace,
                                         @ApiParam(value = "考场") @RequestParam(value = "examRoom", required = false) String examRoom,
                                         @ApiParam(value = "考试时间（开始）") @RequestParam(value = "examStartTime", required = false) Long examStartTime,
                                         @ApiParam(value = "考试时间（结束）") @RequestParam(value = "examEndTime", required = false) Long examEndTime,
                                         @ApiParam(value = "是否缓存") @RequestParam(value = "isDownload", required = false) Boolean isDownload,
                                         @ApiParam(value = "是否校验") @RequestParam(value = "validate", required = false) Boolean validate) {
        List<Map<String, Object>> list = clientService.getPrintDataBatch(machineCode, orgId, semesterId, examId, printPlanId, status, courseCode, paperNumber, examPlace, examRoom, examStartTime, examEndTime, isDownload, validate);
        return ResultUtil.ok(list);
    }

    @ApiOperation(value = "印刷管理-缓存后更新状态")
    @PostMapping("/print/update_download")
    public Result updateDownload(@ApiParam(value = "考场ID", required = true) @RequestParam("examDetailId") Long examDetailId,
                                 @ApiParam(value = "机器码", required = true) @RequestParam("machineCode") String machineCode,
                                 @ApiParam(value = "是否缓存", required = true) @RequestParam("isDownload") Boolean isDownload) {
        Boolean isSuccess = clientService.updateDownload(examDetailId, machineCode, isDownload);
        return ResultUtil.ok(isSuccess);
    }

    @ApiOperation(value = "印刷管理-校验")
    @PostMapping("/print/validate_data")
    public Result dataCheck(@ApiParam(value = "考场ID", required = true) @RequestParam("examDetailId") Long examDetailId,
                            @ApiParam(value = "机器码", required = true) @RequestParam("packageCode") String packageCode,
                            @ApiParam(value = "校验条码号", required = true) @RequestParam("lastCode") String lastCode) {
        Boolean isSuccess = clientService.validateData(examDetailId, packageCode, lastCode);
        return ResultUtil.ok(isSuccess);
    }

    @ApiOperation(value = "印刷管理-更新打印进度")
    @PostMapping("/print/update_progress")
    public Result updateProgress(@ApiParam(value = "考场ID", required = true) @RequestParam("examDetailId") Long examDetailId,
                                 @ApiParam(value = "机器码", required = true) @RequestParam("machineCode") String machineCode,
                                 @ApiParam(value = "打印进度", required = true) @RequestParam("printProgress") Integer printProgress,
                                 @ApiParam(value = "是否打印") @RequestParam(value = "isPrint", required = false) Boolean isPrint) {
        Boolean isSuccess = clientService.updatePrintProgress(examDetailId, machineCode, printProgress, isPrint);
        return ResultUtil.ok(isSuccess);
    }

    @ApiOperation(value = "重打-查询考生列表")
    @PostMapping("/print/list_student")
    public Result listStudent(@ApiParam(value = "考场ID", required = true) @RequestParam("examDetailId") Long examDetailId,
                              @ApiParam(value = "学号") @RequestParam(value = "studentCode", required = false) String studentCode,
                              @ApiParam(value = "学生姓名") @RequestParam(value = "studentName", required = false) String studentName,
                              @ApiParam(value = "课程代码") @RequestParam(value = "courseCode", required = false) String courseCode,
                              @ApiParam(value = "分页参数", required = true) @RequestParam Integer pageNumber,
                              @ApiParam(value = "分页参数", required = true) @RequestParam Integer pageSize) {
        IPage<ClientExamStudentDto> examStudentDtoIPage = clientService.listStudent(examDetailId, studentCode, studentName, courseCode, pageNumber, pageSize);
        return ResultUtil.ok(examStudentDtoIPage);
    }

    @ApiOperation(value = "重打-内容查询")
    @PostMapping("/print/get_reprint_data")
    public Result getReprintData(@ApiParam(value = "考场ID", required = true) @RequestParam("examDetailId") Long examDetailId,
                                 @ApiParam(value = "学号", required = true) @RequestParam("studentCode") String studentCode,
                                 @ApiParam(value = "类型", required = true) @RequestParam("type") String type) {
        Map<String, Object> map = clientService.getReprintData(examDetailId, studentCode, type);
        return ResultUtil.ok(map);
    }

    @ApiOperation(value = "统计查询-查询列表")
    @PostMapping("/print/statistics_list")
    public Result printStatisticsList(@ApiParam(value = "机构ID", required = true) @RequestParam("orgId") Long orgId,
                                      @ApiParam(value = "学期ID") @RequestParam(value = "semesterId", required = false) Long semesterId,
                                      @ApiParam(value = "考试ID") @RequestParam(value = "examId", required = false) Long examId,
                                      @ApiParam(value = "印刷计划ID") @RequestParam(value = "printPlanId", required = false) String printPlanId,
                                      @ApiParam(value = "考点") @RequestParam(value = "examPlace", required = false) String examPlace,
                                      @ApiParam(value = "考试时间（开始）") @RequestParam(value = "examStartTime", required = false) Long examStartTime,
                                      @ApiParam(value = "考试时间（结束）") @RequestParam(value = "examEndTime", required = false) Long examEndTime,
                                      @ApiParam(value = "课程代码") @RequestParam(value = "courseCode", required = false) String courseCode,
                                      @ApiParam(value = "试卷编号") @RequestParam(value = "paperNumber", required = false) String paperNumber,
                                      @ApiParam(value = "分页参数", required = true) @RequestParam Integer pageNumber,
                                      @ApiParam(value = "分页参数", required = true) @RequestParam Integer pageSize) {
        IPage<ClientPrintStatisticsDto> statisticsDtoIPage = clientService.listClientPrintStatistics(orgId, semesterId, examId, printPlanId, examPlace, examStartTime, examEndTime, courseCode, paperNumber, pageNumber, pageSize);
        return ResultUtil.ok(statisticsDtoIPage);
    }

    @ApiOperation(value = "统计查询-汇总数据查询")
    @PostMapping("/print/statistics_total_data")
    public Result printStatisticsTotalData(@ApiParam(value = "机构ID", required = true) @RequestParam("orgId") Long orgId,
                                           @ApiParam(value = "学期ID") @RequestParam(value = "semesterId", required = false) Long semesterId,
                                           @ApiParam(value = "考试ID") @RequestParam(value = "examId", required = false) Long examId,
                                           @ApiParam(value = "印刷计划ID") @RequestParam(value = "printPlanId", required = false) Long printPlanId,
                                           @ApiParam(value = "考点") @RequestParam(value = "examPlace", required = false) String examPlace,
                                           @ApiParam(value = "考试时间（开始）") @RequestParam(value = "examStartTime", required = false) Long examStartTime,
                                           @ApiParam(value = "考试时间（结束）") @RequestParam(value = "examEndTime", required = false) Long examEndTime,
                                           @ApiParam(value = "课程代码") @RequestParam(value = "courseCode", required = false) String courseCode,
                                           @ApiParam(value = "试卷编号") @RequestParam(value = "paperNumber", required = false) String paperNumber) {
        ClientPrintStatisticsTotalDto statisticsTotalDto = clientService.clientStatisticsTotalData(orgId, semesterId, examId, printPlanId, examPlace, examStartTime, examEndTime, courseCode, paperNumber);
        return ResultUtil.ok(statisticsTotalDto);
    }

    @ApiOperation(value = "学校查询")
    @RequestMapping(value = "/school/list", method = RequestMethod.POST)
    @Aac(strict = false, auth = false)
    public Result list(@ApiParam(value = "学校Code") @RequestParam(required = false) String code) {
        List<BasicSchool> list = clientService.listSchool(code);
        // 指定code后，只返回code对应学校，否则查默认学校，没有默认，返回所有
        if (CollectionUtils.isNotEmpty(list) && StringUtils.isBlank(code)) {
            List<BasicSchool> defaultSchools = list.stream().filter(m -> m.getDefaultSchool() != null && m.getDefaultSchool()).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(defaultSchools)) {
                return ResultUtil.ok(defaultSchools);
            }
        }
        return ResultUtil.ok(list);
    }

    @ApiOperation(value = "修改密码")
    @RequestMapping(value = "/user/update_password", method = RequestMethod.POST)
    @Aac(strict = false, auth = false)
    public Result updatePassword(@ApiParam(value = "用户ID", required = true) @RequestParam Long userId,
                                 @ApiParam(value = "密码", required = true) @RequestParam String password) {
        return ResultUtil.ok(clientService.updatePassword(userId, password));
    }

    /**
     * 单文件打印
     */
    @ApiOperation(value = "单文件打印")
    @PostMapping("/print/single")
    public Result printSingleFile(@ApiParam(value = "学期ID", required = true) @RequestParam("semesterId") Long semesterId,
                                  @ApiParam(value = "考试ID", required = true) @RequestParam("examId") Long examId,
                                  @ApiParam(value = "印刷计划ID") @RequestParam(value = "printPlanId", required = false) Long printPlanId,
                                  @ApiParam(value = "课程代码") @RequestParam(value = "courseCode", required = false) Long courseCode,
                                  @ApiParam(value = "试卷编号") @RequestParam(value = "paperNumber", required = false) Long paperNumber,
                                  @ApiParam(value = "分页参数", required = true) @RequestParam Integer pageNumber,
                                  @ApiParam(value = "分页参数", required = true) @RequestParam Integer pageSize) {
        IPage<PrintSingleDto> printSingleDtoIPage = clientService.getSingleData(semesterId, examId, printPlanId, courseCode, paperNumber, pageNumber, pageSize);
        return ResultUtil.ok(printSingleDtoIPage);
    }
}
