package com.qmth.themis.admin.api;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qmth.themis.business.annotation.Logs;
import com.qmth.themis.business.cache.bean.ExamActivityCacheBean;
import com.qmth.themis.business.cache.bean.ExamCacheBean;
import com.qmth.themis.business.constant.SystemConstant;
import com.qmth.themis.business.entity.TBAttachment;
import com.qmth.themis.business.entity.TBUser;
import com.qmth.themis.business.entity.TEAudio;
import com.qmth.themis.business.entity.TEExamActivity;
import com.qmth.themis.business.enums.ExamModeEnum;
import com.qmth.themis.business.enums.FieldUniqueEnum;
import com.qmth.themis.business.enums.LogEnum;
import com.qmth.themis.business.enums.MonitorVideoSourceEnum;
import com.qmth.themis.business.service.*;
import com.qmth.themis.business.service.impl.TEExamActivityServiceImpl;
import com.qmth.themis.business.util.OssUtil;
import com.qmth.themis.business.util.ServletUtil;
import com.qmth.themis.common.exception.BusinessException;
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.util.CollectionUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import java.io.File;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * @Description: 考试场次 前端控制器
 * @Param:
 * @return:
 * @Author: wangliang
 * @Date: 2020/6/25
 */
@Api(tags = "考试场次Controller")
@RestController
@RequestMapping(SystemConstant.PREFIX_URL_ADMIN + "/activity")
@Validated
public class TEExamActivityController {
    private final static Logger log = LoggerFactory.getLogger(TEExamActivityServiceImpl.class);

    @Resource
    private TEExamActivityService teExamActivityService;

    @Resource
    private TEExamPaperService examPaperService;

    @Resource
    TEAudioService teAudioService;

    @Resource
    OssUtil ossUtil;

    @Resource
    TEExamService teExamService;

    @Resource
    ThemisCacheService themisCacheService;

    @Resource
    TOeExamRecordService tOeExamRecordService;

    @ApiOperation(value = "考试场次修改/新增接口")
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    @Transactional
    @ApiResponses({@ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class)})
    @Logs(value = LogEnum.EXAM_ACTIVITY)
    public Result save(
            @ApiParam(value = "考试场次信息", required = true) @RequestBody List<TEExamActivity> teExamActivityList) {
        teExamActivityService.saveExamActivity(teExamActivityList);
        examPaperService.disposeObjectiveAnswer(teExamActivityList.get(0).getExamId());
        return ResultUtil.ok(true);
    }

    @ApiOperation(value = "考试场次查询接口")
    @RequestMapping(value = "/query", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "考试场次信息", response = TEExamActivity.class)})
    public Result query(@ApiParam(value = "主键", required = false) @RequestParam(required = false) Long id,
                        @ApiParam(value = "考试批次id", required = false) @RequestParam(required = false) Long examId,
                        @ApiParam(value = "考试场次编码", required = false) @RequestParam(required = false) String code,
                        @ApiParam(value = "开始日期", required = false) @RequestParam(required = false) Long startDate,
                        @ApiParam(value = "结束日期", required = false) @RequestParam(required = false) Long finishDate,
                        @ApiParam(value = "分页页码", required = true) @RequestParam @Min(SystemConstant.PAGE_NUMBER_MIN) int pageNumber,
                        @ApiParam(value = "分页数", required = true) @RequestParam @Min(SystemConstant.PAGE_SIZE_MIN) @Max(SystemConstant.SELECT_PAGE_SIZE_MAX) int pageSize) {
        return ResultUtil.ok(teExamActivityService
                .examActivityQuery(new Page<>(pageNumber, pageSize), id, examId, code, startDate, finishDate));
    }

    @ApiOperation(value = "考试场次语音查询接口")
    @RequestMapping(value = "/audio/query", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "考试场次语音信息", response = TEAudio.class)})
    public Result audioQuery(@ApiParam(value = "考试场次id", required = true) @RequestParam Long activityId,
                             @ApiParam(value = "分页页码", required = true) @RequestParam @Min(SystemConstant.PAGE_NUMBER_MIN) int pageNumber,
                             @ApiParam(value = "分页数", required = true) @RequestParam @Min(SystemConstant.PAGE_SIZE_MIN) @Max(SystemConstant.PAGE_SIZE_MAX) int pageSize) {
        IPage<TEAudio> teAudioIPage = teAudioService.query(new Page<>(pageNumber, pageSize), activityId);
        if (Objects.nonNull(teAudioIPage) && !CollectionUtils.isEmpty(teAudioIPage.getRecords())) {
            for (TEAudio t : teAudioIPage.getRecords()) {
                if (Objects.nonNull(t.getAttachmentId())) {
                    TBAttachment tbAttachment = themisCacheService.attachmentCache(t.getAttachmentId());
                    if (Objects.nonNull(tbAttachment) && Objects.nonNull(tbAttachment.getRemark())) {
                        JSONObject jsonObject = JSONObject.parseObject(tbAttachment.getRemark());
                        t.setAttachmentPath(ossUtil.getAliYunOssPublicDomain().getPublicUrl() + File.separator + jsonObject.getString(SystemConstant.PATH));
                    }
                    t.setAttachmentName(tbAttachment.getName() + tbAttachment.getType());
                }
            }
        }
        return ResultUtil.ok(teAudioIPage);
    }

    @ApiOperation(value = "考试场次语音保存接口")
    @RequestMapping(value = "/audio/save", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "常规信息", response = Result.class)})
    @Transactional
    public Result audioSave(@Validated @RequestBody TEAudio teAudio, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultUtil.error(bindingResult.getAllErrors().get(0).getDefaultMessage());
        }
        ExamActivityCacheBean examActivityCacheBean = null;
        try {
            TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
            teAudio.setOrgId(Objects.nonNull(tbUser.getOrgId()) ? tbUser.getOrgId() : -1L);
            examActivityCacheBean = teExamActivityService.getExamActivityCacheBean(teAudio.getActivityId());
            ExamCacheBean examCacheBean = teExamService.getExamCacheBean(examActivityCacheBean.getExamId());
            if (Objects.nonNull(examCacheBean) && examCacheBean.getMode() == ExamModeEnum.ANYTIME) {
                throw new BusinessException("只有集中统一的考试才能使用语音播报");
            }
            if (Objects.nonNull(examCacheBean.getForceFinish()) && examCacheBean.getForceFinish().intValue() == 0) {
                throw new BusinessException("考试未启用集中收卷");
            }
            if (Objects.nonNull(examCacheBean.getMonitorRecord()) && (!examCacheBean.getMonitorRecord().contains(MonitorVideoSourceEnum.MOBILE_FIRST.name())
                    && !examCacheBean.getMonitorRecord().contains(MonitorVideoSourceEnum.MOBILE_SECOND.name()))) {
                throw new BusinessException("考试未启用手机直播");
            }
            if (Objects.isNull(teAudio.getId())) {
                teAudio.insertInfo(tbUser.getId());
            } else {
                Integer examCount = tOeExamRecordService.findByExamIdOrExamActivityIdCount(examCacheBean.getId(), teAudio.getActivityId());
                if (Objects.nonNull(examCount) && examCount.intValue() > 0) {
                    throw new BusinessException("已有考试记录不能修改");
                }
                teAudio.updateInfo(tbUser.getId());
            }
            teAudioService.saveOrUpdate(teAudio);
//        teAudioService.sendAudioMessage(teAudio);
        } 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("场次[" + examActivityCacheBean.getCode() + "]下的" + teAudio.getType().getTitle() + teAudio.getPlayTime() / 60 + "分钟" + FieldUniqueEnum.convertToCode(columnStr) + "不允许重复插入");
            } else if (e instanceof BusinessException) {
                throw new BusinessException(e.getMessage());
            } else {
                throw new RuntimeException(e);
            }
        }
        return ResultUtil.ok(true);
    }

    @ApiOperation(value = "考试场次语音启用/禁用接口")
    @RequestMapping(value = "/audio/enable", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "常规信息", response = Result.class)})
    @Transactional
    public Result audioEnable(@ApiParam(value = "考试场次语音id", required = true) @RequestParam Long audioId,
                              @ApiParam(value = "启用/禁用", required = true) @RequestParam Boolean enable) {
        ExamActivityCacheBean examActivityCacheBean = null;
        TEAudio teAudio = null;
        try {
            TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
            teAudio = teAudioService.getById(audioId);
            Optional.ofNullable(teAudio).orElseThrow(() -> new BusinessException("语音信息不存在"));
            examActivityCacheBean = teExamActivityService.getExamActivityCacheBean(teAudio.getActivityId());
            ExamCacheBean examCacheBean = teExamService.getExamCacheBean(examActivityCacheBean.getExamId());
            if (enable) {
                if (Objects.nonNull(examCacheBean) && examCacheBean.getMode() == ExamModeEnum.ANYTIME) {
                    throw new BusinessException("只有集中统一的考试才能使用语音播报");
                }
                if (Objects.nonNull(examCacheBean.getForceFinish()) && examCacheBean.getForceFinish().intValue() == 0) {
                    throw new BusinessException("考试未启用集中收卷");
                }
                if (Objects.nonNull(examCacheBean.getMonitorRecord()) && (!examCacheBean.getMonitorRecord().contains(MonitorVideoSourceEnum.MOBILE_FIRST.name())
                        && !examCacheBean.getMonitorRecord().contains(MonitorVideoSourceEnum.MOBILE_SECOND.name()))) {
                    throw new BusinessException("考试未启用手机直播");
                }
            } else {
                Integer examCount = tOeExamRecordService.findByExamIdOrExamActivityIdCount(examCacheBean.getId(), teAudio.getActivityId());
                if (Objects.nonNull(examCount) && examCount.intValue() > 0) {
                    throw new BusinessException("已有考试记录不能禁用");
                }
            }
            teAudio.setEnable(!enable ? null : enable);
            teAudio.updateInfo(tbUser.getId());
            teAudioService.updateById(teAudio);
            themisCacheService.updateExamAudioCache(teAudio.getId());
        } 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("'", "");
                String s = enable ? "启用" : "禁用";
                throw new BusinessException("场次[" + examActivityCacheBean.getCode() + "]下的" + teAudio.getType().getTitle() + teAudio.getPlayTime() / 60 + "分钟" + FieldUniqueEnum.convertToCode(columnStr) + "已有一条被" + s);
            } else if (e instanceof BusinessException) {
                throw new BusinessException(e.getMessage());
            } else {
                throw new RuntimeException(e);
            }
        }
        return ResultUtil.ok(true);
    }

//    @ApiOperation(value = "考试场次语音测试接口")
//    @RequestMapping(value = "/audio/test", method = RequestMethod.POST)
//    @ApiResponses({@ApiResponse(code = 200, message = "常规信息", response = Result.class)})
//    public Result audioTest(@ApiParam(value = "考试场次语音id", required = true) @RequestParam Long audioId) {
//        TEAudio teAudio = teAudioService.getById(audioId);
//        Optional.ofNullable(teAudio).orElseThrow(() -> new BusinessException("语音信息不存在"));
//        ExamActivityCacheBean ac = teExamActivityService.getExamActivityCacheBean(teAudio.getActivityId());
//        ExamCacheBean examCacheBean = teExamService.getExamCacheBean(ac.getExamId());
//        TEExam teExam = teExamService.cacheConvert(examCacheBean);
////        Long start = ac.getStartTime();
////        Long end = ac.getStartTime() + (ac.getOpeningSeconds() * 1000);
//        long currentTime = System.currentTimeMillis();
//        Long execTime = null, realExecTime = null;
//        if (teAudio.getType() == AudioTypeEnum.BEFORE) {//开考前语音
//            realExecTime = currentTime + (60 * 1000);//当前时间往后一分钟
//        } else if (teAudio.getType() == AudioTypeEnum.AFTER) {//考试结束前语音
//            realExecTime = currentTime + (120 * 1000);//当前时间往后二分钟
//        }
//        execTime = realExecTime - SystemConstant.EXAM_AUDIO_BEFORE_TIME;
//        //新增quartz任务,发送mq消息start
//        Map<String, Object> prop = new HashMap<>();
//        prop.put(SystemConstant.OPER, SystemConstant.INSERT);
//        prop.put(SystemConstant.EXAM, teExam);
//        prop.put(SystemConstant.EXEC_TIME, execTime);
//        prop.put(SystemConstant.REAL_EXEC_TIME, realExecTime);
//        log.info(SystemConstant.EXEC_TIME + ":{}," + SystemConstant.REAL_EXEC_TIME + ":{}", DateUtil.format(new Date(execTime), Constants.DEFAULT_DATE_PATTERN), DateUtil.format(new Date(realExecTime), Constants.DEFAULT_DATE_PATTERN));
////        if (execTime >= System.currentTimeMillis()) {
//        cacheService.updateExamAudioCache(teAudio.getId());
//        MqDto mqDto = new MqDto(mqUtil.getMqGroupDomain().getTopic(), MqTagEnum.EXAM_AUDIO.name(),
//                JacksonUtil.parseJson(teAudio), MqTagEnum.EXAM_AUDIO,
//                String.valueOf(teExam.getId()), prop, "test");
//        mqDtoService.assembleSendOneOrderMsg(mqDto);
////        }
//        //新增quartz任务,发送mq消息end
//        return ResultUtil.ok(true);
//    }
}
