package com.qmth.themis.task.quartz.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qmth.themis.business.cache.ExamRecordCacheUtil;
import com.qmth.themis.business.cache.bean.ExamActivityCacheBean;
import com.qmth.themis.business.cache.bean.ExamCacheBean;
import com.qmth.themis.business.cache.bean.ExamStudentCacheBean;
import com.qmth.themis.business.constant.SystemConstant;
import com.qmth.themis.business.dto.MqDto;
import com.qmth.themis.business.entity.TOeExamRecord;
import com.qmth.themis.business.enums.ExamRecordStatusEnum;
import com.qmth.themis.business.enums.FinishTypeEnum;
import com.qmth.themis.business.enums.MqTagEnum;
import com.qmth.themis.business.enums.WebsocketStatusEnum;
import com.qmth.themis.business.service.*;
import com.qmth.themis.business.util.MqUtil;
import com.qmth.themis.task.quartz.service.QuartzLogicService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

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

/**
 * @Description: quartz逻辑 impl
 * @Param:
 * @return:
 * @Author: wangliang
 * @Date: 2020/7/31
 */
@Service
public class QuartzLogicServiceImpl implements QuartzLogicService {
    private final static Logger log = LoggerFactory.getLogger(QuartzLogicServiceImpl.class);

    @Resource
    TEExamActivityService teExamActivityService;

    @Resource
    TEExamService teExamService;

    @Resource
    TEExamStudentService teExamStudentService;

    @Resource
    TOeExamRecordService tOeExamRecordService;

    @Resource
    CommonService commonService;

    @Resource
    MqUtil mqUtil;

    @Resource
    MqDtoService mqDtoService;

    /**
     * 考试场次quartz逻辑
     *
     * @param key
     */
    @Override
    @Transactional
    public void execExamActivityJobLogic(String key) {
        log.info("execExamActivityJobLogic key:{}", key);
        String[] strings = key.split("\\.");
        ExamActivityCacheBean examActivityCacheBean = teExamActivityService.getExamActivityCacheBean(Long.parseLong(strings[1]));
        ExamCacheBean examCacheBean = teExamService.getExamCacheBean(examActivityCacheBean.getExamId());
        if (Objects.nonNull(examCacheBean) && examCacheBean.getEnable().intValue() == 1 && Objects.nonNull(examActivityCacheBean) && examActivityCacheBean.getEnable().intValue() == 1) {
            Integer forceFinish = examCacheBean.getForceFinish();
            QueryWrapper<TOeExamRecord> tOeExamRecordQueryWrapper = new QueryWrapper<>();
            tOeExamRecordQueryWrapper.lambda().eq(TOeExamRecord::getExamActivityId, examActivityCacheBean.getId());
            List<TOeExamRecord> examRecordList = tOeExamRecordService.list(tOeExamRecordQueryWrapper);
            if (Objects.nonNull(forceFinish) && forceFinish.intValue() == 1) {//强制收卷
                if (!CollectionUtils.isEmpty(examRecordList)) {
                    List<TOeExamRecord> updateExamRecordList = new ArrayList<>(examRecordList.size() / 2);
                    examRecordList.forEach(s -> {
                        ExamRecordStatusEnum examRecordStatusEnum = s.getStatus();
                        //获取该考试批次下所有未交卷的考生的考试记录
                        if (Objects.nonNull(examRecordStatusEnum)
                                && !Objects.equals(ExamRecordStatusEnum.FINISHED, examRecordStatusEnum)
                                && !Objects.equals(ExamRecordStatusEnum.PERSISTED, examRecordStatusEnum)
                                && !Objects.equals(ExamRecordStatusEnum.JUNK, examRecordStatusEnum)) {
                            Integer durationSeconds = s.getDurationSeconds();
                            Long examStudentId = s.getExamStudentId();
                            ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
                            //候考阶段且没有进入考试则不交卷
                            try {
                                if (examRecordStatusEnum == ExamRecordStatusEnum.FIRST_PREPARE && Objects.isNull(s.getFirstStartTime())) {
                                    commonService.deleteExamStudentCache(s.getId(), examStudentCacheBean.getStudentId());
                                    s.setStatus(ExamRecordStatusEnum.JUNK);
                                    s.setUpdateTime(System.currentTimeMillis());
                                    if (Objects.nonNull(s.getClientWebsocketStatus()) && s.getClientWebsocketStatus() == WebsocketStatusEnum.ON_LINE) {
                                        s.setClientWebsocketStatus(WebsocketStatusEnum.OFF_LINE);
                                    }
                                    updateExamRecordList.add(s);
                                    commonService.dismissRoomByStrRoomId(s.getId());
                                } else {//交卷
                                    Long recordEndTime = s.getEndTime();
                                    if (Objects.nonNull(examActivityCacheBean.getFinishTime()) && Objects.nonNull(recordEndTime) && examActivityCacheBean.getFinishTime().longValue() == recordEndTime.longValue()) {
                                        teExamService.finish(examStudentCacheBean.getStudentId(), s.getId(), FinishTypeEnum.AUTO.name(), durationSeconds);
                                    }
                                }
                            } catch (Exception e) {
                                log.error(SystemConstant.LOG_ERROR, e);
                            }
                        }
                    });
                    if (!CollectionUtils.isEmpty(updateExamRecordList)) {
                        tOeExamRecordService.updateBatchById(updateExamRecordList);
                    }
                }
            } else {
                if (!CollectionUtils.isEmpty(examRecordList)) {
                    List<TOeExamRecord> updateExamRecordList = new ArrayList<>(examRecordList.size() / 2);
                    examRecordList.forEach(s -> {
                        ExamRecordStatusEnum examRecordStatusEnum = s.getStatus();
                        //获取该考试批次下所有未交卷的考生的考试记录
                        if (Objects.nonNull(examRecordStatusEnum)
                                && !Objects.equals(ExamRecordStatusEnum.FINISHED, examRecordStatusEnum)
                                && !Objects.equals(ExamRecordStatusEnum.PERSISTED, examRecordStatusEnum)
                                && !Objects.equals(ExamRecordStatusEnum.ANSWERING, examRecordStatusEnum)
                                && !Objects.equals(ExamRecordStatusEnum.JUNK, examRecordStatusEnum)) {
                            Long recordEndTime = s.getEndTime();
                            if (Objects.nonNull(examActivityCacheBean.getFinishTime()) && Objects.nonNull(recordEndTime) && examActivityCacheBean.getFinishTime().longValue() == recordEndTime.longValue()) {
                                Integer durationSeconds = s.getDurationSeconds();
                                Long examStudentId = s.getExamStudentId();
                                ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
                                //候考阶段且没有进入考试则不交卷
                                try {
                                    if (examRecordStatusEnum == ExamRecordStatusEnum.FIRST_PREPARE && Objects.isNull(s.getFirstStartTime())) {
                                        commonService.deleteExamStudentCache(s.getId(), examStudentCacheBean.getStudentId());
                                        s.setStatus(ExamRecordStatusEnum.JUNK);
                                        s.setUpdateTime(System.currentTimeMillis());
                                        if (Objects.nonNull(s.getClientWebsocketStatus()) && s.getClientWebsocketStatus() == WebsocketStatusEnum.ON_LINE) {
                                            s.setClientWebsocketStatus(WebsocketStatusEnum.OFF_LINE);
                                        }
                                        updateExamRecordList.add(s);
                                        commonService.dismissRoomByStrRoomId(s.getId());
                                    } else {//交卷
                                        teExamService.finish(examStudentCacheBean.getStudentId(), s.getId(), FinishTypeEnum.AUTO.name(), durationSeconds);
                                    }
                                } catch (Exception e) {
                                    log.error(SystemConstant.LOG_ERROR, e);
                                }
                            }
                        }
                    });
                    if (!CollectionUtils.isEmpty(updateExamRecordList)) {
                        tOeExamRecordService.updateBatchById(updateExamRecordList);
                    }
                }
            }
        }
    }

    /**
     * 考生quartz逻辑
     *
     * @param key
     */
    @Override
    public void execExamStudentJobLogic(String key) {
        log.info("execExamStudentJobLogic key:{}", key);
        String[] strings = key.split("\\.");
        String[] exams = strings[1].split("-");
        ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(Long.parseLong(exams[0]));
        Long recordId = Long.parseLong(exams[1]);
        ExamRecordStatusEnum examRecordStatusEnum = ExamRecordCacheUtil.getStatus(recordId);
        ExamActivityCacheBean examActivityCacheBean = teExamActivityService.getExamActivityCacheBean(examStudentCacheBean.getExamActivityId());
        //获取该考试批次下所有未交卷的考生的考试记录
        if (Objects.nonNull(examRecordStatusEnum)
                && !Objects.equals(ExamRecordStatusEnum.FINISHED, examRecordStatusEnum)
                && !Objects.equals(ExamRecordStatusEnum.PERSISTED, examRecordStatusEnum)
                && !Objects.equals(ExamRecordStatusEnum.ANSWERING, examRecordStatusEnum)
                && !Objects.equals(ExamRecordStatusEnum.JUNK, examRecordStatusEnum)) {
            Long firstStartTime = ExamRecordCacheUtil.getFirstStartTime(recordId);
            if (Objects.isNull(firstStartTime)) {
                TOeExamRecord tOeExamRecord = SystemConstant.getExamRecord(recordId);
                firstStartTime = tOeExamRecord.getFirstStartTime();
            }
            //候考阶段且没有进入考试则不交卷
            TOeExamRecord tOeExamRecord = null;
            try {
                if (examRecordStatusEnum == ExamRecordStatusEnum.FIRST_PREPARE && Objects.isNull(firstStartTime)) {
                    tOeExamRecord = SystemConstant.getExamRecord(recordId);
                    commonService.deleteExamStudentCache(recordId, examStudentCacheBean.getStudentId());
                    tOeExamRecord.setStatus(ExamRecordStatusEnum.JUNK);
                    tOeExamRecord.setUpdateTime(System.currentTimeMillis());
                    if (Objects.nonNull(tOeExamRecord.getClientWebsocketStatus()) && tOeExamRecord.getClientWebsocketStatus() == WebsocketStatusEnum.ON_LINE) {
                        tOeExamRecord.setClientWebsocketStatus(WebsocketStatusEnum.OFF_LINE);
                    }
                    commonService.dismissRoomByStrRoomId(recordId);
                } else {//交卷
                    Long recordEndTime = ExamRecordCacheUtil.getEndTime(recordId);
                    if (examActivityCacheBean.getFinishTime().longValue() == recordEndTime.longValue()) {
                        Integer durationSeconds = ExamRecordCacheUtil.getDurationSeconds(recordId);
                        teExamService.finish(examStudentCacheBean.getStudentId(), recordId, FinishTypeEnum.AUTO.name(), durationSeconds);
                    }
                }
            } catch (Exception e) {
                log.error(SystemConstant.LOG_ERROR, e);
            }
            if (Objects.nonNull(tOeExamRecord)) {
                tOeExamRecordService.updateById(tOeExamRecord);
            }
        }
    }

    /**
     * 考试最后开考时间quartz逻辑
     *
     * @param key
     */
    @Override
    public void execExamActivityFinalPrepareTimeJobLogic(String key) {
        String[] strings = key.split("\\.");
        String[] examRecordIds = strings[1].split("-");
        TOeExamRecord tOeExamRecord = tOeExamRecordService.getById(Long.parseLong(examRecordIds[0]));
        if (Objects.nonNull(tOeExamRecord)
                && tOeExamRecord.getStatus() == ExamRecordStatusEnum.FIRST_PREPARE
                && tOeExamRecord.getClientWebsocketStatus() == WebsocketStatusEnum.ON_LINE) {
            Map<String, Object> properties = new HashMap<>();
            properties.put(SystemConstant.RECORD_ID, tOeExamRecord.getId());
            MqDto clientMqDto = new MqDto(mqUtil.getTopic(), MqTagEnum.EXAM_EXIT.name(), tOeExamRecord.getId(), MqTagEnum.EXAM_EXIT, String.valueOf(tOeExamRecord.getId()), properties, String.valueOf(tOeExamRecord.getId()));
            mqDtoService.assembleSendAsyncOrderMsg(clientMqDto);
        }
    }

//    /**
//     * 考试语音quartz逻辑
//     *
//     * @param key
//     */
//    @Override
//    public void execExamAudioJobLogic(String key) {
//        log.info("execExamAudioJobLogic key:{}", key);
//        String[] strings = key.split("\\.");
//        String[] exams = strings[1].split("-");
//        Long teAudioId = Long.parseLong(exams[0]);
//        Long examActivityId = Long.parseLong(exams[1]);
//        Long examId = Long.parseLong(exams[2]);
//        Long execTime = Long.parseLong(exams[3]);
//        if (Objects.nonNull(teAudioId)) {
//            List<TOeExamRecord> tOeExamRecordList = tOeExamRecordService.findExamRecordByExamIdAndExamActivityId(examId, examActivityId);
//            if (!CollectionUtils.isEmpty(tOeExamRecordList)) {
//                for (TOeExamRecord t : tOeExamRecordList) {
//                    ExamCacheBean examCacheBean = teExamService.getExamCacheBean(examId);
//                    ExamActivityCacheBean examActivityCacheBean = teExamActivityService.getExamActivityCacheBean(examActivityId);
//                    TEAudio teAudio = cacheService.examAudioCache(teAudioId);
//                    if (Objects.nonNull(examCacheBean) && Objects.nonNull(examActivityCacheBean) && Objects.nonNull(teAudio)
//                            && Objects.nonNull(examCacheBean.getForceFinish()) && examCacheBean.getForceFinish().intValue() == 1
//                            && Objects.nonNull(examCacheBean.getEnable()) && examCacheBean.getEnable() == 1
//                            && Objects.nonNull(examActivityCacheBean.getEnable()) && examActivityCacheBean.getEnable() == 1
//                            && Objects.nonNull(teAudio.getEnable()) && teAudio.getEnable()
//                            && Objects.nonNull(t.getMonitorRecord())
//                            && (t.getMonitorRecord().contains(MonitorVideoSourceEnum.MOBILE_FIRST.name())
//                            || t.getMonitorRecord().contains(MonitorVideoSourceEnum.MOBILE_SECOND.name()))) {
//                        Map<String, Object> mapParameter = new HashMap<>();
//                        mapParameter.put(SystemConstant.RECORD_ID, t.getId());
//                        mapParameter.put(SystemConstant.EXEC_TIME, execTime);
//                        TBAttachment tbAttachment = cacheService.attachmentCache(teAudio.getAttachmentId());
//                        if (Objects.nonNull(tbAttachment) && Objects.nonNull(tbAttachment.getRemark())) {
//                            JSONObject jsonObject = JSONObject.parseObject(tbAttachment.getRemark());
//                            mapParameter.put(SystemConstant.PATH, ossUtil.getAliYunOssPublicDomain().getPublicUrl() + File.separator + jsonObject.getString(SystemConstant.PATH));
//                            mapParameter.put(SystemConstant.NAME, tbAttachment.getName() + tbAttachment.getType());
//                        }
//                        MqDto mqDto = new MqDto(mqUtil.getMqGroupDomain().getTopic(), MqTagEnum.EXAM_AUDIO_MOBILE.name(), t.getId(), MqTagEnum.EXAM_AUDIO_MOBILE, exams[2], mapParameter, exams[2]);
//                        mqDtoService.assembleSendOneOrderMsg(mqDto);
//                    }
//                }
//            }
//        }
//    }
}
