package com.webchat.controller.client;

import com.webchat.common.enums.RedisMessageChannelTopicEnum;
import com.webchat.common.enums.RoleCodeEnum;
import com.webchat.common.util.JsonUtil;
import com.webchat.common.util.SpringContextUtil;
import com.webchat.domain.vo.request.mess.ChatMessageRequestVO;
import com.webchat.domain.vo.response.UserBaseResponseInfoVO;
import com.webchat.domain.vo.response.mess.ChatMessageResponseVO;
import com.webchat.service.UserService;
import com.webchat.service.ai.AiAgentFlowService;
import com.webchat.service.listener.RedisMessageSender;
import io.swagger.annotations.Api;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * OnOpen 表示有浏览器链接过来的时候被调用
 * OnClose 表示浏览器发出关闭请求的时候被调用
 * OnMessage 表示浏览器发消息的时候被调用
 * OnError 表示有错误发生，比如网络断开了等等
 */
@Api(tags = "【WS长链接】基础对话WebSocket Endpoint")
@Data
@Slf4j
@Component
@ServerEndpoint("/ws/chat/{userId}")
public class ChatWebSocket {

    /**
     * 在线人数
     */
    public static int onlineNumber = 0;

    /**
     * 以用户的Id作为key，WebSocket为对象保存起来
     */
    public static Map<String, ChatWebSocket> clients = new ConcurrentHashMap<String, ChatWebSocket>();

    /**
     * 会话
     */
    private Session session;

    /**
     * 用户ID
     */
    private String userId;

    /**
     * 建立连接
     *
     * @param session
     */
    @OnOpen
    public void onOpen(@PathParam("userId") String userId, Session session) {
        this.onlineNumber++;
        this.userId = userId;
        this.session = session;
        clients.put(userId, this);
        log.info("onOpen success. sessionId:{}, userId:{}, online user count:{}", session.getId(), userId, onlineNumber);
    }

    @OnError
    public void onError(Session session, Throwable error) {
        log.info("服务端发生了错误, error message:{}", error.getMessage());
    }

    /**
     * 连接关闭
     */
    @OnClose
    public void onClose() {
        this.onlineNumber--;
        this.clients.remove(userId);
        log.info("onClose success！ online user count:P{}", this.onlineNumber);
    }

    /**
     * 收到客户端的消息
     *
     * @param message 消息
     * @param session 会话
     */
    @OnMessage
    public void onMessage(String message, Session session) {

        if ("heartbeat".equals(message)) {
            // 心跳检测
            clients.get(userId).session.getAsyncRemote().sendText("ok");
            return;
        }
        RedisMessageSender redisMessageSender = SpringContextUtil.getBean(RedisMessageSender.class);
        redisMessageSender.sendMessage(RedisMessageChannelTopicEnum.CHAT.getChannel(), message);
    }

    public static synchronized int getOnlineCount() {
        return onlineNumber;
    }

}