package com.yonge.cooleshow.admin.controller.open;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.microsvc.toolkit.middleware.im.properties.ImConfigProperties;
import com.microsvc.toolkit.middleware.live.LivePluginContext;
import com.microsvc.toolkit.middleware.live.LivePluginService;
import com.microsvc.toolkit.middleware.live.impl.TencentCloudLivePlugin;
import com.yonge.cooleshow.admin.io.request.course.CourseRelationVo;
import com.yonge.cooleshow.admin.io.request.im.IMNotifyMessageVO;
import com.yonge.cooleshow.admin.io.request.im.UserFriendInfoVO;
import com.yonge.cooleshow.api.feign.dto.ImUserInfo;
import com.yonge.cooleshow.biz.dal.dto.LiveRoomStatus;
import com.yonge.cooleshow.biz.dal.dto.TencentData;
import com.yonge.cooleshow.biz.dal.dto.TencentImCallbackResult;
import com.yonge.cooleshow.biz.dal.entity.ImUserStateSync;
import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
import com.yonge.cooleshow.biz.dal.enums.im.ETencentImCallbackCommand;
import com.yonge.cooleshow.biz.dal.service.CourseRelationMusicAlbumService;
import com.yonge.cooleshow.biz.dal.service.ImGroupService;
import com.yonge.cooleshow.biz.dal.service.ImUserFriendService;
import com.yonge.cooleshow.biz.dal.service.LiveRoomService;
import com.yonge.cooleshow.biz.dal.wrapper.im.CustomerService;
import com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupWrapper;
import com.yonge.cooleshow.common.controller.BaseController;
import com.yonge.cooleshow.common.entity.HttpResponseResult;
import com.yonge.toolset.base.exception.BizException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
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.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * 用户通讯录表(ImUserFriend)表控制层
 *
 * @author zx
 * @since 2022-03-22 10:45:59
 */
@Api(tags = "用户通讯录表")
@RestController
@RequestMapping("/open")
@Slf4j
public class ImController extends BaseController {

    /**
     * 服务对象
     */
    @Resource
    private ImUserFriendService imUserFriendService;
    @Autowired
    private CourseRelationMusicAlbumService courseRelationMusicAlbumService;

    @Autowired
    private LivePluginContext livePluginContext;

    @Autowired
    private LiveRoomService liveRoomService;

    @Autowired
    private ImGroupService imGroupService;

    @Autowired
    private ImConfigProperties imConfig;


    @ApiOperation("新用户添加客服")
    @PostMapping(value = "/im/customerService")
    public HttpResponseResult<Boolean> customerService(@RequestBody UserFriendInfoVO info) {

        if (info.invalidRequestParam()) {
            return failed("无效的请求参数");
        }

        // 新用户自动绑定系统客服
        int ret = imUserFriendService.registerUserBindCustomerService(info.getUserId(),
                info.getFriendIds(), ClientEnum.valueOf(info.getClientType()));

        return succeed(ret > 0);
    }

    /**
     * 发送系统客服消息
     * @param info IMNotifyMessageVO
     * @return HttpResponseResult<Boolean>
     */
    @PostMapping(value = "/im/message")
    public HttpResponseResult<Boolean> sendSysCustomerServiceMessage(@RequestBody IMNotifyMessageVO info) {

        if (info.invalidRequestParam()) {
            return failed("无效的请求参数");
        }

        // 发送客服通知消息
        imUserFriendService.sendCustomerServiceNotifyMessage(info.getSender(),
                CustomerService.NotifyMessage.from(info.jsonString()));

        return succeed();
    }

    /**
     * 同步用户购买课程赠送数据
     * @param query CourseRelationVo.CourseRelationQuery
     * @return HttpResponseResult<Boolean>
     */
    @ApiOperation("已购买课程赠送同步")
    @PostMapping(value = "/course/sync")
    public HttpResponseResult<Boolean> syncUserPurchaseRelationMusicAlbum(@RequestBody CourseRelationVo.CourseRelationQuery query) {

        if (Objects.isNull(query.getCourseGroupId()) || Objects.isNull(query.getCourseType())) {
            return failed("无效的请求参数");
        }

        // 同步数据
        courseRelationMusicAlbumService.asyncUpdateCourseRelationMusicAlbumInfo(query.getCourseGroupId(), query.getCourseType());

        return succeed();
    }


    @ApiOperation("腾讯im 回调接口")
    @PostMapping(value = "/tencentImCallback")
    public TencentImCallbackResult tencentImCallback(@RequestBody Object obj, HttpServletRequest request) {
        String body = JSON.toJSONString(obj);
        log.info("tencentImCallback body：{}", body);

        LivePluginService pluginService = livePluginContext.getPluginService(TencentCloudLivePlugin.PLUGIN_NAME);
        String appKey = pluginService.getLiveRoomConfig().getAppKey();

        log.info("tencentImCallback request param：{}", JSON.toJSONString(request.getParameterMap()));

        List<String> sdkList = Arrays.asList(request.getParameterValues("SdkAppid"));
        if (sdkList == null || sdkList.size() == 0) {
            log.error("tencentImCallback sdkAppid is null");
            return new TencentImCallbackResult();
        }
        if (!sdkList.contains(appKey)) {
            log.error("tencentImCallback sdkAppid is not match");
            return new TencentImCallbackResult();
        }

        String clientIP = request.getParameter("ClientIP");
        String optPlatform = request.getParameter("OptPlatform");


        if(request.getParameter("CallbackCommand").equals(ETencentImCallbackCommand.GROUP_CALLBACKONMEMBERSTATECHANGE.getCommand())) {
            // 直播群成员在线状态回调
            TencentData.CallbackOnMemberStateChange callbackOnMemberStateChange = TencentData.CallbackOnMemberStateChange.toObject(
                    body);

            log.debug("callbackOnMemberStateChange: {}", callbackOnMemberStateChange);
            callbackOnMemberStateChange.setClientIP(clientIP);
            callbackOnMemberStateChange.setOptPlatform(optPlatform);
            for (TencentData.MemberListDTO memberListDTO : callbackOnMemberStateChange.getMemberList()) {
                if (!imGroupService.checkImUserId(memberListDTO.getMemberAccount())) {
                    return new TencentImCallbackResult();
                }
                memberListDTO.setMemberAccount(imGroupService.analysisImUserId(memberListDTO.getMemberAccount()));
            }
            // 直播间成员状态变更
            liveRoomService.callbackOnMemberStateChange(callbackOnMemberStateChange);
        } else if(request.getParameter("CallbackCommand").equals(ETencentImCallbackCommand.GROUP_CALLBACKAFTERMEMBEREXIT.getCommand())) {
            // 群成员离开之后回调
            TencentData.CallbackAfterMemberExit callbackAfterMemberExit = TencentData.CallbackAfterMemberExit.toObject(
                    body);

            log.debug("callbackAfterMemberExit: {}", callbackAfterMemberExit);
            callbackAfterMemberExit.setClientIP(clientIP);
            callbackAfterMemberExit.setOptPlatform(optPlatform);
            for (TencentData.MemberListDTO memberListDTO : callbackAfterMemberExit.getExitMemberList()) {
                if (!imGroupService.checkImUserId(memberListDTO.getMemberAccount())) {
                    return new TencentImCallbackResult();
                }
                memberListDTO.setMemberAccount(imGroupService.analysisImUserId(memberListDTO.getMemberAccount()));
            }
            // 直播间成员状态变更
            liveRoomService.callbackAfterMemberExit(callbackAfterMemberExit);
        } else if(request.getParameter("CallbackCommand").equals(ETencentImCallbackCommand.GROUP_CALLBACKAFTERNEWMEMBERJOIN.getCommand())) {
            // 新成员入群之后回调
            TencentData.CallbackAfterNewMemberJoin callbackAfterNewMemberJoin = TencentData.CallbackAfterNewMemberJoin.toObject(
                    body);

            log.debug("CallbackAfterNewMemberJoin: {}", callbackAfterNewMemberJoin);
            callbackAfterNewMemberJoin.setClientIP(clientIP);
            callbackAfterNewMemberJoin.setOptPlatform(optPlatform);
            for (TencentData.MemberListDTO memberListDTO : callbackAfterNewMemberJoin.getNewMemberList()) {
                if (!imGroupService.checkImUserId(memberListDTO.getMemberAccount())) {
                    return new TencentImCallbackResult();
                }
                memberListDTO.setMemberAccount(imGroupService.analysisImUserId(memberListDTO.getMemberAccount()));
            }
            // 直播间成员状态变更
            liveRoomService.callbackAfterNewMemberJoin(callbackAfterNewMemberJoin);
        }


        return new TencentImCallbackResult();
    }


    @ApiOperation("腾讯云直播-推流 回调接口")
    @PostMapping(value = "/tencentStreamEventCallback")
    public TencentData.StreamEventCallbackResult tencentStreamEventCallback(@RequestBody Object obj) {
        String body = JSON.toJSONString(obj);
        log.info("tencentStreamEventCallback body：{}", body);

        TencentData.CallbackStreamStateEvent event = TencentData.CallbackStreamStateEvent.from(body);

        boolean b = checkStream(event.getStreamId());
        if (!b) {
            return TencentData.StreamEventCallbackResult.builder().code(0).build();
        }

        ImUserStateSync imUserState = new ImUserStateSync();
        imUserState.setUserid(getSpeakerId(event.getStreamId()).toString());
        // 断流事件通知
        if (event.getEventType() == 0) {
            imUserState.setStatus("3");

            // 更新推流时长
            if (StringUtils.isNotBlank(event.getPushDuration()) && event.getPushDuration().matches("\\d+")) {
                // 更新直播推流时长
                liveRoomService.updateLiveRoomPushStreamTime(event);
            }

            // 自动关闭录制
            liveRoomService.closeLive(getRoomUid(event.getStreamId()), getSpeakerId(event.getStreamId()).longValue(),event.getSequence());
            // 同步点赞数
            liveRoomService.syncLikeCount(getRoomUid(event.getStreamId()));
        }

        // 推流事件通知
        if (event.getEventType() == 1) {
            // 房间uid
            String roomUid = getRoomUid(event.getStreamId());

            LiveRoomStatus roomStatus = new LiveRoomStatus();
            // 房间ID
            roomStatus.setRoomUid(roomUid);
            // 主播状态
            roomStatus.setSpeakerStatus(1);
            // 推流状态
            roomStatus.setPushStatus(1);
            // 更新直播间状态
            liveRoomService.updateRoomStatus(roomStatus);
            // 自动开启录制
            liveRoomService.startLive(roomUid, getSpeakerId(event.getStreamId()), event.getSequence());

            imUserState.setStatus("0");
        }
        liveRoomService.opsRoom(Lists.newArrayList(imUserState));

        return TencentData.StreamEventCallbackResult.builder().code(0).build();
    }


    private boolean checkStream(String streamId) {
        return imGroupService.checkImUserId(streamId.split("_",2)[1]);
    }


    private Integer getSpeakerId(String streamId) {
        return Integer.parseInt(imGroupService.analysisImUserId(streamId.split("_",2)[1]));
    }

    private String getRoomUid(String streamId) {
        return streamId.split("_")[0];
    }

    @ApiOperation("腾讯云直播-录制 回调接口")
    @PostMapping(value = "/tencentStreamRecordCallback")
    public TencentData.StreamEventCallbackResult tencentStreamRecordCallback(@RequestBody Object obj) {
        String body = JSON.toJSONString(obj);
        log.info("tencentStreamRecordCallback body：{}", body);

        TencentData.CallbackSteamRecordEvent event = TencentData.CallbackSteamRecordEvent.from(body);


        boolean b = checkStream(event.getStreamId());
        if (!b) {
            return TencentData.StreamEventCallbackResult.builder().code(0).build();
        }

        // 直播录制事件通知
        if (event.getStreamId().startsWith("LIVE")) {
            log.info("taskId={}, url={}", event.getTaskId(), event.getVideoUrl());

            // 生成直播录制信息
            liveRoomService.createLiveRoomVideoRecord(event);
        }

        return TencentData.StreamEventCallbackResult.builder().code(0).build();
    }

    @ApiOperation("腾讯云直播-推流异常 回调接口")
    @PostMapping(value = "/tencentStreamExceptionCallback")
    public TencentData.StreamEventCallbackResult tencentStreamExceptionCallback(@RequestBody Object obj) {
        String body = JSON.toJSONString(obj);
        log.info("tencentStreamExceptionCallback body：{}", body);

        return TencentData.StreamEventCallbackResult.builder().code(0).build();
    }

    @ApiOperation("注册im用户")
    @PostMapping(value = "/im/register")
    public ImUserInfo register(String userId, ClientEnum clientType, String username, String avatar) {

        log.info("注册im用户");

        try {
            ImGroupWrapper.ImUserInfo register = imGroupService.register(userId, clientType, username, avatar);
            return JSON.parseObject(JSON.toJSONString(register), ImUserInfo.class);
        } catch (Exception e) {
            log.error("注册im用户失败", e);
            throw new BizException(e.getMessage());
        }
    }

}

