package com.qmth.distributed.print.api;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.qmth.boot.api.constant.ApiConstant;
import com.qmth.distributed.print.business.bean.dto.ExamTaskDetailDto;
import com.qmth.distributed.print.business.bean.dto.MakeupExamTaskDto;
import com.qmth.distributed.print.business.bean.dto.RelatePaperDto;
import com.qmth.distributed.print.business.bean.params.DeleteParams;
import com.qmth.distributed.print.business.bean.params.MakeupExamTaskTotalParam;
import com.qmth.distributed.print.business.bean.params.PrintPlanParams;
import com.qmth.distributed.print.business.bean.params.RelatePaperParam;
import com.qmth.distributed.print.business.enums.PrintPlanStatusEnum;
import com.qmth.distributed.print.business.service.ExamPrintPlanService;
import com.qmth.distributed.print.business.service.ExamTaskDetailService;
import com.qmth.distributed.print.business.service.ExamTaskService;
import com.qmth.teachcloud.common.annotation.OperationLogDetail;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.entity.SysUser;
import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
import com.qmth.teachcloud.common.enums.log.OperationTypeEnum;
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.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
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 ExamPrintPlanController {
    @Resource
    private ExamPrintPlanService examPrintPlanService;
    @Resource
    private ExamTaskService examTaskService;
    @Resource
    private ExamTaskDetailService examTaskDetailService;

    @ApiOperation(value = "印刷计划查询")
    @RequestMapping(value = "/list", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "查询成功", response = Result.class)})
    public Result findPrintPlanPage(@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) PrintPlanStatusEnum status,
                                    @ApiParam(value = "计划创建时间段开始时间") @RequestParam(required = false) Long startTime,
                                    @ApiParam(value = "计划创建时间段结束时间") @RequestParam(required = false) Long endTime,
                                    @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());
        if (Objects.isNull(printPlanIdList)) {
            printPlanIdList = new ArrayList<>();
        }
        List<Long> idList = printPlanIdList.stream().map(SystemConstant::convertIdToLong).collect(Collectors.toList());
        return ResultUtil.ok(examPrintPlanService.printPlanPage(schoolId, SystemConstant.convertIdToLong(semesterId), SystemConstant.convertIdToLong(examId), idList, status, startTime, endTime, pageNumber, pageSize));
    }

    @ApiOperation(value = "印刷计划模糊查询")
    @RequestMapping(value = "/query", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "查询成功", response = Result.class)})
    public Result findPrintPlanQuery(@RequestParam(value = "source", required = false) String source,
                                     @RequestParam(value = "module", required = false) String module) {
        return ResultUtil.ok(examPrintPlanService.printPlanBriefQuery(source, module));
    }

    @ApiOperation(value = "按类型查询模板")
    @RequestMapping(value = "/get_template", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "查询成功", response = Result.class)})
    public Result findPrintPlanPage() {
        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
        SysUser user = (SysUser) ServletUtil.getRequestUser();
        Long userId = user.getId();
        return ResultUtil.ok(examPrintPlanService.printPlanTemplateDatasource(schoolId, userId));
    }

    @ApiOperation(value = "印刷计划-新增/修改")
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "更新成功", response = Result.class)})
    @OperationLogDetail(operationType = OperationTypeEnum.SAVE, detail = "新增/修改操作，考试ID：{{printPlanParams.examId}}、计划ID：{{printPlanParams.id}}、计划名称：{{printPlanParams.name}}")
    public Result savePrintPlan(@Valid @RequestBody PrintPlanParams printPlanParams, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultUtil.error(bindingResult.getAllErrors().get(0).getDefaultMessage());
        }
        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
        printPlanParams.setSchoolId(schoolId);
        return ResultUtil.ok(examPrintPlanService.savePrintPlan(printPlanParams));
    }

    @ApiOperation(value = "印刷计划-删除")
    @RequestMapping(value = "/remove", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "删除成功", response = Result.class)})
    @OperationLogDetail(operationType = OperationTypeEnum.DELETE, detail = "删除操作，用户ID：{{deleteParams.id}}")
    public Result removePrintPlan(@Valid @RequestBody DeleteParams deleteParams, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultUtil.error(bindingResult.getAllErrors().get(0).getDefaultMessage());
        }
        return ResultUtil.ok(examPrintPlanService.removePrintPlan(deleteParams));
    }

    /**
     * 关联试卷管理-查询
     *
     * @param relateType
     * @param printPlanIdList 印刷计划id集合
     * @param courseCode
     * @param paperNumber
     * @param userName        命题老师
     * @return
     */
    @ApiOperation(value = "关联试卷管理-查询")
    @RequestMapping(value = "/relate_list", method = RequestMethod.POST)
    public Result relateList(@ApiParam(value = "学期ID") @RequestParam(required = false) String semesterId,
                             @ApiParam(value = "考试id") @RequestParam(required = false) String examId,
                             @RequestParam(value = "relateType", required = false) String relateType,
                             @RequestParam(value = "printPlanIdList", required = false) List<String> printPlanIdList,
                             @RequestParam(value = "courseCode", required = false) String courseCode,
                             @RequestParam(value = "paperNumber", required = false) String paperNumber,
                             @RequestParam(value = "userName", required = false) String userName,
                             @RequestParam(value = "cardRuleId", required = false) Long cardRuleId) {
        if (semesterId == null) {
            throw ExceptionResultEnum.ERROR.exception("请选择学期");
        }
        if (Objects.isNull(printPlanIdList)) {
            printPlanIdList = new ArrayList<>();
        }
        List<Long> idList = printPlanIdList.stream().map(SystemConstant::convertIdToLong).collect(Collectors.toList());
        List<ExamTaskDetailDto> examTasks = examTaskDetailService.list(SystemConstant.convertIdToLong(semesterId), SystemConstant.convertIdToLong(examId), relateType, idList, courseCode, paperNumber, userName, cardRuleId);
        return ResultUtil.ok(examTasks);
    }

    /**
     * 关联试卷管理-查询计划下命题任务共有的未曝光卷型
     *
     * @param relateType
     * @param printPlanIdList 印刷计划id集合
     * @param courseCode
     * @param paperNumber
     * @param userName        命题老师
     * @return
     */
    @ApiOperation(value = "关联试卷管理-查询计划下命题任务共有的未曝光卷型")
    @RequestMapping(value = "/list_relate_common_types", method = RequestMethod.POST)
    public Result relateCommonTypes(@ApiParam(value = "学期ID") @RequestParam(required = false) String semesterId,
                                    @ApiParam(value = "考试id") @RequestParam(required = false) String examId,
                                    @RequestParam(value = "relateType", required = false) String relateType,
                                    @RequestParam(value = "printPlanIdList", required = false) List<String> printPlanIdList,
                                    @RequestParam(value = "courseCode", required = false) String courseCode,
                                    @RequestParam(value = "paperNumber", required = false) String paperNumber,
                                    @RequestParam(value = "userName", required = false) String userName,
                                    @RequestParam(value = "cardRuleId", required = false) Long cardRuleId) {
        if (Objects.isNull(printPlanIdList)) {
            printPlanIdList = new ArrayList<>();
        }
        List<Long> idList = printPlanIdList.stream().map(SystemConstant::convertIdToLong).collect(Collectors.toList());
        List<String> examTasks = examTaskDetailService.listRelateCommonTypes(SystemConstant.convertIdToLong(semesterId), SystemConstant.convertIdToLong(examId), relateType, idList, courseCode, paperNumber, userName, cardRuleId);
        return ResultUtil.ok(examTasks);
    }

    /**
     * 关联试卷管理-批量关联
     *
     * @param relateType
     * @param printPlanIdList 印刷计划id集合
     * @param courseCode
     * @param paperNumber
     * @param userName        命题老师
     * @return
     */
    @ApiOperation(value = "关联试卷管理-批量关联")
    @RequestMapping(value = "/relate_update_batch", method = RequestMethod.POST)
    @OperationLogDetail(operationType = OperationTypeEnum.UPDATE)
    public Result relateUpdateBatch(@ApiParam(value = "学期ID") @RequestParam(required = false) String semesterId,
                                    @ApiParam(value = "考试id") @RequestParam(required = false) String examId,
                                    @RequestParam(value = "relateType", required = false) String relateType,
                                    @RequestParam(value = "printPlanIdList", required = false) List<String> printPlanIdList,
                                    @RequestParam(value = "courseCode", required = false) String courseCode,
                                    @RequestParam(value = "paperNumber", required = false) String paperNumber,
                                    @RequestParam(value = "userName", required = false) String userName,
                                    @RequestParam(value = "cardRuleId", required = false) Long cardRuleId) throws IOException {
        if (Objects.isNull(printPlanIdList)) {
            printPlanIdList = new ArrayList<>();
        }
        List<Long> idList = printPlanIdList.stream().map(SystemConstant::convertIdToLong).collect(Collectors.toList());
        List<ExamTaskDetailDto> examTasks = examTaskDetailService.list(SystemConstant.convertIdToLong(semesterId), SystemConstant.convertIdToLong(examId), relateType, idList, courseCode, paperNumber, userName, cardRuleId);
        for (ExamTaskDetailDto examTask : examTasks) {
            RelatePaperParam relatePaperParam = new RelatePaperParam();
            relatePaperParam.setExamDetailCourseIds(examTask.getExamDetailCourseIds());
            relatePaperParam.setExamTaskId(Long.valueOf(examTask.getId()));
            relatePaperParam.setPaperNumber(examTask.getPaperNumber());
            relatePaperParam.setPrintPlanId(Long.valueOf(examTask.getPrintPlanId()));
            relatePaperParam.setRelatePaperType(relateType);
            examTaskDetailService.updatePaper(relatePaperParam);
        }
        return ResultUtil.ok("true");
    }

    @ApiOperation(value = "关联试卷管理-查询-汇总数据")
    @RequestMapping(value = "/relate_total", method = RequestMethod.POST)
    public Result relateTotal(@ApiParam(value = "学期ID") @RequestParam(required = false) String semesterId,
                              @ApiParam(value = "考试ID") @RequestParam(required = false) String examId,
                              @RequestParam(value = "relateType", required = false) String relateType,
                              @RequestParam(value = "printPlanIdList", required = false) List<String> printPlanIdList,
                              @RequestParam(value = "courseCode", required = false) String courseCode,
                              @RequestParam(value = "paperNumber", required = false) String paperNumber,
                              @RequestParam(value = "userName", required = false) String userName,
                              @RequestParam(value = "cardRuleId", required = false) Long cardRuleId) {
        if (Objects.isNull(printPlanIdList)) {
            printPlanIdList = new ArrayList<>();
        }
        List<Long> idList = printPlanIdList.stream().map(SystemConstant::convertIdToLong).collect(Collectors.toList());
        Map map = examTaskDetailService.listTotal(SystemConstant.convertIdToLong(semesterId), SystemConstant.convertIdToLong(examId), relateType, idList, courseCode, paperNumber, userName, cardRuleId);
        return ResultUtil.ok(map);
    }

    /**
     * 关联/更换试卷
     *
     * @param paperParam
     * @return
     */
    @ApiOperation(value = "关联/更换试卷")
    @RequestMapping(value = "/relate_update", method = RequestMethod.POST)
    @OperationLogDetail(operationType = OperationTypeEnum.UPDATE, detail = "关联试卷操作，考试ID：{{paperParam.examId}}、试卷编号：{{paperParam.paperNumber}}、关联卷型：{{paperParam.relatePaperType}}")
    public Result relateUpdate(@RequestBody RelatePaperParam paperParam) throws IOException {
        boolean isSuccess = examTaskDetailService.updatePaper(paperParam);
        return ResultUtil.ok(isSuccess);
    }

    /**
     * 查询所有试卷编号/关联卷型
     *
     * @param examTaskId
     * @return
     */
    @ApiOperation(value = "查询所有试卷编号/关联卷型")
    @RequestMapping(value = "/relate_get_paper_numbers", method = RequestMethod.POST)
    public Result relateGetPaperNumbers(@RequestParam(value = "examTaskId", required = true) Long examTaskId,
                                        @RequestParam(value = "printPlanId", required = true) Long printPlanId,
                                        @RequestParam(value = "courseCode", required = true) String courseCode) {
        List<RelatePaperDto> list = examTaskService.listPaperTypes(examTaskId, printPlanId, courseCode);
        return ResultUtil.ok(list);
    }

    /**
     * 补考任务查询
     */
    @ApiOperation(value = "补考任务查询")
    @RequestMapping(value = "/list_makeup_task", method = RequestMethod.POST)
    public Result listMakeupTask(@ApiParam(value = "印刷计划", required = true) @RequestParam(value = "printPlanId") Long printPlanId,
                                 @ApiParam(value = "学期") @RequestParam(value = "semesterId", required = false) Long semesterId,
                                 @ApiParam(value = "考试") @RequestParam(value = "examId", required = false) Long examId,
                                 @ApiParam(value = "开课学院") @RequestParam(value = "collegeId", required = false) Long collegeId,
                                 @ApiParam(value = "课程代码") @RequestParam(value = "courseCode", required = false) String courseCode,
                                 @ApiParam(value = "试卷编号") @RequestParam(value = "paperNumber", required = false) String paperNumber,
                                 @ApiParam(value = "命题老师") @RequestParam(value = "userName", required = false) String userName,
                                 @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) {
        IPage<MakeupExamTaskDto> list = examTaskService.listMakeupExamTask(printPlanId, semesterId, examId, collegeId, courseCode, paperNumber, userName, pageNumber, pageSize);
        return ResultUtil.ok(list);
    }

    /**
     * 补考任务保存
     *
     * @return
     */
    @ApiOperation(value = "补考任务保存")
    @RequestMapping(value = "/save_makeup_task", method = RequestMethod.POST)
    public Result saveMakeupTask(@ApiParam(value = "补考任务") @RequestBody MakeupExamTaskTotalParam makeupExamTaskTotalParam) {
        examTaskService.saveMakeupTask(makeupExamTaskTotalParam);
        return ResultUtil.ok(true, "");
    }

}

