package com.qmth.distributed.print.api;

import com.qmth.boot.api.constant.ApiConstant;
import com.qmth.boot.api.exception.ApiException;
import com.qmth.distributed.print.business.bean.dto.ExamTaskDto;
import com.qmth.distributed.print.business.bean.dto.ExamTaskImportResultDto;
import com.qmth.distributed.print.business.entity.ExamTask;
import com.qmth.distributed.print.business.entity.ExamTaskApplyTemp;
import com.qmth.distributed.print.business.service.*;
import com.qmth.teachcloud.common.annotation.OperationLogDetail;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.entity.BasicAttachment;
import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
import com.qmth.teachcloud.common.enums.UploadFileEnum;
import com.qmth.teachcloud.common.enums.log.OperationTypeEnum;
import com.qmth.teachcloud.common.service.BasicAttachmentService;
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.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
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.util.ArrayList;
import java.util.List;
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 + "/task")
@Validated
public class ExamTaskController {

    @Resource
    private ExamTaskService examTaskService;

    @Resource
    private BasicAttachmentService basicAttachmentService;

    @Resource
    private PrintCommonService printCommonService;

    @Resource
    private ExamTaskPrintService examTaskPrintService;

    @Resource
    ActivitiService activitiService;

    @Resource
    ExamTaskApplyTempService examTaskApplyTempService;

    /**
     * 命题任务管理-查询
     *
     * @param enable      正常/禁用
     * @param status      状态
     * @param cardRuleId  题卡规则ID
     * @param courseCode  课程代码
     * @param paperNumber 试卷编号
     * @param startTime   开始时间
     * @param endTime     结束时间
     * @param userName    命题老师名称
     * @param createName  创建人名称
     * @param pageNumber  分页参数
     * @param pageSize    分页参数
     * @return Result
     */
    @ApiOperation(value = "命题任务管理-分页查询")
    @RequestMapping(value = "/list", method = RequestMethod.POST)
    public Result list(@RequestParam(required = false) String semesterId,
                       @RequestParam(required = false) String examId,
                       @RequestParam(required = false) Boolean enable,
                       @RequestParam(required = false) String status,
                       @RequestParam(required = false) String cardRuleId,
                       @RequestParam(required = false) String courseCode,
                       @RequestParam(required = false) String paperNumber,
                       @RequestParam(required = false) Long startTime,
                       @RequestParam(required = false) Long endTime,
                       @RequestParam(required = false) String userName,
                       @RequestParam(required = false) String createName,
                       @RequestParam @Min(SystemConstant.PAGE_NUMBER_MIN) Integer pageNumber,
                       @RequestParam @Min(SystemConstant.PAGE_SIZE_MIN) @Max(SystemConstant.PAGE_SIZE_MAX) Integer pageSize) {
        if(examId == null){
            throw ExceptionResultEnum.EXAM_ID_IS_NULL.exception();
        }
        return ResultUtil.ok(examTaskService.list(SystemConstant.convertIdToLong(semesterId), SystemConstant.convertIdToLong(examId), enable, status, SystemConstant.convertIdToLong(cardRuleId), courseCode, paperNumber, startTime, endTime, userName, createName, pageNumber, pageSize));
    }

    /**
     * 命题老师模糊查询
     */
    @ApiOperation(value = "命题老师模糊查询")
    @RequestMapping(value = "/user_query", method = RequestMethod.POST)
    public Result userQuery(@RequestParam(value = "param", required = false) String param) {
        return ResultUtil.ok(examTaskService.listUser(param));
    }

    /**
     * 命题任务管理-更改/指派命题老师
     */
    @ApiOperation(value = "命题任务管理-更改/指派命题老师")
    @RequestMapping(value = "/assign_user", method = RequestMethod.POST)
    @OperationLogDetail(operationType = OperationTypeEnum.UPDATE, detail = "更改/指派命题老师操作，命题任务ID：{{examTask.id}}、命题老师ID：{{examTask.userId}}")
    public Result assignUser(@RequestBody ExamTask examTask) {
        examTask = examTaskService.assignUser(examTask);
        if (Objects.nonNull(examTask.getFlowId())) {
            activitiService.sendFlowStartMsg(examTask.getFlowId());
        }
        return ResultUtil.ok(true);
    }

    /**
     * 命题任务管理-启用/禁用
     */
    @ApiOperation(value = "命题任务管理-启用/禁用")
    @RequestMapping(value = "/enable", method = RequestMethod.POST)
    @OperationLogDetail(operationType = OperationTypeEnum.UPDATE, detail = "启用/禁用命题任务操作，命题任务ID：{{examTask.id}}、启用/禁用：{{examTask.enable}}")
    public Result enable(@RequestBody ExamTask examTask) {
        return ResultUtil.ok(examTaskService.enable(examTask));
    }

    /**
     * 命题任务管理-新建命题任务
     */
    @ApiOperation(value = "命题任务管理-新建命题任务")
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    @OperationLogDetail(operationType = OperationTypeEnum.ADD, detail = "新建命题任务操作，命题任务ID：{{examTask.id}}、课程代码：{{examTask.courseCode}}")
    public Result save(@RequestBody ExamTask examTask) {
        examTaskService.saveExamTaskNew(examTask);
        if (Objects.nonNull(examTask.getFlowId())) {
            activitiService.sendFlowStartMsg(examTask.getFlowId());
        }
        return ResultUtil.ok(true);
    }

    /**
     * 命题任务管理-删除
     */
    @ApiOperation(value = "命题任务管理-删除")
    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    @OperationLogDetail(operationType = OperationTypeEnum.DELETE, detail = "删除命题任务操作，命题任务ID：{{id}}")
    public Result delete(@RequestParam Long id) {
        examTaskService.delete(id);
        return ResultUtil.ok(true);
    }

    /**
     * 命题任务管理-文件导入
     */
    @ApiOperation(value = "命题任务管理-批量新建命题任务-文件导入")
    @RequestMapping(value = "/import", method = RequestMethod.POST)
    @OperationLogDetail(operationType = OperationTypeEnum.IMPORT)
    public Result importFile(@ApiParam(value = "上传文件", required = true) @RequestParam MultipartFile file) {
        BasicAttachment basicAttachment = null;
        try {
            basicAttachment = printCommonService.saveAttachment(file, ServletUtil.getRequestMd5(), UploadFileEnum.FILE);
            if (Objects.isNull(basicAttachment)) {
                throw ExceptionResultEnum.ATTACHMENT_ERROR.exception();
            } else {
                ExamTaskImportResultDto examTaskImportResultDto = examTaskService.importFile(file);
                return ResultUtil.ok(examTaskImportResultDto);
            }
        } catch (Exception e) {
            if (Objects.nonNull(basicAttachment)) {
                basicAttachmentService.deleteAttachment(basicAttachment);
            }
            if (e instanceof ApiException) {
                ResultUtil.error((ApiException) e, ((ApiException) e).getCode(), e.getMessage());
            } else {
                ResultUtil.error(e.getMessage());
            }
        }
        return null;
    }

    /**
     * 命题任务管理-批量保存命题任务
     */
    @ApiOperation(value = "命题任务管理-批量新建命题任务-保存")
    @RequestMapping(value = "/save_batch", method = RequestMethod.POST)
    @OperationLogDetail(operationType = OperationTypeEnum.ADD)
    public Result saveBatch(@RequestBody ExamTask task) {
        examTaskService.saveBatch(task);
        return ResultUtil.ok(true);
    }

    /**
     * 根据命题任务ID查询单个数据
     *
     * @param examTaskId 命题任务ID
     * @return Result
     */
    @ApiOperation(value = "根据命题任务ID查询任务详情数据")
    @RequestMapping(value = "/exam_task_get_one", method = RequestMethod.POST)
    public Result applyGetOne(@RequestParam(value = "examTaskId") Long examTaskId) {
        ExamTaskDto examTaskDto = examTaskService.getByExamTaskId(examTaskId);
        return ResultUtil.ok(examTaskDto);
    }

    /**
     * 班级列表
     *
     * @param courseCode 课程代码
     * @return Result
     */
    @ApiOperation(value = "命题任务管理-命题申请-班级列表")
    @RequestMapping(value = "/list_task_apply_class", method = RequestMethod.POST)
    public Result listTaskApplyClass(@RequestParam(value = "courseCode") String courseCode) {
        return ResultUtil.ok(examTaskPrintService.listExamTaskClass(courseCode));
    }

    /**
     * 命题任务管理-命题申请-暂存
     *
     * @param examTaskApplyTemp
     * @return
     */
    @ApiOperation(value = "命题任务管理-命题申请-暂存")
    @RequestMapping(value = "/stage_task_apply", method = RequestMethod.POST)
    @OperationLogDetail(operationType = OperationTypeEnum.SAVE)
    public Result stageTaskApply(@RequestBody ExamTaskApplyTemp examTaskApplyTemp) {
        ExamTaskApplyTemp task = examTaskApplyTempService.stageTaskApply(examTaskApplyTemp);
        return ResultUtil.ok(task);
    }

    /**
     * 试卷编号模糊查询
     */
    @ApiOperation(value = "试卷编号模糊查询")
    @RequestMapping(value = "/paper_number_query", method = RequestMethod.POST)
    public Result paperNumberQuery(@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(examTaskService.listPaperNumber(param, printPlanIdList));
    }
}

