package com.qmth.themis.exam.config;

import com.qmth.themis.business.cache.ExamActivityRecordCacheUtil;
import com.qmth.themis.business.cache.ExamRecordCacheUtil;
import com.qmth.themis.business.cache.bean.ExamActivityRecordCacheBean;
import com.qmth.themis.business.cache.bean.ExamCacheBean;
import com.qmth.themis.business.cache.bean.ExamStudentCacheBean;
import com.qmth.themis.business.constant.SpringContextHolder;
import com.qmth.themis.business.constant.SystemConstant;
import com.qmth.themis.business.dto.MqDto;
import com.qmth.themis.business.dto.WebsocketDto;
import com.qmth.themis.business.enums.*;
import com.qmth.themis.business.service.MqDtoService;
import com.qmth.themis.business.service.TEExamService;
import com.qmth.themis.business.service.TEExamStudentService;
import com.qmth.themis.business.service.TOeExamRecordService;
import com.qmth.themis.common.contanst.Constants;
import com.qmth.themis.exam.websocket.WebSocketMobileServer;
import com.qmth.themis.exam.websocket.WebSocketOeServer;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Description: 考试系统常量
 * @Param:
 * @return:
 * @Author: wangliang
 * @Date: 2020/9/21
 */
public class ExamConstant {

    /**
     * 发送考试结束msg
     *
     * @param recordId
     * @param clientStop
     */
    public static void sendExamStopMsg(Long recordId, boolean clientStop) {
        //客户端考试结束
        if (clientStop) {
            ConcurrentHashMap<Long, WebSocketOeServer> webSocketOeMap = WebSocketOeServer.getWebSocketMap();
            if (Objects.nonNull(webSocketOeMap.get(recordId))) {
                WebSocketOeServer webSocketOeServer = webSocketOeMap.get(recordId);
                Map map = new HashMap<>();
                map.put(SystemConstant.RECORD_ID, recordId);
                WebsocketDto websocketDto = new WebsocketDto(WebsocketTypeEnum.EXAM_STOP.name(), map);
                webSocketOeServer.sendMessage(websocketDto);
            }
        }

        //移动端考试结束
        ConcurrentHashMap<String, WebSocketMobileServer> webSocketMap = WebSocketMobileServer.getWebSocketMap();
        if (Objects.nonNull(webSocketMap.get(recordId + "-" + MonitorVideoSourceEnum.MOBILE_FIRST.name()))) {
            WebSocketMobileServer webSocketMobileServer = webSocketMap.get(recordId + "-" + MonitorVideoSourceEnum.MOBILE_FIRST.name());
            Map map = new HashMap<>();
            map.put(SystemConstant.RECORD_ID, recordId);
            WebsocketDto websocketDto = new WebsocketDto(WebsocketTypeEnum.EXAM_STOP.name(), map);
            webSocketMobileServer.sendMessage(websocketDto);
        }
        if (Objects.nonNull(webSocketMap.get(recordId + "-" + MonitorVideoSourceEnum.MOBILE_SECOND.name()))) {
            WebSocketMobileServer webSocketMobileServer = webSocketMap.get(recordId + "-" + MonitorVideoSourceEnum.MOBILE_SECOND.name());
            Map map = new HashMap<>();
            map.put(SystemConstant.RECORD_ID, recordId);
            WebsocketDto websocketDto = new WebsocketDto(WebsocketTypeEnum.EXAM_STOP.name(), map);
            webSocketMobileServer.sendMessage(websocketDto);
        }
    }

    /**
     * 发送考试开始msg
     *
     * @param recordId
     */
    public static void sendExamStartMsg(Long recordId) {
        //移动端考试开始
        ConcurrentHashMap<String, WebSocketMobileServer> webSocketMap = WebSocketMobileServer.getWebSocketMap();
        if (Objects.nonNull(webSocketMap.get(recordId + "-" + MonitorVideoSourceEnum.MOBILE_FIRST.name()))) {
            WebSocketMobileServer webSocketMobileServer = webSocketMap.get(recordId + "-" + MonitorVideoSourceEnum.MOBILE_FIRST.name());
            Map map = new HashMap<>();
            map.put(SystemConstant.RECORD_ID, recordId);
            WebsocketDto websocketDto = new WebsocketDto(WebsocketTypeEnum.EXAM_START.name(), map);
            webSocketMobileServer.sendMessage(websocketDto);
        }
        if (Objects.nonNull(webSocketMap.get(recordId + "-" + MonitorVideoSourceEnum.MOBILE_SECOND.name()))) {
            WebSocketMobileServer webSocketMobileServer = webSocketMap.get(recordId + "-" + MonitorVideoSourceEnum.MOBILE_SECOND.name());
            Map map = new HashMap<>();
            map.put(SystemConstant.RECORD_ID, recordId);
            WebsocketDto websocketDto = new WebsocketDto(WebsocketTypeEnum.EXAM_START.name(), map);
            webSocketMobileServer.sendMessage(websocketDto);
        }
    }

    /**
     * 发送断点消息
     *
     * @param recordId
     */
    public static void sendExamBreakMsg(Long recordId) {
        Long examId = ExamRecordCacheUtil.getExamId(recordId);
        Long examStudentId = ExamRecordCacheUtil.getExamStudentId(recordId);
        TEExamStudentService teExamStudentService = SpringContextHolder.getBean(TEExamStudentService.class);
        ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
        TEExamService teExamService = SpringContextHolder.getBean(TEExamService.class);
        ExamCacheBean ec = teExamService.getExamCacheBean(examId);//考试缓存

        Integer durationSeconds = Objects.isNull(ExamRecordCacheUtil.getDurationSeconds(recordId)) ? 0 : ExamRecordCacheUtil.getDurationSeconds(recordId);
        Integer alreadyBreakCount = Objects.isNull(ExamRecordCacheUtil.getAlreadyBreakCount(recordId)) ? 0 : ExamRecordCacheUtil.getAlreadyBreakCount(recordId);
        Integer leftBreakResumeCount = ec.getBreakResumeCount() - alreadyBreakCount;
        if (leftBreakResumeCount < 0) {
            teExamService.finish(examStudentCacheBean.getStudentId(), recordId, FinishTypeEnum.AUTO.name(), durationSeconds);
        } else {
            alreadyBreakCount++;
            Long breakId = Constants.idGen.next();
            ExamRecordCacheUtil.setLastBreakId(recordId, breakId, false);
            ExamRecordCacheUtil.setStatus(recordId, ExamRecordStatusEnum.BREAK_OFF, false);
            Long lastBreakTimeNow = System.currentTimeMillis();
            ExamRecordCacheUtil.setLastBreakTime(recordId, lastBreakTimeNow, false);
            ExamRecordCacheUtil.setAlreadyBreakCount(recordId, alreadyBreakCount, false);
            Long lastStartTime = System.currentTimeMillis();
            ExamRecordCacheUtil.setLastStartTime(recordId, lastStartTime, false);
            String[] columns = new String[]{ExamRecordFieldEnum.last_break_id.name(), ExamRecordFieldEnum.status.name(), ExamRecordFieldEnum.last_break_time.name(), ExamRecordFieldEnum.already_break_count.name(), ExamRecordFieldEnum.last_start_time.name()};
            Object[] values = new Object[]{breakId, ExamRecordStatusEnum.BREAK_OFF, lastBreakTimeNow, alreadyBreakCount, lastStartTime};
            TOeExamRecordService tOeExamRecordService = SpringContextHolder.getBean(TOeExamRecordService.class);
            tOeExamRecordService.dataUpdatesMq(recordId, columns, values);
            sendExamStopMsg(recordId, true);
            //考试断点异常原因 发送mq start
            MqDto mqDtoBreak = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.EXAM_BREAK.name(), ExceptionEnum.EXIT, MqTagEnum.EXAM_BREAK, String.valueOf(recordId), String.valueOf(recordId));
            MqDtoService mqDtoService = SpringContextHolder.getBean(MqDtoService.class);
            mqDtoService.assembleSendOneWayMsg(mqDtoBreak);
            //考试断点异常原因 发送mq end
            //更新场次-考试记录缓存
            ExamActivityRecordCacheUtil.setExamRecordStatus(examStudentCacheBean.getExamActivityId(), recordId, new ExamActivityRecordCacheBean(ExamRecordCacheUtil.getExamStudentId(recordId), ExamRecordCacheUtil.getStatus(recordId)));
        }
    }
}
