/**
 * 状态管理
 * 使用简单的 Observable 模式，可替换为 Redux/Vuex/Pinia
 */
import { mockCallSession } from './models.js';
import { Signaling, WebSocketSignaling } from "../../module/signaling.js";// 信令管理
import { RenderStreaming } from "../../module/renderstreaming.js"; // WebRTC连接管理
import { getServerConfig, getRTCConfiguration } from "../js/config.js";//服务器配置和RTC配置
import { showNotification, generateId } from './utils.js'; // 导入通知函数
import chatMessage from './chatmessage.js';

const AUDIO_CONFIG = {
    echoCancellation: true,
    noiseSuppression: true,
    autoGainControl: true
};

const VAD_CONFIG = {
    threshold: 15,
    debounceTime: 500,
    fftSize: 256
};

const MEDIA_CONSTRAINTS = {
    video: {
        width: { ideal: 1920, max: 1920 },
        height: { ideal: 1080, max: 1080 },
        frameRate: { ideal: 30, max: 30 }
    },
    audio: AUDIO_CONFIG
};

const VIDEO_ONLY_CONSTRAINT = {
    video: {
        width: { ideal: 1920, max: 1920 },
        height: { ideal: 1080, max: 1080 },
        frameRate: { ideal: 30, max: 30 }
    },
    audio: false
};

class CallStateManager {
    constructor() {
        // 核心状态
        this.state = {
            id: generateId(),
            session: {
                ...mockCallSession,
                status: 'idle' // 初始状态为空闲
            },
            localStream: null,  // MediaStream 对象
            remoteStream: null,  // 单路远端流（兼容旧逻辑，participant端使用）
            remoteStreams: {},     // 多路远端流 Map: { connectionId: MediaStream }（host端使用）
            participants: {}     // 多Participant用户信息 Map: { participantId: { id, name, avatar, mediaState, status } }（host端使用）
        };

        // 监听器数组
        this.listeners = [];
    }

    // 订阅状态变化
    subscribe(callback) {
        this.listeners.push(callback);
        return () => {
            this.listeners = this.listeners.filter(cb => cb !== callback);
        };
    }

    // 通知所有监听器
    notify(changes) {
        this.listeners.forEach(cb => cb(this.state, changes));
    }

    // 初始化
    async init() {
        // 初始化配置
        await this.setupConfig();
        // 加载用户设置
        this.loadUserSettings();
        // 获取本地摄像头视频流
        await this.getLocalStream();
    }

    // 加载用户设置
    loadUserSettings() {
        const userSettings = localStorage.getItem('userSettings');
        if (userSettings) {
            try {
                const settings = JSON.parse(userSettings);

                // 更新本地用户信息
                if (settings.name || settings.avatar) {
                    this.state.session.localUser = {
                        ...this.state.session.localUser,
                        id: settings.userId || this.state.session.localUser.id,
                        name: settings.name || this.state.session.localUser.name,
                        avatar: settings.avatar || this.state.session.localUser.avatar
                    };

                    // 通知UI更新
                    this.notify({ type: 'USER_SETTINGS_UPDATED', user: this.state.session.localUser });
                }

                // 恢复保存的分辨率设置
                if (settings.resolution) {
                    this._savedResolution = settings.resolution;
                    console.log(`已恢复分辨率设置: ${settings.resolution.width}x${settings.resolution.height}`);
                }
            } catch (error) {
                console.error('Error loading user settings:', error);
            }
        }
    }
    async setupConfig() {
        const res = await getServerConfig();
        this.useWebSocket = res.useWebSocket;
    }
    // 获取本地摄像头视频流
    async getLocalStream() {
        try {
            console.log('Requesting camera permission...');

            // 检查浏览器是否支持getUserMedia
            if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
                console.error('getUserMedia is not supported');
                throw new Error('getUserMedia is not supported');
            }

            // 请求摄像头权限并获取媒体流，启用回声消除
            // 使用保存的分辨率（如有），否则使用默认约束
            const videoConstraints = this._savedResolution
                ? {
                    width: { ideal: this._savedResolution.width, max: this._savedResolution.width },
                    height: { ideal: this._savedResolution.height, max: this._savedResolution.height },
                    frameRate: { ideal: 30, max: 30 }
                }
                : MEDIA_CONSTRAINTS.video;
            const stream = await navigator.mediaDevices.getUserMedia({
                video: videoConstraints,
                audio: AUDIO_CONFIG
            });

            console.log('Stream obtained successfully:', stream);
            console.log('Video tracks:', stream.getVideoTracks());
            console.log('Audio tracks:', stream.getAudioTracks());

            this.state.localStream = stream;
            this.state.session.localUser.mediaState.video = true;
            this.state.session.localUser.mediaState.audio = true;

            console.log('Local stream stored, notifying UI...');

            // 先通知视频流已获取
            this.notify({ type: 'LOCAL_STREAM_OBTAINED', stream });
            // 再通知媒体状态变化
            this.notify({ type: 'LOCAL_MEDIA_CHANGE', mediaType: 'video', value: true });
            this.notify({ type: 'LOCAL_MEDIA_CHANGE', mediaType: 'audio', value: true });

            // 发送媒体状态到服务器
            this.emitMediaStateChange();

            // 启动本地音频活动检测
            this.startActivityDetection(this.state.localStream, { isLocal: true });
        } catch (error) {
            console.error('Error getting local stream:', error);
            // 如果获取视频失败，保持视频关闭状态
            this.state.session.localUser.mediaState.video = false;
            this.state.session.localUser.mediaState.audio = false;

            // 通知媒体状态变化
            this.notify({ type: 'LOCAL_MEDIA_CHANGE', mediaType: 'video', value: false });
            this.notify({ type: 'LOCAL_MEDIA_CHANGE', mediaType: 'audio', value: false });
        }
    }

    // 更新本地媒体状态
    async updateLocalMedia(mediaType, value) {

        // 如果是开启视频，重新获取摄像头资源
        if (mediaType === 'video' && value) {
            try {
                // 只获取新的视频轨道，不干扰正在工作的音频
                const newVideoStream = await navigator.mediaDevices.getUserMedia(VIDEO_ONLY_CONSTRAINT);
                const newVideoTrack = newVideoStream.getVideoTracks()[0];

                if (!newVideoTrack) {
                    throw new Error('Failed to get video track');
                }

                // 更新本地流中的视频轨道（替换旧的已停止的轨道）
                if (this.state.localStream) {
                    const oldVideoTracks = this.state.localStream.getVideoTracks();
                    oldVideoTracks.forEach(track => {
                        track.stop();
                        this.state.localStream.removeTrack(track);
                    });
                    this.state.localStream.addTrack(newVideoTrack);
                } else {
                    // 本地流不存在时（不应该发生），使用新流
                    this.state.localStream = newVideoStream;
                }

                // 更新WebRTC连接中的视频轨道
                if (this.renderstreaming) {
                    console.log('Updating video track in WebRTC connection');

                    if (this.role === 'host') {
                        // Host端：需要遍历所有participant的peer来替换视频轨道
                        const participantIds = Object.keys(this.state.remoteStreams);
                        for (const participantId of participantIds) {
                            const transceivers = this.renderstreaming.getTransceivers(participantId);
                            if (!transceivers) continue;

                            const videoTransceivers = transceivers.filter(t =>
                                t.sender && t.sender.track && t.sender.track.kind === 'video'
                            );

                            if (videoTransceivers.length > 0) {
                                for (const transceiver of videoTransceivers) {
                                    try {
                                        await transceiver.sender.replaceTrack(newVideoTrack);
                                        console.log(`Replaced video track for participant ${participantId}`);
                                    } catch (error) {
                                        console.error(`Error replacing video track for ${participantId}:`, error);
                                    }
                                }
                            } else {
                                // 没有视频收发器，添加新的
                                try {
                                    this.renderstreaming.addTransceiver(newVideoTrack, { direction: 'sendonly' }, participantId);
                                    console.log(`Added new video transceiver for participant ${participantId}`);
                                } catch (error) {
                                    console.error(`Error adding video transceiver for ${participantId}:`, error);
                                }
                            }

                            // 设置编解码器偏好
                            setTimeout(() => { this.setCodecPreferences(participantId); }, 100);
                            setTimeout(() => { this.setVideoEncodingParameters(participantId); }, 200);
                        }
                    } else {
                        // Participant端：使用单一peer
                        const transceivers = this.renderstreaming.getTransceivers();
                        if (transceivers) {
                            const videoTransceivers = transceivers.filter(t =>
                                t.sender && t.sender.track && t.sender.track.kind === 'video'
                            );

                            if (videoTransceivers.length > 0) {
                                for (const transceiver of videoTransceivers) {
                                    try {
                                        await transceiver.sender.replaceTrack(newVideoTrack);
                                        console.log('Successfully replaced video track');
                                    } catch (error) {
                                        console.error('Error replacing video track:', error);
                                    }
                                }
                            } else {
                                try {
                                    this.renderstreaming.addTransceiver(newVideoTrack, { direction: 'sendonly' });
                                    console.log('Added new video transceiver');
                                } catch (error) {
                                    console.error('Error adding video transceiver:', error);
                                }
                            }
                        }
                        setTimeout(() => { this.setCodecPreferences(); }, 100);
                        setTimeout(() => { this.setVideoEncodingParameters(); }, 200);
                    }
                }

                // 更新状态和通知UI
                this.state.session.localUser.mediaState.video = true;
                this.notify({ type: 'LOCAL_STREAM_OBTAINED', stream: this.state.localStream });
                this.notify({ type: 'LOCAL_MEDIA_CHANGE', mediaType: 'video', value: true });
                this.emitMediaStateChange();
                this.startActivityDetection(this.state.localStream, { isLocal: true });

            } catch (error) {
                console.error('Error reopening video:', error);
                this.state.session.localUser.mediaState.video = false;
                this.notify({ type: 'LOCAL_MEDIA_CHANGE', mediaType: 'video', value: false });
            }
        } else {
            // 直接更新媒体状态
            this.state.session.localUser.mediaState[mediaType] = value;
            this.notify({ type: 'LOCAL_MEDIA_CHANGE', mediaType, value });

            // 发送媒体状态到服务器
            this.emitMediaStateChange();
        }


        // 如果是关闭视频，释放摄像头资源
        if (mediaType === 'video' && !value && this.state.localStream) {
            this.state.session.localUser.mediaState.video = false;
            this.state.localStream.getTracks().forEach(track => {
                if (track.kind === 'video') {
                    track.stop();
                }
            });
            // 发送媒体状态到服务器
            this.emitMediaStateChange();

        }

        // 如果是音频状态变化，控制本地音频轨道
        if (mediaType === 'audio' && this.state.localStream) {
            this.state.session.localUser.mediaState.audio = value;
            this.state.localStream.getTracks().forEach(track => {
                if (track.kind === 'audio') {
                    track.enabled = value;
                }
            });
            // 发送媒体状态到服务器
            this.emitMediaStateChange();
        }

        // 通知UI更新用户列表
        this.notify({ type: 'USER_LIST_UPDATE', localUser: this.state.session.localUser, remoteUser: this.state.session.remoteUser });

    }

    /**
     * 创建信令和RTC实例
     * @async
     * @param {string} connectionId - 连接ID
     * @returns {Promise<void>}
     */
    async _createSignalingAndRTC(connectionId) {
        this.connectionId = connectionId; // 获取连接ID
        // 设置状态为连接中
        this.state.session.status = 'connecting';
        this.notify({ type: 'CALL_STATUS_CHANGE', status: 'connecting' });

        // 确保本地流已经初始化
        if (!this.state.localStream) {
            console.log('Local stream not available, waiting for initialization...');
            // 等待localStream初始化
            await new Promise((resolve) => {
                const checkStream = () => {
                    if (this.state.localStream) {
                        resolve();
                    } else {
                        setTimeout(checkStream, 100);
                    }
                };
                checkStream();
            });
        }

        // 创建信令实例
        const signaling = this.useWebSocket ? new WebSocketSignaling() : new Signaling();
        const config = getRTCConfiguration(); // 获取RTC配置
        this.renderstreaming = new RenderStreaming(signaling, config);
    }

    /**
     * 设置WebRTC连接
     * @async
     * @returns {Promise<void>}
     */
    async setUp(connectionId) {
        await this._createSignalingAndRTC(connectionId);
        this._registerCallbacks();
        await this._startConnection(connectionId);
    }

    /**
     * 注册所有WebRTC回调
     */
    _registerCallbacks() {
        this.renderstreaming.onNewPeer = (participantId) => {
            console.log(`New peer created for ${participantId}, adding local tracks`);
            if (this.state.localStream) {
                const tracks = this.state.localStream.getTracks();
                for (const track of tracks) {
                    this.renderstreaming.addTransceiver(track, { direction: 'sendonly' }, participantId);
                }
                this.setCodecPreferences(participantId);
                this.setVideoEncodingParameters(participantId);
            }
        };

        // 连接建立回调
        this.renderstreaming.onConnect = (connectionId, data) => {
            // 保存角色信息（host/participant）
            if (data && data.role) {
                this.role = data.role;
                // 更新localUser的isHost标志
                this.state.session.localUser.isHost = (this.role === 'host');
                // 保存自身的participantId，用于从participants-sync中过滤自身
                if (data.participantId) {
                    this.selfParticipantId = data.participantId;
                }
                console.log(`Connected as ${this.role}, participantId: ${this.selfParticipantId}`);
            }
            // 连接建立后，更新状态为ongoing
            this.state.session.status = 'ongoing';
            this.notify({ type: 'CALL_STATUS_CHANGE', status: 'ongoing' });

            // 参与者加入时默认静音：禁用音频轨道并更新状态
            if (this.role === 'participant') {
                if (this.state.localStream) {
                    this.state.localStream.getAudioTracks().forEach(track => {
                        track.enabled = false;
                    });
                }
                this.state.session.localUser.mediaState.audio = false;
                this.notify({ type: 'LOCAL_MEDIA_CHANGE', mediaType: 'audio', value: false });
                console.log('Participant joined with audio muted by default');
            }

            // 连接建立后发送本地用户信息
            this.sendMessage('user-info', {
                id: this.state.session.localUser.id,
                name: this.state.session.localUser.name,
                avatar: this.state.session.localUser.avatar
            });

            // 发送当前媒体状态，确保远端收到正确的初始状态
            this.emitMediaStateChange();

            if (this.state.localStream) {
                // const tracks = this.state.localStream.getTracks();
                // for (const track of tracks) {
                //     this.renderstreaming.addTransceiver(track, { direction: 'sendonly' });
                // }
                // this.setCodecPreferences();
                this.showStatsMessage();
            } else {
                console.error('Local stream is not available');
                showNotification('本地视频流不可用', 'error');
            }
        };

        // 连接断开回调（收到服务器的 disconnect 消息，通常是 host 离开导致房间关闭）
        this.renderstreaming.onDisconnect = () => {
            console.log('Received disconnect from server, host left or room closed');
            this.hangUp(); // 房间已关闭，挂断连接
        };

        // SDP Answer 接收回调：重新设置编码参数以保障画质
        this.renderstreaming.onGotAnswer = (connectionId) => {
            console.log('SDP Answer received, resetting encoding parameters for connectionId:', connectionId);
            if (this.role === 'host') {
                const allParticipantIds = Object.keys(this.state.remoteStreams || {});
                for (const pid of allParticipantIds) {
                    setTimeout(() => { this.setVideoEncodingParameters(pid); }, 50);
                }
            } else {
                setTimeout(() => { this.setVideoEncodingParameters(); }, 50);
            }
        };

        // participant加入回调（host收到，新participant加入房间）
        this.renderstreaming.onParticipantJoined = (participantId) => {
            console.log(`Participant joined: ${participantId}`);
            if (!this.state.participants[participantId]) {
                this.state.participants[participantId] = {
                    id: '',
                    name: '参与者',
                    avatar: '/images/p2.png',
                    mediaState: { audio: false, video: true, isSpeaking: false },
                    status: 'online'
                };
            }
            this.notify({ type: 'PARTICIPANTS_UPDATE', participants: this.state.participants });
            this.broadcastParticipantsList();
        };

        // participant离开回调（host收到，房间仍然存在）
        this.renderstreaming.onParticipantLeft = (participantId) => {
            console.log(`Participant left: ${participantId}, room still active`);
            this.updateRemoteUserStatus('offline');
            this.updateRemoteUserNetworkQuality('no_signal');
            showNotification('对方已离开通话', 'warning');
            // 清理该 participant 的远端流
            if (this.state.remoteStreams[participantId]) {
                this.state.remoteStreams[participantId].getTracks().forEach(track => track.stop());
                delete this.state.remoteStreams[participantId];
            }
            if (this.state.remoteStream) {
                this.state.remoteStream.getTracks().forEach(track => track.stop());
                this.state.remoteStream = null;
            }
            // 清理该 participant 的用户信息
            delete this.state.participants[participantId];
            // 通知UI更新，用participantId作为connectionId传给renderer
            this.notify({ type: 'PARTICIPANT_LEFT', connectionId: participantId });
            this.notify({ type: 'PARTICIPANTS_UPDATE', participants: this.state.participants });
            this.broadcastParticipantsList();
        };

        // 轨道事件回调
        this.renderstreaming.onTrackEvent = (data) => {
            const direction = data.transceiver.direction;
            if (direction == "sendrecv" || direction == "recvonly") {
                // 使用participantId区分不同participant的流
                const trackParticipantId = data.participantId || this.connectionId;
                const isHost = this.role === 'host';

                let targetStream = null;
                if (isHost) {
                    // Host端: 按 participantId 管理多路远端流
                    if (!this.state.remoteStreams[trackParticipantId]) {
                        this.state.remoteStreams[trackParticipantId] = new MediaStream();
                    }
                    targetStream = this.state.remoteStreams[trackParticipantId];
                } else {
                    // Participant端: 使用单一远端流
                    if (this.state.remoteStream == null) {
                        this.state.remoteStream = new MediaStream();
                    }
                    targetStream = this.state.remoteStream;
                }

                // 检查是否已经有相同类型的轨道
                const existingTracks = targetStream.getTracks().filter(track => track.kind === data.track.kind);
                existingTracks.forEach(track => {
                    targetStream.removeTrack(track);
                    console.log('Removed old track:', track.kind);
                });

                targetStream.addTrack(data.track);
                console.log('Added new track:', data.track.kind, 'for participant:', trackParticipantId);

                // Host端兜底：确保participants中有该participant条目
                if (isHost && !this.state.participants[trackParticipantId]) {
                    this.state.participants[trackParticipantId] = {
                        id: '',
                        name: '参与者',
                        avatar: '/images/p2.png',
                        mediaState: { audio: false, video: true, isSpeaking: false },
                        status: 'online'
                    };
                    this.notify({ type: 'PARTICIPANTS_UPDATE', participants: this.state.participants });
                    this.broadcastParticipantsList();
                }

                // 通知UI远程流已更新
                // 关键优化：如果是音频轨道先到达且流中尚无视频轨道，
                // 延迟通知UI等待视频轨道到达，避免音频先触发的UI更新导致黑屏
                const notifyStreamUpdate = () => {
                    this.notify({
                        type: 'REMOTE_STREAM_OBTAINED',
                        stream: targetStream,
                        connectionId: trackParticipantId,
                        isHost: isHost
                    });
                    console.log('Notified UI about remote stream update');
                };

                if (data.track.kind === 'audio' && targetStream.getVideoTracks().length === 0) {
                    // 音频先到，视频尚未到达：延迟200ms通知，给视频轨道到达的机会
                    console.log('Audio track arrived first, delaying stream notification for video track...');
                    setTimeout(() => {
                        const nowHasVideo = targetStream.getVideoTracks().length > 0;
                        console.log(`After delay, stream has video: ${nowHasVideo}`);
                        notifyStreamUpdate();
                    }, 200);
                } else {
                    // 视频轨道到达，或音频视频同时存在：立即通知
                    notifyStreamUpdate();
                }
                // 只有当收到远程流时才更新远程用户状态为在线
                if (this.state.session.remoteUser.status !== 'online') {
                    this.updateRemoteUserStatus('online');
                    // 更新远程用户网络质量为好
                    this.updateRemoteUserNetworkQuality('good');

                    this.sendMessage('user-info', {
                        id: this.state.session.localUser.id,
                        name: this.state.session.localUser.name,
                        avatar: this.state.session.localUser.avatar
                    });
                    // 启动通话时长计时器（避免重复启动）
                    if (!this.durationInterval) {
                        this.durationInterval = setInterval(() => {
                            this.state.session.duration++;
                            this.notify({ type: 'DURATION_UPDATE', duration: this.state.session.duration });
                        }, 1000);
                    }
                }
                // 如果是音频轨道，启动远程音频活动检测
                if (data.track.kind === 'audio') {
                    this.startActivityDetection(this.state.remoteStream, { isLocal: false });
                }
            } else if (direction == "sendonly") {
                // 本地发送轨道，启动本地音频活动检测
                if (data.track.kind === 'audio') {
                    this.startActivityDetection(this.state.localStream, { isLocal: true });
                }
            }
        };

        this.renderstreaming.onMessage = (data) => {
            console.log('收到消息:', data);
            if (data.type === 'chat-message') {
                // 处理聊天
                // 添加到列表并更新UI
                chatMessage.handleChatMessage(data.message);
                // Host端：按participantId更新对应用户信息
                if (data.participantId && this.role === 'host' && this.state.participants[data.participantId]) {
                    this.state.participants[data.participantId].id = data.message.senderId;
                    if (data.message.senderName) {
                        this.state.participants[data.participantId].name = data.message.senderName;
                    }
                    if (data.message.senderAvatar) {
                        this.state.participants[data.participantId].avatar = data.message.senderAvatar;
                    }
                    this.notify({ type: 'PARTICIPANTS_UPDATE', participants: this.state.participants });
                    this.broadcastParticipantsList();
                }
                // Participant端：根据消息来源更新对应用户信息
                if (!this.role || this.role !== 'host') {
                    if (data.participantId && this.state.participants[data.participantId]) {
                        // 来自其他Participant的消息：更新participants中对应条目
                        if (data.message.senderName) {
                            this.state.participants[data.participantId].name = data.message.senderName;
                        }
                        if (data.message.senderAvatar) {
                            this.state.participants[data.participantId].avatar = data.message.senderAvatar;
                        }
                        this.notify({ type: 'PARTICIPANTS_UPDATE', participants: this.state.participants });
                    } else if (data.message && data.message.senderId !== this.state.session.localUser.id) {
                        // 来自Host的消息：更新remoteUser
                        this.state.session.remoteUser = {
                            ...this.state.session.remoteUser,
                            id: data.message.senderId,
                            name: data.message.senderName,
                            avatar: data.message.senderAvatar
                        };
                        this.notify({ type: 'REMOTE_MEDIA_CHANGE', mediaState: this.state.session.remoteUser.mediaState });
                    }
                }
            } else if (data.type === 'media-state-changed') {
                // 处理媒体状态变化
                console.log('收到媒体状态变化:', data.data, 'from participant:', data.participantId);
                if (this.role === 'host') {
                    // Host端：按participantId同步更新participants中对应participant的mediaState
                    if (data.participantId && this.state.participants[data.participantId]) {
                        this.state.participants[data.participantId].mediaState = {
                            ...this.state.participants[data.participantId].mediaState,
                            ...data.data
                        };
                    }
                    // 更新远端媒体状态
                    this.updateRemoteMedia(data.data, data.participantId);
                    // 通知UI更新participants
                    this.notify({ type: 'PARTICIPANTS_UPDATE', participants: this.state.participants });
                    // Host端广播最新成员列表（含媒体状态）给所有Participant
                    this.broadcastParticipantsList();
                } else {
                    // Participant端：根据消息来源更新对应条目
                    if (data.participantId && this.state.participants[data.participantId]) {
                        // 来自其他Participant的媒体状态变化：仅更新participants中对应条目
                        // 不调用updateRemoteMedia，因为Participant端没有其他Participant的视频流
                        this.state.participants[data.participantId].mediaState = {
                            ...this.state.participants[data.participantId].mediaState,
                            ...data.data
                        };
                        this.notify({ type: 'PARTICIPANTS_UPDATE', participants: this.state.participants });
                    } else if (!data.participantId) {
                        // 来自Host的媒体状态变化（无participantId）：
                        // 更新participants中Host条目 + 更新remoteUser（Host的视频流是本端远端画面）
                        if (this.state.participants['host']) {
                            this.state.participants['host'].mediaState = {
                                ...this.state.participants['host'].mediaState,
                                ...data.data
                            };
                        }
                        this.updateRemoteMedia(data.data, data.participantId);
                        this.notify({ type: 'PARTICIPANTS_UPDATE', participants: this.state.participants });
                    }
                }
            } else if (data.type === 'user-info') {
                // 处理用户信息更新
                console.log('收到用户信息:', data.data, 'from participant:', data.participantId);
                if (data.data) {
                    if (data.participantId && this.role === 'host') {
                        // Host端：按participantId存储到participants Map
                        if (!this.state.participants[data.participantId]) {
                            this.state.participants[data.participantId] = {
                                id: '',
                                name: '参与者',
                                avatar: '/images/p2.png',
                                mediaState: { audio: false, video: true, isSpeaking: false },
                                status: 'online'
                            };
                        }
                        this.state.participants[data.participantId].id = data.data.id || '';
                        this.state.participants[data.participantId].name = data.data.name || '参与者';
                        this.state.participants[data.participantId].avatar = data.data.avatar || '/images/p2.png';
                        this.notify({ type: 'PARTICIPANTS_UPDATE', participants: this.state.participants });
                        this.broadcastParticipantsList();
                    } else {
                        // Participant端：更新单一remoteUser（Host的信息）
                        this.state.session.remoteUser = {
                            ...this.state.session.remoteUser,
                            id: data.data.id || this.state.session.remoteUser.id,
                            name: data.data.name || this.state.session.remoteUser.name,
                            avatar: data.data.avatar || this.state.session.remoteUser.avatar
                        };
                        this.notify({ type: 'REMOTE_MEDIA_CHANGE', mediaState: this.state.session.remoteUser.mediaState });
                    }
                }
            } else if (data.type === 'participants-sync') {
                // Participant端：接收Host广播的完整成员列表
                if (this.role !== 'host' && data.data) {
                    console.log('收到成员列表同步:', data.data);
                    // 过滤掉自身条目，避免在列表中重复显示（自身已作为localUser显示）
                    const filtered = {};
                    for (const [pid, pInfo] of Object.entries(data.data)) {
                        if (pid !== this.selfParticipantId) {
                            filtered[pid] = pInfo;
                        }
                    }
                    this.state.participants = filtered;
                    this.notify({ type: 'PARTICIPANTS_UPDATE', participants: this.state.participants });

                    // 同步通话时长：仅首次同步，将Host的时长作为基准
                    if (!this.durationSynced && typeof data.callDuration === 'number') {
                        this.state.session.duration = data.callDuration;
                        this.durationSynced = true;
                        // 如果计时器尚未启动（远程流还未到达），先启动计时器
                        if (!this.durationInterval) {
                            this.durationInterval = setInterval(() => {
                                this.state.session.duration++;
                                this.notify({ type: 'DURATION_UPDATE', duration: this.state.session.duration });
                            }, 1000);
                        }
                        this.notify({ type: 'DURATION_UPDATE', duration: this.state.session.duration });
                        console.log(`通话时长已同步，当前时长: ${data.callDuration}秒`);
                    }
                }
            }
        };
    }

    /**
     * 启动WebRTC连接和检测
     * @async
     * @param {string} connectionId - 连接ID
     * @returns {Promise<void>}
     */
    async _startConnection(connectionId) {
        // 启动WebRTC连接
        await this.renderstreaming.start();
        await this.renderstreaming.createConnection(connectionId);

        // 启动网络质量检测
        this.startNetworkQualityDetection();

        // 启动本地音频活动检测
        this.startActivityDetection(this.state.localStream, { isLocal: true });
        //启动远端音频活动检测
        this.startActivityDetection(this.state.remoteStream, { isLocal: false });
    }

    /**
 * 挂断WebRTC连接
 * Host挂断：房间删除，通知所有participants
 * Participant挂断：仅自己离开，房间保留
 * @async
 * @returns {Promise<void>}
 */
    async hangUp() {
        this.clearStatsMessage(); // 清除统计信息
        this.stopNetworkQualityDetection(); // 停止网络质量检测
        // 停止通话时长计时器
        if (this.durationInterval) {
            clearInterval(this.durationInterval);
            this.durationInterval = null;
        }
        // 重置通话时长同步标志
        this.durationSynced = false;

        const isHost = this.role === 'host';
        console.log(`Disconnect peer on ${this.connectionId}. Role: ${this.role}`);

        // 删除连接并停止WebRTC
        if (this.renderstreaming) {
            try {
                // 发送断开连接信令给服务器
                // 服务器会根据角色决定：
                // - host断开：通知所有participants，删除房间
                // - participant断开：仅通知host，保留房间
                await this.renderstreaming.deleteConnection();
                await this.renderstreaming.stop();
            } catch (error) {
                console.error('Error during hangUp:', error);
            }
            this.renderstreaming = null;
        }

        // 更新远程用户状态为离线
        this.updateRemoteUserStatus('offline');
        this.updateRemoteUserNetworkQuality('no_signal');
        // 清理participants
        this.state.participants = {};
        this.selfParticipantId = null;
        this.connectionId = null;
        this.role = null;
        this.state.session.status = 'ended';
        this.notify({ type: 'CALL_ENDED', reason: isHost ? 'host_hangup' : 'participant_hangup' });
    }

    /**
     * 发送消息
     * @param {string} type - 消息类型
     * @param {Object} data - 消息数据
     */
    sendMessage(type, data) {
        if (this.renderstreaming) {
            this.renderstreaming.sendMessage({
                type: type,
                data: data
            });
        }
    }

    /**
     * Host端广播完整成员列表给所有Participant
     * 包含Host自身信息 + 所有Participant信息
     * Participant收到后可展示完整通话成员列表
     */
    broadcastParticipantsList() {
        if (this.role !== 'host' || !this.renderstreaming) return;

        const memberList = {};

        // 添加Host自身信息
        memberList['host'] = {
            id: this.state.session.localUser.id,
            name: this.state.session.localUser.name,
            avatar: this.state.session.localUser.avatar,
            mediaState: { ...this.state.session.localUser.mediaState },
            status: 'online',
            role: 'host'
        };

        // 添加所有Participant信息
        for (const [pid, pInfo] of Object.entries(this.state.participants)) {
            memberList[pid] = {
                ...pInfo,
                role: 'participant'
            };
        }

        this.renderstreaming.sendMessage({
            type: 'participants-sync',
            data: memberList,
            callDuration: this.state.session.duration
        });
        console.log('Broadcast participants list:', Object.keys(memberList));
    }

    /**
     * 设置编解码器偏好
     * 优先选择 VP9/AV1（更高效的压缩），回退到 H264 High Profile
     */
    setCodecPreferences(participantId) {
        const capabilities = RTCRtpSender.getCapabilities('video');
        if (!capabilities || !capabilities.codecs || capabilities.codecs.length === 0) return;
        const { codecs } = capabilities;

        // 构建多codec优先级列表（而非只选一个）
        let selectedCodecs = [];

        const av1Codec = codecs.find(c => c.mimeType === 'video/AV1');
        const vp9Codec = codecs.find(c => c.mimeType === 'video/VP9');
        const h264HighCodec = codecs.find(c =>
            c.mimeType === 'video/H264' &&
            c.sdpFmtpLine && c.sdpFmtpLine.includes('profile-level-id=6400')
        );
        const h264Codec = codecs.find(c => c.mimeType === 'video/H264');

        if (av1Codec) selectedCodecs.push(av1Codec);
        if (vp9Codec) selectedCodecs.push(vp9Codec);
        if (h264HighCodec) selectedCodecs.push(h264HighCodec);
        if (h264Codec && (!h264HighCodec || h264Codec !== h264HighCodec)) selectedCodecs.push(h264Codec);

        if (selectedCodecs.length === 0) return;

        if (this.renderstreaming) {
            const transceivers = this.renderstreaming.getTransceivers(participantId);
            if (transceivers && transceivers.length > 0) {
                const videoTransceivers = transceivers.filter(t => {
                    if (t.sender && t.sender.track) {
                        return t.sender.track.kind === 'video';
                    }
                    return t.mid !== null && t.receiver && t.receiver.track && t.receiver.track.kind === 'video';
                });
                if (videoTransceivers && videoTransceivers.length > 0) {
                    videoTransceivers.forEach(t => {
                        try {
                            t.setCodecPreferences(selectedCodecs);
                        } catch(e) {
                            console.error('Error setting codec preferences:', e);
                        }
                    });
                    console.log(`Codec preferences set: ${selectedCodecs.map(c => c.mimeType).join(' > ')}`);
                }
            }
        }
    }

    /**
     * 设置视频发送编码参数
     * 提升 maxBitrate 以改善远端视频画质
     * @param {string} [participantId] - 目标participant（host端使用）
     */
    setVideoEncodingParameters(participantId) {
        if (!this.renderstreaming) return;

        const transceivers = this.renderstreaming.getTransceivers(participantId);
        if (!transceivers || transceivers.length === 0) return;

        const videoTransceivers = transceivers.filter(t =>
            t.sender && t.sender.track && t.sender.track.kind === 'video'
        );

        for (const transceiver of videoTransceivers) {
            try {
                const sender = transceiver.sender;
                const params = sender.getParameters();

                if (!params.encodings || params.encodings.length === 0) {
                    params.encodings = [{}];
                }

                // 根据实际采集分辨率动态设置maxBitrate
                const videoTrack = sender.track;
                const settings = videoTrack ? videoTrack.getSettings() : {};
                const height = settings.height || 1080;

                const bitrateMap = {
                    270: 1000000,
                    480: 1500000,
                    720: 2500000,
                    1080: 4000000,
                    1440: 6000000
                };
                // 找到最接近的分辨率对应的比特率
                let maxBitrate = 4000000;
                const heights = Object.keys(bitrateMap).map(Number).sort((a, b) => a - b);
                for (const h of heights) {
                    if (height <= h) {
                        maxBitrate = bitrateMap[h];
                        break;
                    }
                    maxBitrate = bitrateMap[h];
                }

                params.encodings[0].maxBitrate = maxBitrate;
                params.encodings[0].scaleResolutionDownBy = 1.0;
                params.encodings[0].xGoogleMinBitrate = Math.floor(maxBitrate * 0.5);

                // 优先保持分辨率，降低帧率来适应带宽
                // 'maintain-resolution' 在带宽不足时保持清晰度
                if (params.degradationPreference !== undefined) {
                    params.degradationPreference = 'maintain-resolution';
                }

                sender.setParameters(params);
                console.log(`Set video encoding: maxBitrate=${maxBitrate / 1000000}Mbps, scaleResolutionDownBy=1.0, xGoogleMinBitrate=${Math.floor(maxBitrate * 0.5)}${participantId ? ` for ${participantId}` : ''}`);
            } catch (error) {
                console.error('Error setting video encoding parameters:', error);
            }
        }
    }


    /**
     * 动态切换视频分辨率
     * 使用 MediaStreamTrack.applyConstraints() 在通话中实时调整
     * 同时根据分辨率调整编码比特率
     * @param {number} width - 目标宽度
     * @param {number} height - 目标高度
     */
    async changeResolution(width, height) {
        if (!this.state.localStream) {
            showNotification('本地视频流不可用', 'error');
            return;
        }

        const videoTracks = this.state.localStream.getVideoTracks();
        if (videoTracks.length === 0) {
            showNotification('视频轨道不可用', 'error');
            return;
        }

        const track = videoTracks[0];
        const label = height >= 1440 ? '2K 1440p' : height >= 1080 ? '1080p 超清' : height >= 720 ? '720p 高清' : '480p 流畅';

        try {
            // 使用 applyConstraints 在不重新获取流的情况下调整分辨率
            await track.applyConstraints({
                width: { ideal: width, max: width },
                height: { ideal: height, max: height },
                frameRate: { ideal: 30, max: 30 }
            });

            console.log(`分辨率已切换为 ${width}x${height}`);

            // 根据分辨率调整编码比特率
            // 480p: ~1Mbps, 720p: ~2.5Mbps, 1080p: ~4Mbps, 2K: ~6Mbps
            const bitrateMap = {
                270: 1000000,   // 480p
                720: 2500000,   // 720p
                1080: 4000000,  // 1080p
                1440: 6000000   // 2K
            };
            const maxBitrate = bitrateMap[height] || 2500000;
            this._applyMaxBitrate(maxBitrate);

            // 保存当前分辨率设置到本地存储
            const userSettings = JSON.parse(localStorage.getItem('userSettings') || '{}');
            userSettings.resolution = { width, height };
            localStorage.setItem('userSettings', JSON.stringify(userSettings));

            // 通知 UI 更新
            this.notify({ type: 'RESOLUTION_CHANGED', resolution: { width, height, label } });
            showNotification(`已切换为 ${label}`, 'success');
        } catch (error) {
            console.error('切换分辨率失败:', error);
            showNotification('切换分辨率失败，摄像头不支持该分辨率', 'error');
        }
    }

    /**
     * 对所有视频 sender 应用 maxBitrate
     * @param {number} maxBitrate - 最大比特率（bps）
     */
    _applyMaxBitrate(maxBitrate) {
        if (!this.renderstreaming) return;

        const isHost = this.role === 'host';
        const participantIds = isHost ? Object.keys(this.state.participants) : [null];

        for (const pid of participantIds) {
            const transceivers = this.renderstreaming.getTransceivers(pid);
            if (!transceivers) continue;

            const videoTransceivers = transceivers.filter(t =>
                t.sender && t.sender.track && t.sender.track.kind === 'video'
            );

            for (const transceiver of videoTransceivers) {
                try {
                    const sender = transceiver.sender;
                    const params = sender.getParameters();
                    if (!params.encodings || params.encodings.length === 0) {
                        params.encodings = [{}];
                    }
                    params.encodings[0].maxBitrate = maxBitrate;
                    sender.setParameters(params);
                    console.log(`Updated maxBitrate to ${maxBitrate} for ${pid || 'self'}`);
                } catch (error) {
                    console.error('Error updating maxBitrate:', error);
                }
            }
        }
    }

    // 更新远端媒体状态 (由 WebSocket 触发)
    updateRemoteMedia(mediaState, participantId) {
        this.state.session.remoteUser.mediaState = {
            ...this.state.session.remoteUser.mediaState,
            ...mediaState
        };
        this.notify({ type: 'REMOTE_MEDIA_CHANGE', mediaState, participantId });
        // 通知UI更新用户列表
        this.notify({ type: 'USER_LIST_UPDATE', localUser: this.state.session.localUser, remoteUser: this.state.session.remoteUser });
    }

    // 更新远端用户状态
    updateRemoteUserStatus(status) {
        this.state.session.remoteUser.status = status;
        this.notify({ type: 'REMOTE_MEDIA_CHANGE', localUser: this.state.session.localUser, remoteUser: this.state.session.remoteUser });
    }
    updateRemoteUserNetworkQuality(networkQuality) {
        this.state.session.remoteUser.networkQuality = networkQuality;
        this.notify({ type: 'REMOTE_MEDIA_CHANGE', localUser: this.state.session.localUser, remoteUser: this.state.session.remoteUser });
    }
    // 结束通话（用户主动点击挂断按钮）
    async endCall() {
        console.log(`endCall called. Role: ${this.role}`);
        // 调用 hangUp() 正确关闭 WebRTC 连接并发送断开信令
        // hangUp 内部会根据角色区分：
        // - host: 通知所有participants，删除房间
        // - participant: 仅自己离开，房间保留
        await this.hangUp();
    }

    // 加入通话
    async joinCall(connectionId) {
        this.state.session.status = 'connecting';
        this.notify({ type: 'CALL_STATUS_CHANGE', status: 'connecting' });
        showNotification(`正在加入通话 (${connectionId})`);

        // 初始化
        await this.init();

        // 保存连接ID
        this.connectionId = connectionId;
    }

    // 创建通话
    async createCall() {
        this.state.session.status = 'connecting';
        this.notify({ type: 'CALL_STATUS_CHANGE', status: 'connecting' });
        showNotification('正在创建通话...');

        // 初始化
        await this.init();
    }

    // 真实网络质量检测
    async detectNetworkQuality() {
        if (!this.renderstreaming) {
            return;
        }

        try {
            const stats = await this.renderstreaming.getStats();
            if (!stats) {
                return;
            }

            let totalPacketsLost = 0;
            let totalPacketsReceived = 0;
            let inboundRTPCount = 0;
            let jitter = 0;
            let roundTripTime = 0;

            // 分析统计信息
            stats.forEach(report => {
                if (report.type === 'inbound-rtp' && report.mediaType === 'video') {
                    inboundRTPCount++;

                    // 计算丢包率
                    if (report.packetsLost !== undefined && report.packetsReceived !== undefined) {
                        totalPacketsLost += report.packetsLost;
                        totalPacketsReceived += report.packetsReceived;
                    }

                    // 获取抖动
                    if (report.jitter !== undefined) {
                        jitter = Math.max(jitter, report.jitter);
                    }

                    // 获取往返时间
                    if (report.roundTripTime !== undefined) {
                        roundTripTime = Math.max(roundTripTime, report.roundTripTime);
                    }
                }
            });

            // 计算网络质量指标
            let quality = 'excellent';

            if (inboundRTPCount > 0) {
                // 基于丢包率判断
                const packetLossRate = totalPacketsReceived > 0 ? (totalPacketsLost / (totalPacketsLost + totalPacketsReceived)) : 0;

                // 基于抖动判断
                const jitterMs = jitter * 1000;

                // 基于往返时间判断
                const rttMs = roundTripTime * 1000;

                // 综合评估网络质量
                if (packetLossRate > 0.05 || jitterMs > 100 || rttMs > 300) {
                    quality = 'poor';
                } else if (packetLossRate > 0.02 || jitterMs > 50 || rttMs > 150) {
                    quality = 'fair';
                } else if (packetLossRate > 0.01 || jitterMs > 30 || rttMs > 100) {
                    quality = 'good';
                } else {
                    quality = 'excellent';
                }
            } else {
                // 没有收到任何RTP包，设置为无信号状态
                quality = 'no_signal';
            }

            // 更新网络质量状态
            if (this.state.session.remoteUser.networkQuality !== quality) {
                this.state.session.remoteUser.networkQuality = quality;
                this.notify({ type: 'NETWORK_CHANGE', quality });
            }

        } catch (error) {
            console.error('Error detecting network quality:', error);
        }
    }
    // 音频活动检测
    startActivityDetection(stream, { isLocal = false } = {}) {
        if (!stream) {
            return;
        }

        const audioTracks = stream.getAudioTracks();
        if (audioTracks.length === 0) {
            return;
        }

        try {
            const { threshold, debounceTime, fftSize } = VAD_CONFIG;

            const audioContext = new (window.AudioContext || window.webkitAudioContext)();
            const source = audioContext.createMediaStreamSource(stream);
            const analyser = audioContext.createAnalyser();
            analyser.fftSize = fftSize;

            source.connect(analyser);

            const dataArray = new Uint8Array(analyser.frequencyBinCount);
            let isSpeaking = false;
            let lastActivityTime = 0;

            const detectActivity = () => {
                if (!stream || !this.renderstreaming) {
                    return;
                }

                analyser.getByteTimeDomainData(dataArray);

                let sum = 0;
                for (let i = 0; i < dataArray.length; i++) {
                    const amplitude = dataArray[i] - 128;
                    sum += amplitude * amplitude;
                }
                const rms = Math.sqrt(sum / dataArray.length);
                const level = rms / 128;

                const currentTime = Date.now();
                if (level > threshold / 100) {
                    lastActivityTime = currentTime;
                    if (!isSpeaking) {
                        isSpeaking = true;
                        if (isLocal) {
                            this.state.session.localUser.mediaState.isSpeaking = true;
                            this.notify({ type: 'LOCAL_MEDIA_CHANGE', mediaType: 'isSpeaking', value: true });
                            this.emitMediaStateChange();
                        } else {
                            this.updateRemoteMedia({ isSpeaking: true });
                        }
                    }
                } else if (isSpeaking && currentTime - lastActivityTime > debounceTime) {
                    isSpeaking = false;
                    if (isLocal) {
                        this.state.session.localUser.mediaState.isSpeaking = false;
                        this.notify({ type: 'LOCAL_MEDIA_CHANGE', mediaType: 'isSpeaking', value: false });
                        this.emitMediaStateChange();
                    } else {
                        this.updateRemoteMedia({ isSpeaking: false });
                    }
                }

                if (this.state.session.status === 'ongoing') {
                    requestAnimationFrame(detectActivity);
                }
            };

            detectActivity();

            console.log(`${isLocal ? 'Local' : 'Remote'} activity detection started`);

        } catch (error) {
            console.error(`Error starting ${isLocal ? 'local' : 'remote'} activity detection:`, error);
        }
    }
    // 启动网络质量检测
    startNetworkQualityDetection() {
        // 每3秒检测一次网络质量
        this.networkQualityInterval = setInterval(() => {
            this.detectNetworkQuality();
        }, 3000);
    }

    // 停止网络质量检测
    stopNetworkQualityDetection() {
        if (this.networkQualityInterval) {
            clearInterval(this.networkQualityInterval);
            this.networkQualityInterval = null;
        }
    }



    // 发送媒体状态到服务器
    emitMediaStateChange() {
        const payload = {
            userId: this.state.session.localUser.id,
            ...this.state.session.localUser.mediaState
        };
        console.log('[WebSocket Emit] media-state-changed:', payload);
        // 使用WebRTC发送媒体状态变化
        if (this.renderstreaming) {
            this.renderstreaming.sendMessage({
                type: 'media-state-changed',
                data: payload
            });
        }
    }

    // 显示统计信息
    async showStatsMessage() {
        console.log('Showing stats message');

        // 立即执行一次网络质量检测
        await this.detectNetworkQuality();

        // 定期显示详细统计信息
        this.statsInterval = setInterval(async () => {
            if (!this.renderstreaming) {
                return;
            }

            try {
                const stats = await this.renderstreaming.getStats();
                if (!stats) {
                    return;
                }

                let statsSummary = {
                    video: {
                        packetsLost: 0,
                        packetsReceived: 0,
                        bytesReceived: 0,
                        jitter: 0,
                        roundTripTime: 0,
                        fps: 0,
                        bitrate: 0
                    },
                    audio: {
                        packetsLost: 0,
                        packetsReceived: 0,
                        bytesReceived: 0,
                        jitter: 0
                    }
                };

                // 分析统计信息
                stats.forEach(report => {
                    if (report.type === 'inbound-rtp') {
                        if (report.mediaType === 'video') {
                            statsSummary.video.packetsLost = report.packetsLost || 0;
                            statsSummary.video.packetsReceived = report.packetsReceived || 0;
                            statsSummary.video.bytesReceived = report.bytesReceived || 0;
                            statsSummary.video.jitter = report.jitter || 0;
                            statsSummary.video.roundTripTime = report.roundTripTime || 0;
                            statsSummary.video.fps = report.framesPerSecond || 0;

                            // 计算视频比特率 (kbps)
                            if (report.bytesReceived && report.timestamp) {
                                const duration = report.timestamp / 1000; // 转换为秒
                                statsSummary.video.bitrate = duration > 0 ? Math.round((report.bytesReceived * 8) / (duration * 1000)) : 0;
                            }
                        } else if (report.mediaType === 'audio') {
                            statsSummary.audio.packetsLost = report.packetsLost || 0;
                            statsSummary.audio.packetsReceived = report.packetsReceived || 0;
                            statsSummary.audio.bytesReceived = report.bytesReceived || 0;
                            statsSummary.audio.jitter = report.jitter || 0;
                        }
                    }
                });

                // 输出详细统计信息
                console.log('=== WebRTC Statistics ===');
                console.log(`Network Quality: ${this.state.session.remoteUser.networkQuality}`);
                console.log('Video Stats:', {
                    'Packets Lost': statsSummary.video.packetsLost,
                    'Packets Received': statsSummary.video.packetsReceived,
                    'Packet Loss Rate': statsSummary.video.packetsReceived > 0 ?
                        `${((statsSummary.video.packetsLost / (statsSummary.video.packetsLost + statsSummary.video.packetsReceived)) * 100).toFixed(2)}%` : '0%',
                    'Jitter': `${(statsSummary.video.jitter * 1000).toFixed(2)}ms`,
                    'Round Trip Time': `${(statsSummary.video.roundTripTime * 1000).toFixed(2)}ms`,
                    'FPS': statsSummary.video.fps.toFixed(1),
                    'Bitrate': `${statsSummary.video.bitrate}kbps`
                });
                console.log('Audio Stats:', {
                    'Packets Lost': statsSummary.audio.packetsLost,
                    'Packets Received': statsSummary.audio.packetsReceived,
                    'Packet Loss Rate': statsSummary.audio.packetsReceived > 0 ?
                        `${((statsSummary.audio.packetsLost / (statsSummary.audio.packetsLost + statsSummary.audio.packetsReceived)) * 100).toFixed(2)}%` : '0%',
                    'Jitter': `${(statsSummary.audio.jitter * 1000).toFixed(2)}ms`
                });
                console.log('========================');

            } catch (error) {
                console.error('Error showing stats message:', error);
            }
        }, 5000); // 每5秒更新一次统计信息
    }

    // 清除统计信息
    clearStatsMessage() {
        console.log('Clearing stats message');

        // 清理统计信息定时器
        if (this.statsInterval) {
            clearInterval(this.statsInterval);
            this.statsInterval = null;
        }
    }

    // Getters
    getState() { return this.state; }
    getLocalUser() { return this.state.session.localUser; }
    getRemoteUser() { return this.state.session.remoteUser; }

    getConnectionId() { return this.connectionId; }

    getRenderStreaming() { return this.renderstreaming; }
}

// 创建单例实例
const store = new CallStateManager();

// 页面卸载前清理
window.addEventListener('beforeunload', async () => {
    if (!store.renderstreaming)
        return;
    await store.renderstreaming.stop(); // 停止WebRTC连接
}, true);
export default store;
