package com.qmth.distributed.print.api;

import com.qmth.boot.api.constant.ApiConstant;
import com.qmth.distributed.print.business.bean.params.SingleExamStudentAddParam;
import com.qmth.distributed.print.business.bean.result.EditResult;
import com.qmth.distributed.print.business.service.ExamDetailCourseService;
import com.qmth.distributed.print.business.service.ExamDetailService;
import com.qmth.distributed.print.business.service.ExamStudentService;
import com.qmth.distributed.print.business.templete.execute.AsyncExaminationExportTemplateService;
import com.qmth.teachcloud.common.annotation.OperationLogDetail;
import com.qmth.teachcloud.common.bean.dto.DataPermissionRule;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.entity.SysUser;
import com.qmth.teachcloud.common.entity.TBTask;
import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
import com.qmth.teachcloud.common.enums.TaskTypeEnum;
import com.qmth.teachcloud.common.enums.log.OperationTypeEnum;
import com.qmth.teachcloud.common.service.BasicRoleDataPermissionService;
import com.qmth.teachcloud.common.service.TBTaskService;
import com.qmth.teachcloud.common.util.Result;
import com.qmth.teachcloud.common.util.ResultUtil;
import com.qmth.teachcloud.common.util.ServletUtil;
import io.swagger.annotations.*;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 考务数据 前端控制器
 * </p>
 *
 * @author xf
 * @since 2021-03-23
 */
@Api(tags = "考务数据管理Controller")
@RestController
@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + SystemConstant.PREFIX_URL_EXAM + "/print")
@Validated
public class ExamDetailController {
    @Resource
    private TBTaskService tbTaskService;
    @Resource
    private AsyncExaminationExportTemplateService asyncExaminationExportTemplateService;
    @Resource
    private ExamDetailService examDetailService;
    @Resource
    private ExamDetailCourseService examDetailCourseService;
    @Resource
    private ExamStudentService examStudentService;
    @Resource
    private BasicRoleDataPermissionService basicRoleDataPermissionService;

    @ApiOperation(value = "异步考务数据批量导入接口")
    @RequestMapping(value = "/data_import", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = EditResult.class)})
    @OperationLogDetail(operationType = OperationTypeEnum.IMPORT)
    public Result examinationImportAsync(@ApiParam(value = "上传文件", required = true) @RequestParam MultipartFile file,
                                         @ApiParam(value = "印刷计划id", required = true) @RequestParam String printPlanId) {
        TBTask tbTask = examDetailService.importData(printPlanId, file);
        return Objects.nonNull(tbTask) ? ResultUtil.ok(tbTask.getId()) : ResultUtil.error("创建任务失败");
    }

    @ApiOperation(value = "考务数据导入-查询")
    @RequestMapping(value = "/data_list", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "查询成功", response = Result.class)})
    public Result findExaminationBrief(@ApiParam(value = "学期ID") @RequestParam(required = false) String semesterId,
                                       @ApiParam(value = "考试id") @RequestParam(required = false) String examId,
                                       @ApiParam(value = "印刷计划id集合") @RequestParam(required = false) List<String> printPlanIdList,
                                       @ApiParam(value = "课程代码") @RequestParam(required = false) String courseCode,
                                       @ApiParam(value = "试卷编号") @RequestParam(required = false) String paperNumber,
                                       @ApiParam(value = "考点") @RequestParam(required = false) String examPlace,
                                       @ApiParam(value = "考场") @RequestParam(required = false) String examRoom,
                                       @ApiParam(value = "卷袋号") @RequestParam(required = false) String packageCode,
                                       @ApiParam(value = "考试日期-起始") @RequestParam(required = false) Long startDate,
                                       @ApiParam(value = "考试日期-终止") @RequestParam(required = false) Long endDate,
                                       @ApiParam(value = "分页页码", required = true) @RequestParam @Min(SystemConstant.PAGE_NUMBER_MIN) Integer pageNumber,
                                       @ApiParam(value = "分页数", required = true) @RequestParam @Min(SystemConstant.PAGE_SIZE_MIN) @Max(SystemConstant.PAGE_SIZE_MAX) Integer pageSize) {
        if (semesterId == null) {
            throw ExceptionResultEnum.SEMESTER_ID_IS_NULL.exception();
        }
        if (examId == null) {
            throw ExceptionResultEnum.EXAM_ID_IS_NULL.exception();
        }
        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
        DataPermissionRule dpr = basicRoleDataPermissionService.findDataPermission(schoolId, requestUser.getId(), ServletUtil.getRequest().getServletPath());
        if (Objects.isNull(printPlanIdList)) {
            printPlanIdList = new ArrayList<>();
        }
        List<Long> idList = printPlanIdList.stream().map(SystemConstant::convertIdToLong).collect(Collectors.toList());

        return ResultUtil.ok(examDetailService.findExaminationBriefPage(schoolId, SystemConstant.convertIdToLong(semesterId), SystemConstant.convertIdToLong(examId),
                idList, courseCode, paperNumber, examPlace, examRoom, packageCode, startDate, endDate, pageNumber, pageSize, dpr));
    }

    @ApiOperation(value = "考务数据导入-汇总数据查询")
    @RequestMapping(value = "/data_total", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "查询成功", response = Result.class)})
    public Result findSummarizedData(@ApiParam(value = "学期ID") @RequestParam(required = false) String semesterId,
                                     @ApiParam(value = "考试id") @RequestParam(required = false) String examId,
                                     @ApiParam(value = "印刷计划id集合") @RequestParam(required = false) List<String> printPlanIdList,
                                     @ApiParam(value = "课程代码") @RequestParam(required = false) String courseCode,
                                     @ApiParam(value = "试卷编号") @RequestParam(required = false) String paperNumber,
                                     @ApiParam(value = "考点") @RequestParam(required = false) String examPlace,
                                     @ApiParam(value = "考场") @RequestParam(required = false) String examRoom,
                                     @ApiParam(value = "卷袋号") @RequestParam(required = false) String packageCode,
                                     @ApiParam(value = "考试日期-起始") @RequestParam(required = false) Long startDate,
                                     @ApiParam(value = "考试日期-终止") @RequestParam(required = false) Long endDate) {

        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
        DataPermissionRule dpr = basicRoleDataPermissionService.findDataPermission();
        if (Objects.isNull(printPlanIdList)) {
            printPlanIdList = new ArrayList<>();
        }
        List<Long> idList = printPlanIdList.stream().map(SystemConstant::convertIdToLong).collect(Collectors.toList());
        return ResultUtil.ok(examDetailService.findSummarizedData(schoolId, SystemConstant.convertIdToLong(semesterId), SystemConstant.convertIdToLong(examId), idList, courseCode, paperNumber, examPlace, examRoom, packageCode, startDate, endDate, dpr));
    }

    @ApiOperation(value = "考务数据导入-查看明细")
    @RequestMapping(value = "/data_detail", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "查询成功", response = Result.class)})
    public Result findExaminationDetail(@ApiParam(value = "学期ID") @RequestParam(required = false) String semesterId,
                                        @ApiParam(value = "考试id") @RequestParam(required = false) String examId,
                                        @ApiParam(value = "印刷计划主键集合") @RequestParam(required = false) List<String> printPlanIdList,
                                        @ApiParam(value = "课程代码") @RequestParam(required = false) String courseCode,
                                        @ApiParam(value = "试卷编号") @RequestParam(required = false) String paperNumber,
                                        @ApiParam(value = "考点") @RequestParam(required = false) String examPlace,
                                        @ApiParam(value = "考场") @RequestParam(required = false) String examRoom,
                                        @ApiParam(value = "学生查询参数") @RequestParam(required = false) String studentParams,
                                        @ApiParam(value = "考试日期-起始") @RequestParam(required = false) Long startDate,
                                        @ApiParam(value = "考试日期-终止") @RequestParam(required = false) Long endDate,
                                        @ApiParam(value = "分页页码", required = true) @RequestParam @Min(SystemConstant.PAGE_NUMBER_MIN) Integer pageNumber,
                                        @ApiParam(value = "分页数", required = true) @RequestParam @Min(SystemConstant.PAGE_SIZE_MIN) @Max(SystemConstant.PAGE_SIZE_MAX) Integer pageSize) {
        if (semesterId == null) {
            throw ExceptionResultEnum.SEMESTER_ID_IS_NULL.exception();
        }
        if (examId == null) {
            throw ExceptionResultEnum.EXAM_ID_IS_NULL.exception();
        }
        if (Objects.isNull(printPlanIdList)) {
            printPlanIdList = new ArrayList<>();
        }
        List<Long> idList = printPlanIdList.stream().map(SystemConstant::convertIdToLong).collect(Collectors.toList());
        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
        return ResultUtil.ok(examDetailService.findExaminationDetail(schoolId, SystemConstant.convertIdToLong(semesterId), SystemConstant.convertIdToLong(examId), idList,
                courseCode, paperNumber, examPlace, examRoom, studentParams, startDate, endDate, pageNumber, pageSize));
    }

    @ApiOperation(value = "查看考生明细")
    @RequestMapping(value = "/get_student_detail", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "查询成功", response = Result.class)})
    public Result getStudentDetail(@ApiParam(value = "考生表主键") @RequestParam(required = false) Long id) {
        Map<String, Object> map = examStudentService.getStudentDetail(id);
        return ResultUtil.ok(map);
    }


    @ApiOperation(value = "考务数据导入-查看明细弹窗")
    @RequestMapping(value = "/data_detail_list", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "查询成功", response = Result.class)})
    public Result findExaminationDetailById(@ApiParam(value = "考场ID", required = true) @RequestParam String examDetailId,
                                            @ApiParam(value = "姓名/学号") @RequestParam(required = false) String param,
                                            @ApiParam(value = "分页页码", required = true) @RequestParam @Min(SystemConstant.PAGE_NUMBER_MIN) Integer pageNumber,
                                            @ApiParam(value = "分页数", required = true) @RequestParam @Min(SystemConstant.PAGE_SIZE_MIN) @Max(SystemConstant.PAGE_SIZE_MAX) Integer pageSize) {
        return ResultUtil.ok(examDetailService.findExaminationDetail(SystemConstant.convertIdToLong(examDetailId), param, pageNumber, pageSize));
    }

    @ApiOperation(value = "考务数据导入-考点模糊查询")
    @RequestMapping(value = "/data_place_query", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "查询成功", response = Result.class)})
    public Result findExamPlaceDatasource(@RequestParam(value = "param", required = false) String param,
                                          @RequestParam(value = "printPlanId", required = false) List<String> printPlanId) {
        if (Objects.isNull(printPlanId)) {
            printPlanId = new ArrayList<>();
        }
        List<Long> printPlanIdList = printPlanId.stream().map(SystemConstant::convertIdToLong).collect(Collectors.toList());
        return ResultUtil.ok(examDetailService.findExamPlaceDatasource(param, printPlanIdList));
    }

    @ApiOperation(value = "考务数据导入-考场模糊查询")
    @RequestMapping(value = "/data_room_query", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "查询成功", response = Result.class)})
    public Result findExamRoomDatasource(@RequestParam(value = "param", required = false) String param,
                                         @RequestParam(value = "printPlanId", required = false) List<String> printPlanId) {
        if (Objects.isNull(printPlanId)) {
            printPlanId = new ArrayList<>();
        }
        List<Long> printPlanIdList = printPlanId.stream().map(SystemConstant::convertIdToLong).collect(Collectors.toList());
        return ResultUtil.ok(examDetailService.findExamRoomDatasource(param, printPlanIdList));
    }

    @ApiOperation(value = "考务数据导入-模板下载")
    @RequestMapping(value = "/template_download", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "下载成功", response = EditResult.class)})
    public void downLoadExaminationTemplate() throws IOException {
        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
        examDetailService.downLoadExaminationTemplate(schoolId, ServletUtil.getResponse());
    }

    @ApiOperation(value = "考务数据导入-结果导出")
    @RequestMapping(value = "/data_export", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = EditResult.class)})
    @OperationLogDetail(operationType = OperationTypeEnum.EXPORT)
    public Result dataExport(@ApiParam(value = "学期ID") @RequestParam(required = false) String semesterId,
                             @ApiParam(value = "考试id") @RequestParam(required = false) String examId,
                             @ApiParam(value = "印刷计划id集合") @RequestParam(required = false) List<String> printPlanIdList,
                             @ApiParam(value = "课程代码") @RequestParam(required = false) String courseCode,
                             @ApiParam(value = "试卷编号") @RequestParam(required = false) String paperNumber,
                             @ApiParam(value = "考点") @RequestParam(required = false) String examPlace,
                             @ApiParam(value = "考场") @RequestParam(required = false) String examRoom,
                             @ApiParam(value = "卷袋号") @RequestParam(required = false) String packageCode,
                             @ApiParam(value = "考试日期-起始") @RequestParam(required = false) Long startDate,
                             @ApiParam(value = "考试日期-终止") @RequestParam(required = false) Long endDate) {
        if (examId == null) {
            throw ExceptionResultEnum.EXAM_ID_IS_NULL.exception();
        }
        DataPermissionRule dpr = basicRoleDataPermissionService.findDataPermission();
        if (Objects.isNull(printPlanIdList)) {
            printPlanIdList = new ArrayList<>();
        }
        List<Long> idList = printPlanIdList.stream().map(SystemConstant::convertIdToLong).collect(Collectors.toList());
        Long printId = null;
        if (idList.size() > 0) {
            printId = idList.get(0);
        }
        Map<String, Object> map = tbTaskService.saveTask(TaskTypeEnum.EXAMINATION_EXPORT, printId);
        map.put("semesterId", semesterId);
        map.put("examId", examId);
        map.put("printPlanIdList", idList);
        map.put("courseCode", courseCode);
        map.put("paperNumber", paperNumber);
        map.put("examPlace", examPlace);
        map.put("examRoom", examRoom);
        map.put("packageCode", packageCode);
        map.put("startDate", startDate);
        map.put("endDate", endDate);
        map.put("dpr", dpr);
        asyncExaminationExportTemplateService.exportTask(map);
        TBTask tbTask = Objects.nonNull(map.get(SystemConstant.TASK)) ? (TBTask) map.get(SystemConstant.TASK) : null;
        return Objects.nonNull(tbTask) ? ResultUtil.ok(tbTask.getId()) : ResultUtil.error("创建任务失败");
    }

    /**
     * 考务数据导入-删除
     *
     * @param id examDetail表id
     * @return
     */
    @ApiOperation(value = "考务数据导入-删除")
    @RequestMapping(value = "/data_delete", method = RequestMethod.POST)
    @OperationLogDetail(operationType = OperationTypeEnum.DELETE)
    public Result dataDelete(@RequestParam Long id) {
        examDetailService.dataDelete(id);
        return ResultUtil.ok(true);
    }

    /**
     * 获取新增考生考务字段
     *
     * @param examDetailId 考场ID
     */
    @ApiOperation(value = "考务数据导入-新增考生-考场科目")
    @RequestMapping(value = "/list_exam_detail_course", method = RequestMethod.POST)
    public Result listExamDetailPaperNumber(@ApiParam(value = "考务场次ID", required = true) @RequestParam Long examDetailId) {
        return ResultUtil.ok(examDetailCourseService.listExamDetailPaperNumber(examDetailId));
    }

    /**
     * 新增考生-保存
     *
     * @param singleExamStudentAddParam 请求参数
     * @return
     */
    @ApiOperation(value = "考务数据导入-新增考生-保存")
    @RequestMapping(value = "/add_exam_student", method = RequestMethod.POST)
    @OperationLogDetail(operationType = OperationTypeEnum.ADD)
    public Result addExamStudent(@RequestBody SingleExamStudentAddParam singleExamStudentAddParam) {
        return ResultUtil.ok(examDetailCourseService.addExamStudent(singleExamStudentAddParam));
    }

    /**
     * 删除考生
     *
     * @param id 请求参数
     * @return
     */
    @ApiOperation(value = "考务数据导入-查看详情-删除考生")
    @RequestMapping(value = "/delete_exam_student", method = RequestMethod.POST)
    @OperationLogDetail(operationType = OperationTypeEnum.ADD)
    public Result deleteExamStudent(@RequestParam Long id) {
        return ResultUtil.ok(examDetailCourseService.deleteExamStudent(id));
    }
}

