package com.qmth.themis.admin.api;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qmth.themis.business.annotation.Logs;
import com.qmth.themis.business.cache.bean.ExamCacheBean;
import com.qmth.themis.business.cache.bean.ExamCourseCacheBean;
import com.qmth.themis.business.cache.bean.ExamPaperCacheBean;
import com.qmth.themis.business.constant.SystemConstant;
import com.qmth.themis.business.dto.MqDto;
import com.qmth.themis.business.entity.*;
import com.qmth.themis.business.enums.*;
import com.qmth.themis.business.service.*;
import com.qmth.themis.business.util.MqUtil;
import com.qmth.themis.business.util.OssUtil;
import com.qmth.themis.business.util.ServletUtil;
import com.qmth.themis.business.util.UidUtil;
import com.qmth.themis.common.enums.ExceptionResultEnum;
import com.qmth.themis.common.exception.BusinessException;
import com.qmth.themis.common.util.GsonUtil;
import com.qmth.themis.common.util.Result;
import com.qmth.themis.common.util.ResultUtil;
import io.swagger.annotations.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.*;

/**
 * @Description: 考试试卷 前端控制器
 * @Param:
 * @return:
 * @Author: wangliang
 * @Date: 2020/6/25
 */
@Api(tags = "考试试卷Controller")
@RestController
@RequestMapping(SystemConstant.PREFIX_URL_ADMIN + "/exam/paper")
public class TEExamPaperController {

    private final static Logger log = LoggerFactory.getLogger(TEExamPaperController.class);

    @Resource
    TEExamPaperService teExamPaperService;

    @Resource
    TBTaskHistoryService taskHistoryService;

    @Resource
    TEExamService teExamService;

    @Resource
    TBAttachmentService tbAttachmentService;

    @Resource
    MqDtoService mqDtoService;

    @Resource
    OssUtil ossUtil;

    @Resource
    MqUtil mqUtil;

    @Resource
    TEExamCourseService examCourseService;

    @Resource
    TOeExamRecordService tOeExamRecordService;

    @ApiOperation(value = "考试试卷查询接口")
    @RequestMapping(value = "/query", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "考试科目信息", response = TEExamPaper.class)})
    public Result query(@ApiParam(value = "考试批次id", required = true) @RequestParam Long examId,
                        @ApiParam(value = "科目编码", required = true) @RequestParam String courseCode) {
        if (Objects.isNull(examId) || Objects.equals(examId, "")) {
            throw new BusinessException(ExceptionResultEnum.EXAM_ID_IS_NULL);
        }
        if (Objects.isNull(courseCode) || Objects.equals(courseCode, "")) {
            throw new BusinessException(ExceptionResultEnum.COURSE_CODE_IS_NULL);
        }
        QueryWrapper<TEExamPaper> teExamPaperQueryWrapper = new QueryWrapper<>();
        teExamPaperQueryWrapper.lambda().eq(TEExamPaper::getExamId, examId).eq(TEExamPaper::getCourseCode, courseCode);
        return ResultUtil.ok(teExamPaperService.list(teExamPaperQueryWrapper));
    }

    @ApiOperation(value = "考试试卷参数修改接口")
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    @Transactional
    @ApiResponses({@ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class)})
    @Logs(value = LogEnum.EXAM_PAPER)
    public Result save(@ApiParam(value = "考试试卷信息", required = true) @RequestBody List<TEExamPaper> teExamPaperList) {
        if (Objects.isNull(teExamPaperList) || teExamPaperList.size() == 0) {
            throw new BusinessException(ExceptionResultEnum.PAPER_INFO_IS_NULL);
        }
        try {
            TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
            teExamPaperList.forEach(s -> {
                if (Objects.isNull(s.getId())) {
                    s.setId(UidUtil.nextId());
                    s.setCreateTime(System.currentTimeMillis());
                }
                s.setUpdateId(tbUser.getId());
                s.setUpdateTime(System.currentTimeMillis());
                teExamPaperService.saveOrUpdate(s);
            });
        } catch (Exception e) {
            log.error(SystemConstant.LOG_ERROR, e);
            if (e instanceof DuplicateKeyException) {
                String errorColumn = e.getCause().toString();
                String columnStr = errorColumn.substring(errorColumn.lastIndexOf("key") + 3, errorColumn.length())
                        .replaceAll("'", "");
                throw new BusinessException(
                        "机构id[" + teExamPaperList.get(0).getExamId() + "]下的" + FieldUniqueEnum.convertToCode(columnStr)
                                + "数据不允许重复插入");
            } else if (e instanceof BusinessException) {
                throw new BusinessException(e.getMessage());
            } else {
                throw new RuntimeException(e);
            }
        }
        teExamPaperList.forEach(s -> {
            teExamPaperService.updateExamPaperCacheBean(s.getId());
            ExamPaperCacheBean paper = teExamPaperService.getExamPaperCacheBean(s.getId());
            examCourseService.updateExamCourseCacheBean(paper.getExamId(), paper.getCourseCode());
        });
        return ResultUtil.ok(true);
    }

    @ApiOperation(value = "考试试卷数据包上传接口")
    @RequestMapping(value = "/import", method = RequestMethod.POST)
    @Transactional
    @ApiResponses({@ApiResponse(code = 200, message = "{\"taskId\":0}", response = Result.class)})
    public Result importData(@ApiParam(value = "上传文件", required = true) @RequestParam MultipartFile file,
                             @ApiParam(value = "批次ID", required = true) @RequestParam Long examId,
                             @ApiParam(value = "客观题乱序", required = true) @RequestParam Boolean objectiveShuffle,
                             @ApiParam(value = "选项乱序", required = true) @RequestParam Boolean optionShuffle,
                             @ApiParam(value = "音频播放次数", required = true) @RequestParam Integer audioPlayCount,
                             @ApiParam(value = "是否允许使用移动端拍照答题", required = true) @RequestParam Integer mobilePhotoUpload,
                             @ApiParam(value = "解析试卷", required = true) @RequestParam Boolean processPaper,
                             @ApiParam(value = "解析标答", required = true) @RequestParam Boolean processAnswer) {
        if (file == null) {
            throw new BusinessException(ExceptionResultEnum.ATTACHMENT_IS_NULL);
        }
        if (examId == null) {
            throw new BusinessException(ExceptionResultEnum.EXAM_ID_IS_NULL);
        }
        Map<String, Object> mapParameter = ossUtil.getAliYunOssPrivateDomain().getMap();
        TBAttachment tbAttachment = null;
        TBTaskHistory tbTaskHistory = null;
        Map<String, Object> transMap = new HashMap<String, Object>();
        try {
            TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
            tbAttachment = tbAttachmentService
                    .saveAttachment(file, ServletUtil.getRequestMd5(), ServletUtil.getRequestPath(), mapParameter,
                            UploadFileEnum.file, tbUser.getOrgId(), tbUser.getId());
            if (Objects.isNull(tbAttachment)) {
                throw new BusinessException(ExceptionResultEnum.ATTACHMENT_ERROR);
            } else {
                //往任务表里插一条数据
                tbTaskHistory = new TBTaskHistory(TaskTypeEnum.IMPORT_EXAM_PAPER, examId, TaskStatusEnum.INIT,
                        SystemConstant.IMPORT_INIT, 0d, tbAttachment.getName(), tbAttachment.getRemark(),
                        tbUser.getId(), tbUser.getOrgId());
                tbTaskHistory.setExamId(examId);
                taskHistoryService.save(tbTaskHistory);
                transMap.put("tbTaskHistory", tbTaskHistory);
            }
            transMap.put(SystemConstant.EXAM_ID, examId);
            transMap.put(SystemConstant.CREATE_ID, tbUser.getId());
            transMap.put(SystemConstant.ORG_ID, tbUser.getOrgId());
            //先查询考试相关信息
            ExamCacheBean examCacheBean = teExamService.getExamCacheBean(examId);
            Optional.ofNullable(examCacheBean).orElseThrow(() -> new BusinessException(ExceptionResultEnum.EXAM_NO));

//            TEExam teExam = teExamService.cacheConvert(examCacheBean);
            transMap.put("objectiveShuffle", objectiveShuffle);
            transMap.put("optionShuffle", optionShuffle);
            transMap.put("audioPlayCount", audioPlayCount);
            transMap.put("processPaper", processPaper);
            transMap.put("processAnswer", processAnswer);
            transMap.put("mobilePhotoUpload", mobilePhotoUpload);
            transMap.put(SystemConstant.REMARK, tbAttachment.getRemark());
            //mq发送消息start
            MqDto mqDto = new MqDto(mqUtil.getTopic(), MqTagEnum.EXAM_PAPER_IMPORT.name(), transMap,
                    MqTagEnum.EXAM_PAPER_IMPORT, String.valueOf(tbTaskHistory.getId()), tbUser.getName());
            mqDtoService.assembleSendAsyncMsg(mqDto);
            //mq发送消息end
        } catch (Exception e) {
            log.error(SystemConstant.LOG_ERROR, e);
            if (Objects.nonNull(tbAttachment)) {
                tbAttachmentService.deleteAttachment(mapParameter, UploadFileEnum.file, tbAttachment);
            }
            if (e instanceof BusinessException) {
                throw new BusinessException(e.getMessage());
            } else {
                throw new RuntimeException(e);
            }
        }
        return ResultUtil.ok(Collections.singletonMap(SystemConstant.TASK_ID, tbTaskHistory.getId()));
    }

    @ApiOperation(value = "试卷删除接口")
    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "常规信息", response = Result.class)})
    @Transactional
    public Result delete(@ApiParam(value = "试卷id", required = true) @RequestParam Long id) {
        int count = tOeExamRecordService.count(new QueryWrapper<TOeExamRecord>().lambda().eq(TOeExamRecord::getPaperId, id));
        if (count > 0) {
            throw new BusinessException("该试卷已存在考试记录，无法删除");
        }
        ExamPaperCacheBean examPaperCacheBean = teExamPaperService.getExamPaperCacheBean(id);
        Optional.ofNullable(examPaperCacheBean).orElseThrow(() -> new BusinessException("试卷数据为空"));

        ExamCourseCacheBean examCourseCacheBean = examCourseService.getExamCourseCacheBean(examPaperCacheBean.getExamId(), examPaperCacheBean.getCourseCode());
        Optional.ofNullable(examCourseCacheBean).orElseThrow(() -> new BusinessException("科目数据为空"));

        Integer paperCount = Objects.nonNull(examCourseCacheBean.getPaperCount()) ? examCourseCacheBean.getPaperCount() : 0;
        paperCount = paperCount.intValue() - 1;
        examCourseCacheBean.setPaperCount(Objects.isNull(paperCount) || paperCount.intValue() < 0 ? 0 : paperCount);
        TEExamCourse teExamCourse = GsonUtil.fromJson(GsonUtil.toJson(examCourseCacheBean), TEExamCourse.class);
        teExamCourse.setUpdateTime(System.currentTimeMillis());
        examCourseService.saveOrUpdate(teExamCourse);
        examCourseService.updateExamCourseCacheBean(examPaperCacheBean.getExamId(), examPaperCacheBean.getCourseCode());

        teExamPaperService.removeById(id);
        teExamPaperService.deleteExamPaperCacheBean(id);
        return ResultUtil.ok(true);
    }
}
