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

import com.qmth.boot.api.constant.ApiConstant;
import com.qmth.boot.core.concurrent.service.ConcurrentService;
import com.qmth.boot.core.exception.ParameterException;
import com.qmth.boot.core.exception.ReentrantException;
import com.qmth.distributed.print.business.service.BasicExamService;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.entity.BasicExam;
import com.qmth.teachcloud.common.service.TeachcloudCommonService;
import com.qmth.teachcloud.common.util.Result;
import com.qmth.teachcloud.common.util.ResultUtil;
import com.qmth.teachcloud.mark.bean.UriVo;
import com.qmth.teachcloud.mark.bean.answercard.AnswerCardSaveDomain;
import com.qmth.teachcloud.mark.bean.answercard.AnswerCardSaveVo;
import com.qmth.teachcloud.mark.entity.ScanAnswerCard;
import com.qmth.teachcloud.mark.enums.LockType;
import com.qmth.teachcloud.mark.service.ScanAnswerCardService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;

/**
 * <p>
 * 题卡卡格式表 前端控制器
 * </p>
 *
 * @author xf
 * @since 2023-09-22
 */
@Api(tags = "扫描-卡格式")
@RestController
@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + SystemConstant.PREFIX_URL_SCAN + "/answer/card")
public class ScanAnswerCardController extends BaseController {

    @Autowired
    private ScanAnswerCardService scanAnswerCardService;

    @Autowired
    private ConcurrentService concurrentService;

    @Autowired
    private BasicExamService basicExamService;
    @Resource
    private TeachcloudCommonService teachcloudCommonService;

    @ApiOperation(value = "答题卡卡格式列表")
    @RequestMapping(value = "list", method = RequestMethod.POST)
    public Result cardList(@RequestParam Long examId,
                           @RequestParam(required = false) String coursePaperId) {
        return ResultUtil.ok(scanAnswerCardService.cardList(examId, coursePaperId));
    }

    @ApiOperation(value = "创建/修改题卡卡格式")
    @RequestMapping(value = "save", method = RequestMethod.POST)
    public Result cardSave(@RequestParam Integer dpi, @RequestParam Long examId,
                           @RequestParam String coursePaperId, @RequestParam String md5,
                           @RequestParam(required = false) Integer number, @RequestParam(required = false) String remark,
                           @RequestParam Integer paperCount, @RequestParam MultipartFile file) {
        validMarkPaperForScan(examId, coursePaperId);
        BasicExam exam = basicExamService.getById(examId);
        if (exam == null) {
            throw new ParameterException("未找到考试信息");
        }
        AnswerCardSaveDomain domain = new AnswerCardSaveDomain(number, examId, coursePaperId, remark, paperCount, file, md5, dpi);
        if (concurrentService.getLock(LockType.CARD_SAVE + "-" + examId).tryLock()) {
            try {
                ScanAnswerCard scanAnswerCard = scanAnswerCardService.cardSave(domain);
                AnswerCardSaveVo vo = new AnswerCardSaveVo(scanAnswerCard.getExamId(), scanAnswerCard.getCoursePaperId(), scanAnswerCard.getMd5(), teachcloudCommonService.filePreview(scanAnswerCard.getUri()), scanAnswerCard.getNumber(), System.currentTimeMillis());
                return ResultUtil.ok(vo);
            } finally {
                concurrentService.getLock(LockType.CARD_SAVE + "-" + examId).unlock();
            }
        } else {
            throw new ReentrantException("正在处理卡格式，请稍后再试");
        }
    }

    @ApiOperation(value = "删除答题卡卡格式")
    @RequestMapping(value = "delete", method = RequestMethod.POST)
    public Result cardDelete(@RequestParam Long examId, @RequestParam Integer number) {
        BasicExam exam = basicExamService.getById(examId);
        if (exam == null) {
            throw new ParameterException("未找到考试信息");
        }
        ScanAnswerCard card = scanAnswerCardService.findByExamAndNumber(examId, number);
        if (card == null) {
            throw new ParameterException("未找到卡格式信息");
        }
        validMarkPaperForScan(card.getExamId(), card.getCoursePaperId());
        if (concurrentService.getLock(LockType.CARD_SAVE + "-" + examId).tryLock()) {
            try {
                scanAnswerCardService.cardDelete(card);
                AnswerCardSaveVo vo = new AnswerCardSaveVo(number, System.currentTimeMillis());
                return ResultUtil.ok(vo);
            } finally {
                concurrentService.getLock(LockType.CARD_SAVE + "-" + examId).unlock();
            }
        } else {
            throw new ReentrantException("正在处理卡格式，请稍后再试");
        }
    }

    @ApiOperation(value = "答题卡适配卡格式上传")
    @RequestMapping(value = "adapte/upload", method = RequestMethod.POST)
    public Result adapteUpload(@RequestParam Long examId, @RequestParam String coursePaperId,
                               @RequestParam Integer cardNumber, @RequestParam MultipartFile file, @RequestParam String md5,
                               @RequestParam Integer dpi, @RequestParam(required = false) String remark) {
        validMarkPaperForScan(examId, coursePaperId);
        BasicExam exam = basicExamService.getById(examId);
        if (exam == null) {
            throw new ParameterException("未找到考试信息");
        }
        if (concurrentService.getLock(LockType.CARD_SAVE + "-" + examId).tryLock()) {
            try {
                UriVo uriVo = scanAnswerCardService.adapteUpload(examId, coursePaperId, cardNumber, md5, dpi, file, remark);
                return ResultUtil.ok(uriVo);
            } finally {
                concurrentService.getLock(LockType.CARD_SAVE + "-" + examId).unlock();
            }
        } else {
            throw new ReentrantException("正在处理卡格式，请稍后再试");
        }
    }

    @ApiOperation(value = "答题卡卡格式查询")
    @RequestMapping(value = "get", method = RequestMethod.POST)
    public Result cardGet(@RequestParam Long examId, @RequestParam Integer number) {
        return ResultUtil.ok(scanAnswerCardService.cardGet(examId, number));
    }
}
