package com.yonge.cooleshow.classroom.controller;


import com.alibaba.fastjson.JSONObject;
import com.yonge.cooleshow.biz.dal.dto.BasicUserInfoDto;
import com.yonge.cooleshow.biz.dal.dto.ETencentTRTCCallbackCommand;
import com.yonge.cooleshow.biz.dal.dto.ImChannelStateNotify;
import com.yonge.cooleshow.biz.dal.dto.ImNetworkBaseDto;
import com.yonge.cooleshow.biz.dal.dto.ImNetworkCustomMessage;
import com.yonge.cooleshow.biz.dal.dto.ImNetworkDeviceControlDto;
import com.yonge.cooleshow.biz.dal.dto.ImNetworkDisplayDataDto;
import com.yonge.cooleshow.biz.dal.dto.ImNetworkMusicSheetDto;
import com.yonge.cooleshow.biz.dal.dto.ImNetworkRoomResult;
import com.yonge.cooleshow.biz.dal.dto.RoomStatusNotify;
import com.yonge.cooleshow.biz.dal.dto.TencentData;
import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
import com.yonge.cooleshow.biz.dal.enums.RoleEnum;
import com.yonge.cooleshow.biz.dal.service.ImGroupService;
import com.yonge.cooleshow.biz.dal.service.ImNetworkRoomService;
import com.yonge.cooleshow.biz.dal.service.SysUserService;
import com.yonge.cooleshow.common.controller.BaseController;
import com.yonge.cooleshow.common.entity.BaseResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
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.RestController;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

/**
 * 网络教室房间(room)表控制层
 *
 * @author zx
 * @since 2022-03-30 16:36:36
 */
@Api(tags = "网络教室房间")
@RestController
@RequestMapping("/room")
public class RoomController extends BaseController {

    private final static Logger log = LoggerFactory.getLogger(RoomController.class);
    /**
     * 服务对象
     */
    @Resource
    private ImNetworkRoomService imNetworkRoomService;
    @Resource
    private SysUserService sysUserService;
    @Autowired
    private ImGroupService imGroupService;

    @ApiOperation("加入网络教室")
    @PostMapping(value = "/join")
    public BaseResponse<ImNetworkRoomResult> joinRoom(@RequestBody ImNetworkBaseDto imNetworkBaseDto) {
        RoleEnum userRole = RoleEnum.RoleStudent;
        if(imNetworkBaseDto.getClientType() == ClientEnum.TEACHER){
            userRole = RoleEnum.RoleTeacher;
        }
        return imNetworkRoomService.joinRoom(imNetworkBaseDto.getRoomId(), userRole);
    }

    @ApiOperation("查询网络教室信息")
    @PostMapping(value = "/info")
    public BaseResponse<ImNetworkRoomResult> getRoomInfo(@RequestBody ImNetworkBaseDto imNetworkBaseDto){
        return imNetworkRoomService.roomInfo(imNetworkBaseDto);
    }

    @RequestMapping(value = "joinRoomStatusNotify", method = RequestMethod.POST)
    public Object joinRoomStatusNotify(@RequestBody RoomStatusNotify roomStatusNotify) throws Exception {
        log.info("joinRoomStatusNotify: {}",JSONObject.toJSON(roomStatusNotify));
        if(!roomStatusNotify.isRequestStatus()){
            imNetworkRoomService.joinRoomFailure(roomStatusNotify.getRoomId(), roomStatusNotify.getClientType());
        }
        return new BaseResponse<>();
    }

    @PostMapping(value = "/statusSync")
    @ApiOperation("加入网络教室状态回调")
    public void statusSync(@RequestBody String body) throws Exception {
        log.info("statusSync body: {}",body);
        ImChannelStateNotify notify = JSONObject.parseObject(body, ImChannelStateNotify.class);

        switch (notify.getEvent()) {
            case 11:
                //成员加入
                imNetworkRoomService.joinRoomSuccess(notify.getRoomId(), notify.getUserId());
                break;
            case 12:
                //成员退出
                imNetworkRoomService.quitRoomSuccess(notify.getRoomId(), notify.getUserId());
                break;
        }
    }


    @PostMapping(value = "/tencentRtcCallback")
    public void statusSyncTencent(@RequestBody TencentData.TRTCEventInfo eventInfo) {
        try {
            if (Objects.isNull(eventInfo.getEventInfo())) {
                log.warn("statusSyncTencent eventInfo is null, time={}", DateTime.now().toString("yyy-MM-dd HH:mm:ss"));
                return;
            }
            log.info("statusSyncTencent: {}", eventInfo.jsonString());
            String roomId = eventInfo.getEventInfo().getRoomId();

            // 网络教室回调整消息
            // 进出用户信息
            String userId = eventInfo.getEventInfo().getUserId();
            switch (ETencentTRTCCallbackCommand.get(eventInfo.getEventType())){
                case EVENT_TYPE_ENTER_ROOM:
                    //成员加入
                    imNetworkRoomService.joinRoomSuccess(roomId, userId);
                    break;
                case EVENT_TYPE_EXIT_ROOM:
                    //成员退出
                    imNetworkRoomService.quitRoomSuccess(roomId, userId);
                    break;
                default:
                    // 默认事件，直接忽略
                    break;
            }

            // 直播课回调消息, roomId.startsWith("LIVE")
            if (roomId.startsWith("LIVE")) {
                String[] values = roomId.split("-");
                if (values.length < 2 || !values[1].startsWith("S")) {
                    return;
                }

                roomId = values[1];
                // 直播课回调事件处理, 课程编号
                switch (ETencentTRTCCallbackCommand.get(eventInfo.getEventType())){
                    case EVENT_TYPE_START_VIDEO:
                    case EVENT_TYPE_START_AUDIO:
                    case EVENT_TYPE_START_ASSIT:
                        //成员加入
                        imNetworkRoomService.joinRoomSuccess(roomId, eventInfo.getEventInfo().getUserId());
                        break;
                    case EVENT_TYPE_STOP_VIDEO:
                    case EVENT_TYPE_STOP_AUDIO:
                    case EVENT_TYPE_STOP_ASSIT:
                        //成员退出
                        imNetworkRoomService.quitRoomSuccess(roomId, eventInfo.getEventInfo().getUserId());
                        break;
                    default:
                        // 默认事件，直接忽略
                        break;
                }
            }

        }catch (Exception e){
            log.error("statusSyncTencent event={}", eventInfo.jsonString(), e);
        }
    }

    @ApiOperation("退出网络教室")
    @PostMapping(value = "/leave")
    public BaseResponse leaveRoom(@RequestBody ImNetworkBaseDto imNetworkBaseDto) throws Exception {
        // 设置请求客户端来源
        if (Objects.isNull(imNetworkBaseDto.getClientType())) {
            imNetworkBaseDto.setClientType(ClientEnum.STUDENT);
        }
        // 用户ID
        Long userId = sysUserService.getUserId();
        // IM用户ID
        String imUserId = String.valueOf(userId);
        if (ClientEnum.STUDENT == imNetworkBaseDto.getClientType()) {
            imUserId = imGroupService.getImUserId(imUserId, ClientEnum.STUDENT.name());
        }else {
            imUserId = imGroupService.getImUserId(imUserId, ClientEnum.TEACHER.name());
        }

        imNetworkRoomService.quitRoomSuccess(imNetworkBaseDto.getRoomId(), imUserId);
        return BaseResponse.success();
    }

    @ApiOperation("控制学员节拍器")
    @PostMapping(value = "/sendImPlayMidiMessage")
    public BaseResponse sendImPlayMidiMessage(@RequestBody ImNetworkCustomMessage customMessage) throws Exception {
        // 设置客户端类型
        if (Objects.isNull(customMessage.getClientType())) {
            customMessage.setClientType(ClientEnum.TEACHER);
        }
        imNetworkRoomService.sendImPlayMidiMessage(customMessage);
        return BaseResponse.success();
    }

    @ApiOperation("移动端用来渲染页面")
    @PostMapping(value = "/display")
    public BaseResponse display(@RequestBody ImNetworkDisplayDataDto displayData) throws Exception {
        // 设置客户端类型
        if (Objects.isNull(displayData.getClientType())) {
            displayData.setClientType(ClientEnum.TEACHER);
        }
        imNetworkRoomService.display(displayData);
        return BaseResponse.success();
    }

    @ApiOperation(value = "批量控制学员设备开关")
    @PostMapping(value = "/device/batchControl")
    public BaseResponse batchControlDevice(@RequestBody ImNetworkDeviceControlDto deviceControl)throws Exception {

        // 设置客户端类型
        if (Objects.isNull(deviceControl.getClientType())) {
            deviceControl.setClientType(ClientEnum.TEACHER);
        }

        imNetworkRoomService.batchControlDevice(deviceControl);
        return BaseResponse.success();
    }

    @ApiOperation(value = "控制学员设备开关")
    @PostMapping(value = "/device/control")
    public BaseResponse controlDevice(@RequestBody ImNetworkDeviceControlDto deviceControl)
            throws Exception {

        // 设置客户端类型
        if (Objects.isNull(deviceControl.getClientType())) {
            deviceControl.setClientType(ClientEnum.TEACHER);
        }

        imNetworkRoomService.controlDevice(deviceControl);
        return BaseResponse.success();
    }

    @ApiOperation(value = "学员同意打开，麦克风、摄像头")
    @PostMapping(value = "/device/approve")
    public BaseResponse approveControlDevice(@RequestBody ImNetworkDeviceControlDto deviceControl) throws Exception {
        deviceControl.setEnable(true);

        // 设置客户端类型
        if (Objects.isNull(deviceControl.getClientType())) {
            deviceControl.setClientType(ClientEnum.STUDENT);
        }

        imNetworkRoomService.approveControlDevice(deviceControl);
        return BaseResponse.success();
    }

    @ApiOperation(value = "学员拒绝打开，麦克风、摄像头")
    @PostMapping(value = "/device/reject")
    public BaseResponse rejectControlDevice(@RequestBody ImNetworkDeviceControlDto deviceControl)
            throws Exception {
        deviceControl.setEnable(false);

        // 设置客户端类型
        if (Objects.isNull(deviceControl.getClientType())) {
            deviceControl.setClientType(ClientEnum.STUDENT);
        }

        imNetworkRoomService.rejectControlDevice(deviceControl);
        return BaseResponse.success();
    }

    @ApiOperation(value = "学员设备状态同步")
    @PostMapping(value = "/device/sync")
    public Object deviceStatusSync(@RequestBody ImNetworkDeviceControlDto deviceControl)
            throws Exception {

        // 设置客户端类型
        if (Objects.isNull(deviceControl.getClientType())) {
            deviceControl.setClientType(ClientEnum.STUDENT);
        }

        imNetworkRoomService.deviceStatusSync(deviceControl);
        return BaseResponse.success();
    }

    @ApiOperation(value = "老师在网络教室选择完伴奏后、通知学员下载伴奏")
    @PostMapping(value = "pushDownloadMusicScoreMsg")
    public BaseResponse pushDownloadMusicSheetMsg(@RequestBody ImNetworkMusicSheetDto musicSheetDto) throws Exception {
        // 设置客户端类型
        if (Objects.isNull(musicSheetDto.getClientType())) {
            musicSheetDto.setClientType(ClientEnum.TEACHER);
        }
        imNetworkRoomService.pushDownloadMusicSheetMsg(musicSheetDto);
        return BaseResponse.success();
    }

    @ApiOperation(value = "学员伴奏下载状态回调")
    @PostMapping(value = "adjustExamSong")
    public BaseResponse adjustMusicScore(@RequestBody ImNetworkMusicSheetDto musicSheetDto) throws Exception {

        // 设置客户端类型
        if (Objects.isNull(musicSheetDto.getClientType())) {
            musicSheetDto.setClientType(ClientEnum.STUDENT);
        }

        imNetworkRoomService.musicSheetDownNotify(musicSheetDto);
        return BaseResponse.success();
    }

    @ApiOperation(value = "查询不在教室的学员")
    @GetMapping(value = "/queryNoJoinStu")
    public BaseResponse<List<BasicUserInfoDto>> queryNoJoinStu(String roomId){
        return BaseResponse.success(imNetworkRoomService.queryNoJoinStu(roomId));
    }
}

