package com.ruoyi.cai.ws.manager;

import com.ruoyi.cai.domain.Anchor;
import com.ruoyi.cai.domain.User;
import com.ruoyi.cai.domain.UserCall;
import com.ruoyi.cai.service.AnchorService;
import com.ruoyi.cai.service.UserCallService;
import com.ruoyi.cai.service.UserInviteService;
import com.ruoyi.cai.service.UserService;
import com.ruoyi.cai.ws.bean.Room;
import com.ruoyi.cai.ws.bean.RoomData;
import com.ruoyi.cai.ws.bean.UserData;
import com.ruoyi.cai.ws.cache.CallerRoomCache;
import com.ruoyi.cai.ws.cache.RoomDataCache;
import com.ruoyi.cai.ws.cache.UserDataCache;
import com.ruoyi.cai.ws.constant.RedisConstant;
import com.ruoyi.cai.ws.service.RoomService;
import com.ruoyi.common.exception.ServiceException;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class WebSocketManager {
    @Autowired
    private CallerRoomCache callerRoomCache;
    @Autowired
    private RoomService roomService;
    @Autowired
    private UserCallService userCallService;
    @Autowired
    private UserService userService;
    @Autowired
    private AnchorService anchorService;
    @Autowired
    private UserInviteService userInviteService;
    @Autowired
    private RoomDataCache roomDataCache;
    @Autowired
    private UserDataCache userDataCache;
    @Autowired
    private RedissonClient redissonClient;

    public Room checkOnlineRoom(Long fromUserId,Long toUserId){
        Long roomId = callerRoomCache.getRoomId(fromUserId, toUserId);
        if(roomId == null){
            return null;
        }
        Room room = roomService.load(roomId);
        if(room == null){
            return null;
        }
        return room;
    }

    public Long createRoom(Long roomId) {
        UserCall userCall = userCallService.getById(roomId);
        if(userCall == null){
            throw new ServiceException("无效房间");
        }
        Room room = checkOnlineRoom(userCall.getFromUid(), userCall.getToUid());
        if(room != null && room.isCanCall()){ // 缓存中存在旧房间，直接返回
            return room.getRoomId();
        }
        RLock lock = redissonClient.getLock(String.format(RedisConstant.INIT_ROOM_LOCK, userCall.getFromUid(), userCall.getToUid()));
        boolean b = lock.tryLock();
        if(!b){
            throw new ServiceException("系统繁忙");
        }
        try {
            roomId = initRoom(userCall);
        }finally {
            lock.unlock();
        }
        return roomId;
    }

    public Long initRoom(UserCall call){
        call = userCallService.getById(call.getId());
        User callUser = userService.getById(call.getFromUid());
        if(callUser == null){
            throw new ServiceException("无效的呼叫方");
        }
        User receiverUser = userService.getById(call.getToUid());
        if(receiverUser == null){
            throw new ServiceException("无效的接收方");
        }
        Anchor anchor = anchorService.getByUserId(call.getToUid());
        if(anchor == null){
            throw new ServiceException("接收方不是女神");
        }
        // 检查视频状态
        if(anchor.getVideoStatus() != 0){
            throw new ServiceException("对方正在视频中");
        }
        // 检查女神在线状态 TODO

        // 关闭发起的其他房间


        roomService.closeAllRoom(call.getFromUid());
        // 删除旧房间记录
        roomService.delCallRoom(call.getFromUid());
        // 初始化
        RoomData roomData = new RoomData();
        roomData.setRoomId(call.getId());
        roomData.setCallPrice(call.getCallPrice());
        roomData.setSkillName(call.getSkillName());
        roomData.setStatus(call.getStatus());
        roomData.setVideoDivide(call.getReceiverVideoDivide());
        roomDataCache.init(roomData);
        UserData callerUserData = new UserData();
        callerUserData.setId(call.getFromUid());
        callerUserData.setRoomId(call.getId());
        callerUserData.setNickname(callUser.getNickname());
        callerUserData.setUserCode(callUser.getUsercode());
        userDataCache.initCaller(callerUserData);
        UserData receiveUserData = new UserData();
        receiveUserData.setId(call.getToUid());
        receiveUserData.setRoomId(call.getId());
        receiveUserData.setNickname(receiverUser.getNickname());
        receiveUserData.setUserCode(receiverUser.getUsercode());
        receiveUserData.setInviterId(call.getReceiverInviteUserId());
        receiveUserData.setInviterRate(call.getReceiverIncomeDivide());
        receiveUserData.setInviterIsGet(call.getReceiverInviteGet());
        receiveUserData.setUnionUserId(call.getReceiverUnionUserId());
        receiveUserData.setUnionUserRate(call.getReceiverUnionVideoDivide());
        receiveUserData.setUnionIsGet(call.getReceiverUnionGet());
        userDataCache.initReceiver(callerUserData);
        callerRoomCache.addRoom(call.getFromUid(),call.getToUid(),call.getId());
        return call.getId();

    }
}
