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

import com.qmth.boot.api.constant.ApiConstant;
import com.qmth.distributed.print.business.entity.ExamCard;
import com.qmth.distributed.print.business.entity.ExamTaskDetail;
import com.qmth.distributed.print.business.service.ExamCardService;
import com.qmth.distributed.print.business.service.ExamTaskDetailService;
import com.qmth.teachcloud.common.annotation.OperationLogDetail;
import com.qmth.teachcloud.common.bean.vo.PaperInfoVo;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.entity.MarkQuestion;
import com.qmth.teachcloud.common.enums.CardCreateMethodEnum;
import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
import com.qmth.teachcloud.common.enums.log.OperationTypeEnum;
import com.qmth.teachcloud.common.util.ExamTaskUtil;
import com.qmth.teachcloud.common.util.Result;
import com.qmth.teachcloud.common.util.ResultUtil;
import com.qmth.teachcloud.common.util.ServletUtil;
import com.qmth.teachcloud.mark.dto.mark.setting.MarkQuestionDto;
import com.qmth.teachcloud.mark.params.MarkObjectiveQuestionParams;
import com.qmth.teachcloud.mark.params.MarkQuestionParams;
import com.qmth.teachcloud.mark.service.MarkQuestionService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 小题信息表 前端控制器
 * </p>
 *
 * @author xf
 * @since 2023-09-22
 */
@Api(tags = "评卷-试卷结构")
@RestController
@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + SystemConstant.PREFIX_URL_MARK + "/question")
public class MarkQuestionController extends BaseController {
    private final static Logger log = LoggerFactory.getLogger(MarkQuestionController.class);

    @Resource
    private MarkQuestionService markQuestionService;
    @Resource
    private ExamTaskDetailService examTaskDetailService;
    @Resource
    private ExamCardService examCardService;

    /**
     * 评卷结构查询
     */
    @ApiOperation(value = "查询")
    @RequestMapping(value = "/list", method = RequestMethod.POST)
    public Result list(@ApiParam(value = "考试ID", required = true) @RequestParam Long examId,
                       @ApiParam(value = "试卷编号", required = true) @RequestParam String paperNumber,
                       @ApiParam(value = "试卷编号", required = true) @RequestParam String paperType) {
        boolean canCreate = false;
        ExamTaskDetail examTaskDetail = examTaskDetailService.findByExamIdAndCourseCodeAndPaperNumber(examId, null, paperNumber);
        if (examTaskDetail == null) {
            canCreate = true;
        } else {
            List<PaperInfoVo> paperInfoVoList = ExamTaskUtil.parsePaperAttachmentPath(examTaskDetail.getPaperAttachmentIds(), paperType);
            PaperInfoVo paperInfoVo = paperInfoVoList.get(0);
            if (paperInfoVo.getCardId() != null) {
                ExamCard examCard = examCardService.getById(paperInfoVo.getCardId());
                if (examCard != null) {
                    if (CardCreateMethodEnum.UPLOAD.equals(examCard.getCreateMethod())) {
                        canCreate = true;
                    }
                }
            }
        }
        MarkQuestionDto markQuestionDto = markQuestionService.pageQuestionsByExamIdAndPaperNumber(examId, paperNumber, paperType, canCreate);
        return ResultUtil.ok(markQuestionDto);
    }

    /**
     * 评卷结构保存
     */
    @ApiOperation(value = "提交")
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    @OperationLogDetail(operationType = OperationTypeEnum.ADD, detail = "提交评卷结构，考试ID：{{markQuestionParams.examId}}、试卷编号：{{markQuestionParams.paperNumber}}")
    public Result save(@RequestBody MarkQuestionParams markQuestionParams) {
        validMarkPaperForMark(markQuestionParams.getExamId(), markQuestionParams.getPaperNumber());
        markQuestionService.saveQuestions(markQuestionParams);
        return ResultUtil.ok(true);
    }

    /**
     * 客观题标答查询
     */
    @ApiOperation(value = "客观题标答查询")
    @RequestMapping(value = "/objective/list", method = RequestMethod.POST)
    public Result listObjective(@ApiParam(value = "考试ID", required = true) @RequestParam Long examId,
                                @ApiParam(value = "试卷编号", required = true) @RequestParam String paperNumber) {
        List<MarkQuestion> markQuestionList = markQuestionService.listQuestionByExamIdAndPaperNumberAndGroupNumber(examId, paperNumber, null, true);
        return ResultUtil.ok(markQuestionList);
    }

    /**
     * 客观题标答保存
     */
    @ApiOperation(value = "客观题标答提交")
    @RequestMapping(value = "/objective/save", method = RequestMethod.POST)
    @OperationLogDetail(operationType = OperationTypeEnum.ADD, detail = "客观题标答提交操作，考试ID：{{markObjectiveQuestionParams.examId}}、试卷编号：{{markObjectiveQuestionParams.paperNumber}}")
    public Result saveObjective(@RequestBody MarkObjectiveQuestionParams markObjectiveQuestionParams) {
        markQuestionService.saveObjectiveQuestions(markObjectiveQuestionParams);
        return ResultUtil.ok(true);
    }

    /**
     * 客观题模板导出
     */
    @ApiOperation(value = "客观题模板导出")
    @RequestMapping(value = "/objective/export", method = RequestMethod.POST)
    public Result objectiveExport(@ApiParam(value = "考试ID", required = true) @RequestParam String examId,
            @ApiParam(value = "试卷编号", required = true) @RequestParam String paperNumber, HttpServletResponse response)
            throws Exception {
        markQuestionService.objectiveAnswerSettingModelExport(SystemConstant.convertIdToLong(examId), paperNumber,
                response);
        return ResultUtil.ok();
    }

    /**
     * 客观题标答导入
     */
    @ApiOperation(value = "客观题标答导入")
    @RequestMapping(value = "/objective/import", method = RequestMethod.POST)
    @OperationLogDetail(operationType = OperationTypeEnum.IMPORT, detail = "客观题标答导入操作，考试ID：{{examId}}、试卷编号：{{paperNumber}}")
    public Result objectiveImport(@ApiParam(value = "考试ID", required = true) @RequestParam String examId,
            @ApiParam(value = "试卷编号", required = true) @RequestParam String paperNumber,
            @ApiParam(value = "标答excel文件",required = true) @RequestParam MultipartFile file) throws Exception {
        String md5 = ServletUtil.getRequestMd5();
        String fileMd5 = DigestUtils.md5Hex(file.getBytes());
        log.info("fileMd5:{}", fileMd5);
        log.info("md5:{}", md5);
        if (!Objects.equals(fileMd5, md5)) {
            throw ExceptionResultEnum.MD5_EQUALS_FALSE.exception();
        }
        markQuestionService.objectiveAnswerSettingImport(SystemConstant.convertIdToLong(examId), paperNumber, file);
        return ResultUtil.ok();
    }

    /**
     * 主观题标答文件查询
     */
    @ApiOperation(value = "主观题标答文件查询")
    @RequestMapping(value = "/subjective/get", method = RequestMethod.POST)
    public Result getSubjective(@ApiParam(value = "考试ID", required = true) @RequestParam Long examId,
                                @ApiParam(value = "试卷编号", required = true) @RequestParam String paperNumber) {
        return ResultUtil.ok(markQuestionService.previewAnswerFileByExamIdAndPaperNumber(examId, paperNumber), null);
    }

    /**
     * 主观题标答文件上传
     */
    @ApiOperation(value = "主观题标答文件上传")
    @RequestMapping(value = "/subjective/upload", method = RequestMethod.POST)
    @OperationLogDetail(operationType = OperationTypeEnum.ADD, detail = "主观题标答文件上传操作，考试ID：{{examId}}、试卷编号：{{paperNumber}}")
    public Result uploadSubjective(@ApiParam(value = "考试ID", required = true) @RequestParam Long examId,
                                   @ApiParam(value = "试卷编号", required = true) @RequestParam String paperNumber,
                                   @ApiParam(value = "文件", required = true) @RequestParam MultipartFile file,
                                   @ApiParam(value = "文件md5", required = true) @RequestParam String md5) {

        return ResultUtil.ok(markQuestionService.uploadSubjectiveFile(examId, paperNumber, file, md5), "");
    }
}
