package com.qmth.themis.exam.api;

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

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
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 com.qmth.themis.business.bean.exam.AnswerReadyParamBean;
import com.qmth.themis.business.bean.exam.AnswerReadyResponseBean;
import com.qmth.themis.business.bean.exam.MobileAnswerSubmitParamBean;
import com.qmth.themis.business.bean.exam.MobileAnswerSubmitReponseBean;
import com.qmth.themis.business.bean.mobile.MobileAuthorizationParamBean;
import com.qmth.themis.business.cache.ExamRecordCacheUtil;
import com.qmth.themis.business.cache.bean.ExamStudentCacheBean;
import com.qmth.themis.business.constant.SystemConstant;
import com.qmth.themis.business.dto.WebsocketDto;
import com.qmth.themis.business.dto.cache.TEStudentCacheDto;
import com.qmth.themis.business.enums.ExamRecordStatusEnum;
import com.qmth.themis.business.enums.WebsocketTypeEnum;
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.TEMobileService;
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 com.qmth.themis.exam.websocket.WebSocketOeServer;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;

@Api(tags = "移动端接口")
@RestController
@RequestMapping("/${prefix.url.mobile}")
public class TEMobileController {

    @Resource
    TEMobileService mobileService;

    @Resource
    TEExamService examService;

    @Resource
    TEExamStudentService examStudentService;


    @ApiOperation(value = "获取登录详细信息")
    @RequestMapping(value = "/authorization", method = RequestMethod.POST)
    public Result authorization(@RequestBody MobileAuthorizationParamBean param) throws NoSuchAlgorithmException {
        if (param.getMode() == null) {
            throw new BusinessException("mode不能为空");
        }
        if (param.getCode() == null) {
            throw new BusinessException("code不能为空");
        }
        return ResultUtil.ok(mobileService.authorization(param));
    }

    @ApiOperation(value = "拍照/录音答题就绪")
    @RequestMapping(value = "/answer/ready", method = RequestMethod.POST)
    public Result answerReady(@RequestBody AnswerReadyParamBean param) {
        if (param.getRecordId() == null) {
            throw new BusinessException("考试记录id不能为空");
        }
        if (param.getMainNumber() == null) {
            throw new BusinessException("大题号不能为空");
        }
        if (param.getSubNumber() == null) {
            throw new BusinessException("小题号不能为空");
        }
        Long esId = ExamRecordCacheUtil.getExamStudentId(param.getRecordId());
        if (ExamRecordCacheUtil.getId(param.getRecordId()) == null) {
            throw new BusinessException("考试记录不存在");
        }
        ExamRecordStatusEnum sta = ExamRecordCacheUtil.getStatus(param.getRecordId());
//        if (ExamRecordStatusEnum.FIRST_PREPARE.equals(sta)) {
//            throw new BusinessException("该考试未开始答题");
//        }
        if (ExamRecordStatusEnum.FINISHED.equals(sta) || ExamRecordStatusEnum.PERSISTED.equals(sta)) {
            throw new BusinessException("该考试已结束");
        }
        ConcurrentHashMap<Long, WebSocketOeServer> webSocketMap = WebSocketOeServer.getWebSocketMap();
        WebSocketOeServer webSocketOeServer = webSocketMap.get(param.getRecordId());
        if (webSocketOeServer == null) {
            throw new BusinessException("消息连接不存在");
        }
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("recordId", param.getRecordId());
        map.put("mainNumber", param.getMainNumber());
        map.put("subNumber", param.getSubNumber());
        if (param.getSubIndex() != null) {
            map.put("subIndex", param.getSubIndex());
        }
        WebsocketDto websocketDto = new WebsocketDto(WebsocketTypeEnum.MOBILE_ANSWER_READY.name(), map);
        webSocketOeServer.sendMessage(websocketDto);
        ExamStudentCacheBean es = examStudentService.getExamStudentCacheBean(esId);
        AnswerReadyResponseBean ret = new AnswerReadyResponseBean();
        ret.setCourseName(es.getCourseName());
        ret.setExamName(examService.getExamCacheBean(es.getExamId()).getName());
        return ResultUtil.ok(ret);
    }

    @ApiOperation(value = "文件上传")
    @RequestMapping(value = "/file/upload", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "试卷信息")})
    public Result fileUpload(@ApiParam(value = "考试记录ID", required = true) @RequestParam Long recordId,
                             @ApiParam(value = "上传文件", required = true) @RequestParam MultipartFile file,
                             @ApiParam(value = "后缀名", required = true) @RequestParam String suffix,
                             @ApiParam(value = "md5", required = true) @RequestParam String md5) {
        TEStudentCacheDto teStudent = (TEStudentCacheDto) ServletUtil.getRequestStudentAccount();
        return ResultUtil.ok(examService.fileUpload(teStudent.getId(), recordId, file, suffix, md5));
    }

    @ApiOperation(value = "提交作答结果")
    @RequestMapping(value = "/answer/submit", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "试卷信息")})
    public Result answerSubmit(@RequestBody MobileAnswerSubmitParamBean param) {
        TEStudentCacheDto teStudent = (TEStudentCacheDto) ServletUtil.getRequestStudentAccount();
        if (param.getRecordId() == null) {
            throw new BusinessException("考试记录id不能为空");
        }
        if (param.getMainNumber() == null) {
            throw new BusinessException("大题号不能为空");
        }
        if (param.getSubNumber() == null) {
            throw new BusinessException("小题号不能为空");
        }
        if (StringUtils.isBlank(param.getUrls())) {
            throw new BusinessException("答案不能为空");
        }
        MobileAnswerSubmitReponseBean ret = mobileService.answerSubmit(teStudent.getId(), param.getRecordId(), param.getMainNumber(),
                param.getSubNumber(), param.getSubIndex(), param.getUrls());
        ConcurrentHashMap<Long, WebSocketOeServer> webSocketMap = WebSocketOeServer.getWebSocketMap();
        if (Objects.nonNull(webSocketMap.get(param.getRecordId()))) {
            WebSocketOeServer webSocketOeServer = webSocketMap.get(param.getRecordId());
            Map<String, Object> map = new HashMap<String, Object>();
            map.put(SystemConstant.RECORD_ID, param.getRecordId());
            map.put("mainNumber", param.getMainNumber());
            map.put("subNumber", param.getSubNumber());
            if (param.getSubIndex() != null) {
                map.put("subIndex", param.getSubIndex());
            }
            map.put("urls", param.getUrls());
            WebsocketDto websocketDto = new WebsocketDto(WebsocketTypeEnum.MOBILE_ANSWER_UPLOAD.name(), map);
            webSocketOeServer.sendMessage(websocketDto);
        }
        return ResultUtil.ok(ret);
    }

}
