package com.fs.app.socket;

import com.alibaba.fastjson.JSON;
import com.fs.app.socket.configurator.QwImConfigurator;
import com.fs.qw.vo.QwMessageListVO;
import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;

@ServerEndpoint(value = "/qwImSocket/{companyId}", configurator = QwImConfigurator.class)
@Component
public class QwImSocket {

    private static final ConcurrentHashMap<Long, CopyOnWriteArraySet<Session>> companySessions = new ConcurrentHashMap<>();

    /**
     * 连接建立成功调用的方法
     * @param session   连接会话
     * @param companyId 公司ID
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("companyId") Long companyId) {
        // 将当前会话加入到会话池中
        companySessions.computeIfAbsent(companyId, k -> new CopyOnWriteArraySet<>()).add(session);
    }

    /**
     * 连接关闭调用的方法
     * @param session   连接会话
     * @param companyId 公司ID
     */
    @OnClose
    public void onClose(Session session, @PathParam("companyId") Long companyId) {
        // 从会话池中移除当前会话
        CopyOnWriteArraySet<Session> sessions = companySessions.get(companyId);
        if (sessions != null) {
            sessions.remove(session);
            // 如果直播间没人了，可以移除该直播间
            if (sessions.isEmpty()) {
                companySessions.remove(companyId);
            }
        }
    }

    /**
     * 发生错误时调用的方法
     * @param session   连接会话
     * @param companyId 公司ID
     * @param error     错误对象
     */
    @OnError
    public void onError(Session session, @PathParam("companyId") Long companyId, Throwable error) {
        System.err.println("发生错误！会话ID: " + session.getId());
        CopyOnWriteArraySet<Session> sessions = companySessions.get(companyId);
        if (sessions != null) {
            sessions.remove(session);
            // 如果直播间没人了，可以移除该直播间
            if (sessions.isEmpty()) {
                companySessions.remove(companyId);
            }
        }
    }

    /**
     * 群发消息
     * @param message   要发送的消息
     */
    public static void broadcast(QwMessageListVO message) {
        if (Objects.isNull(message)) {
            return;
        }

        String msg = JSON.toJSONString(message);
        CopyOnWriteArraySet<Session> sessions = companySessions.get(message.getCompanyId());
        if (sessions != null) {
            for (Session session : sessions) {
                if (session.isOpen()) {
                    try {
                        session.getBasicRemote().sendText(msg);
                    } catch (IOException e) {
                        System.err.println("发送消息给会话[" + session.getId() + "]失败: " + e.getMessage());
                        // 移除无效会话
                        sessions.remove(session);
                    }
                } else {
                    sessions.remove(session); // 移除已关闭的会话
                }
            }
        }
    }

}
