package com.qmth.themis.backend.api;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qmth.themis.backend.config.DictionaryConfig;
import com.qmth.themis.business.annotation.ApiJsonObject;
import com.qmth.themis.business.annotation.ApiJsonProperty;
import com.qmth.themis.business.bean.mobile.MobileAuthorizationMonitorBean;
import com.qmth.themis.business.cache.ExamRecordCacheUtil;
import com.qmth.themis.business.config.SystemConfig;
import com.qmth.themis.business.constant.SystemConstant;
import com.qmth.themis.business.dto.AuthDto;
import com.qmth.themis.business.dto.MqDto;
import com.qmth.themis.business.dto.response.TIeExamInvigilateCallDto;
import com.qmth.themis.business.entity.TBSession;
import com.qmth.themis.business.entity.TBUser;
import com.qmth.themis.business.entity.TIeExamInvigilateCall;
import com.qmth.themis.business.entity.TIeExamInvigilateCallLog;
import com.qmth.themis.business.enums.*;
import com.qmth.themis.business.service.MqDtoService;
import com.qmth.themis.business.service.TIeExamInvigilateCallService;
import com.qmth.themis.business.util.RedisUtil;
import com.qmth.themis.business.util.ServletUtil;
import com.qmth.themis.business.util.TencentYunUtil;
import com.qmth.themis.common.enums.ExceptionResultEnum;
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.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.io.File;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @Description: mobile监考监控通话信息 前端控制器
 * @Param:
 * @return:
 * @Author: wangliang
 * @Date: 2020/6/25
 */
@Api(tags = "mobile监考监控通话信息Controller")
@RestController
@RequestMapping("/${prefix.url.admin}/monitor")
public class TIeInvigilateCallMobileController {
    private final static Logger log = LoggerFactory.getLogger(TIeInvigilateCallMobileController.class);

    @Resource
    RedisUtil redisUtil;

    @Resource
    MqDtoService mqDtoService;

    @Resource
    TIeExamInvigilateCallService tIeExamInvigilateCallService;

    @Resource
    TencentYunUtil tencentYunUtil;

    @Resource
    SystemConfig systemConfig;

    @Resource
    DictionaryConfig dictionaryConfig;

    @ApiOperation(value = "监考监控通话查询接口")
    @RequestMapping(value = "/call/list", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "监考监控信息", response = TIeExamInvigilateCallDto.class)})
    public Result callList(@ApiParam(value = "考试批次id", required = true) @RequestParam(required = true) Long examId, @ApiParam(value = "通话状态", required = false) @RequestParam(required = false) String callStatus, @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber, @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
        if (Objects.isNull(examId) || Objects.equals(examId, "")) {
            throw new BusinessException(ExceptionResultEnum.EXAM_ID_IS_NULL);
        }
        if (Objects.nonNull(callStatus) && !Objects.equals(callStatus, "")) {
            MonitorCallStatusSourceEnum callStatusEnum = MonitorCallStatusSourceEnum.valueOf(callStatus);
            callStatus = callStatusEnum.name();
        }
        TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
        AuthDto authDto = (AuthDto) redisUtil.get(SystemConstant.userOauth + "::" + tbUser.getId());
        //如果有监考员角色，只能查看自己所监考的考场，巡考员和管理员则可以查看全部考场
        Long userId = null;
        if (authDto.getRoleCodes().toString().contains(RoleEnum.INVIGILATE.name())) {
            userId = tbUser.getId();
        }
        IPage<TIeExamInvigilateCallDto> tIeExamInvigilateCallIPage = tIeExamInvigilateCallService.examInvigilateCallQuery(new Page<>(pageNumber, pageSize), examId, userId, tbUser.getOrgId(), MonitorStatusSourceEnum.START.name(), callStatus);
        tIeExamInvigilateCallIPage.getRecords().forEach(s -> {
            s.setBasePhotoPath(systemConfig.getProperty("aliyun.oss.url") + File.separator + s.getBasePhotoPath());
        });
        return ResultUtil.ok(tIeExamInvigilateCallIPage);
    }

    @ApiOperation(value = "监考监控通话提醒接口")
    @RequestMapping(value = "/call/count", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "监考监控信息", response = Integer.class)})
    public Result callCount(@ApiParam(value = "考试批次id", required = true) @RequestParam Long examId, @ApiParam(value = "通话状态", required = false) @RequestParam(required = false) String callStatus) {
        if (Objects.isNull(examId) || Objects.equals(examId, "")) {
            throw new BusinessException(ExceptionResultEnum.EXAM_ID_IS_NULL);
        }
        if (Objects.nonNull(callStatus) && !Objects.equals(callStatus, "")) {
            MonitorCallStatusSourceEnum callStatusEnum = MonitorCallStatusSourceEnum.valueOf(callStatus);
            callStatus = callStatusEnum.name();
        }
        TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
        AuthDto authDto = (AuthDto) redisUtil.get(SystemConstant.userOauth + "::" + tbUser.getId());
        //如果有监考员角色，只能查看自己所监考的考场，巡考员和管理员则可以查看全部考场
        Long userId = null;
        if (authDto.getRoleCodes().toString().contains(RoleEnum.INVIGILATE.name())) {
            userId = tbUser.getId();
        }
        int count = tIeExamInvigilateCallService.examInvigilateCallQueryCount(examId, userId, tbUser.getOrgId(), MonitorStatusSourceEnum.START.name(), callStatus);
        return ResultUtil.ok(Collections.singletonMap("count", count));
    }

    @ApiOperation(value = "监考监控通话查询来源接口")
    @RequestMapping(value = "/call/query", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "监考监控信息", response = TIeExamInvigilateCall.class)})
    public Result callQuery(@ApiParam(value = "考试记录id", required = true) @RequestParam(required = true) Long recordId) {
        QueryWrapper<TIeExamInvigilateCall> tIeExamInvigilateCallQueryWrapper = new QueryWrapper<>();
        tIeExamInvigilateCallQueryWrapper.lambda().eq(TIeExamInvigilateCall::getExamRecordId, recordId);
        return ResultUtil.ok(tIeExamInvigilateCallService.list(tIeExamInvigilateCallQueryWrapper));
    }

    @ApiOperation(value = "撤销通话申请接口")
    @RequestMapping(value = "/call/cancel", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class)})
    @Transactional
    public Result callCancel(@ApiJsonObject(name = "callCancelBackendMobile", value = {
            @ApiJsonProperty(key = "recordId", type = "long", example = "1", description = "考试记录id", required = true),
            @ApiJsonProperty(key = "source", description = "监考视频源", required = true)
    }) @ApiParam(value = "监控信息", required = true) @RequestBody Map<String, Object> mapParameter) {
        if (Objects.isNull(mapParameter.get("recordId")) || Objects.equals(mapParameter.get("recordId"), "")) {
            throw new BusinessException(ExceptionResultEnum.RECORD_ID_IS_NULL);
        }
        Long recordId = Long.parseLong(String.valueOf(mapParameter.get("recordId")));
        if (Objects.isNull(mapParameter.get("source")) || Objects.equals(mapParameter.get("source"), "")) {
            throw new BusinessException("来源不能为空!");
        }
        MonitorVideoSourceEnum source = MonitorVideoSourceEnum.valueOf(String.valueOf(mapParameter.get("source")));
        //获取考试记录缓存
        String liveUrl = null;
        if (Objects.isNull(ExamRecordCacheUtil.getMonitorStatus(recordId, source.name()))) {
            throw new BusinessException("推流状态为空");
        }
        ExamRecordCacheUtil.setMonitorCallStatus(recordId, source.name(), MonitorCallStatusSourceEnum.STOP);
        String monitorKey = ExamRecordCacheUtil.getMonitorKey(recordId);
        MonitorStatusSourceEnum status = ExamRecordCacheUtil.getMonitorStatus(recordId, source.name());
        TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl, status, monitorKey, MonitorCallStatusSourceEnum.STOP);
        //监考监控通话信息 发送mq start
        MqDto mqDto = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.MONITOR_LOG.name(), tIeExamInvigilateCallLog, MqTagEnum.MONITOR_LOG, String.valueOf(tIeExamInvigilateCallLog.getId()), source.name());
        mqDtoService.assembleSendOneWayMsg(mqDto);
        //监考监控通话信息 发送mq end
        return ResultUtil.ok(Collections.singletonMap("success", true));
    }

    @ApiOperation(value = "监考获取monitorKey接口")
    @RequestMapping(value = "/getMonitorKey", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "获取监考monitorKey", response = MobileAuthorizationMonitorBean.class)})
    public Result getMonitorKey(@ApiParam(value = "考试记录id", required = true) @RequestParam Long recordId) {
        TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
        TBSession tbSession = (TBSession) ServletUtil.getRequestSession();
        String monitorKey = ExamRecordCacheUtil.getMonitorKey(recordId);
        AuthDto authDto = (AuthDto) redisUtil.get(SystemConstant.userOauth + "::" + tbUser.getId());
        String monitorUserId = null;
        if (Objects.nonNull(authDto) && authDto.toString().contains(RoleEnum.STUDENT.name())) {
            monitorUserId = "s_" + tbSession.getId();
        } else {
            monitorUserId = "m_" + tbSession.getId();
        }
        String monitorUserSig = tencentYunUtil.getSign(monitorUserId, SystemConstant.TENCENT_EXPIRE_TIME);
        Map<String, Object> map = new HashMap<>();
        map.put("monitorKey", monitorKey);
        map.put("monitorUserId", monitorUserId);
        map.put("monitorUserSig", monitorUserSig);
        map.put("appId", dictionaryConfig.tencentYunDomain().getAppId());
        map.put("key", dictionaryConfig.tencentYunDomain().getKey());
        return ResultUtil.ok(map);
    }
}
