/**
 * UI渲染器
 * 负责将状态映射到DOM，与状态管理解耦
 */
import { formatTime, formatTimestamp, toggleElement, toggleButtonState } from './utils.js';
import { mockCallSession } from './models.js';
import chatMessage from './chatmessage.js';
import store from './store.js';

const GRID_LAYOUT = {
    maxColumns: 3,
    breakpoints: [
        { maxParticipants: 1, template: '1fr' },
        { maxParticipants: 4, template: 'repeat(2, 1fr)' }
    ],
    defaultTemplate: 'repeat(3, 1fr)'
};

function getGridTemplateColumns(participantCount) {
    for (const bp of GRID_LAYOUT.breakpoints) {
        if (participantCount <= bp.maxParticipants) {
            return bp.template;
        }
    }
    return GRID_LAYOUT.defaultTemplate;
}

class UIRenderer {
    constructor(stateManager) {
        this.stateManager = stateManager;
        this.unsubscribe = stateManager.subscribe(this.render.bind(this));

        // 缓存 DOM 元素
        this.elements = {
            // 头部和底部
            header: document.querySelector('header'),
            footer: document.querySelector('footer'),
            // 多Participant视频网格
            participantGrid: document.getElementById('participantGrid'),
            // 头部内容
            headerTitle: document.getElementById('headerTitle'),
            callDuration: document.getElementById('callDuration'),
            encryptionBadge: document.getElementById('encryptionBadge'),
            unreadBadge: document.getElementById('unreadBadge'),
            remoteNetworkIndicator: document.getElementById('remoteNetworkIndicator'),
            remoteNetworkQuality: document.getElementById('remoteNetworkQuality'),

            // 远端视频
            remoteVideo: document.getElementById('remoteVideo'),
            remoteVideoPlaceholder: document.getElementById('remoteVideoPlaceholder'),
            networkStatus: document.getElementById('networkStatus'),
            networkStatusText: document.getElementById('networkStatusText'),
            connectingOverlay: document.getElementById('connectingOverlay'),

            // 本地视频
            localVideo: document.getElementById('localVideo'),
            localVideoPlaceholder: document.getElementById('localVideoPlaceholder'),
            localAudioWave: document.getElementById('localAudioWave'),
            localInitials: document.getElementById('localInitials'),

            // 侧边栏
            sidebar: document.getElementById('sidebar'),
            chatContent: document.getElementById('chatContent'),
            userList: document.getElementById('userList'),
            localMediaStatus: document.getElementById('localMediaStatus'),
            localMuteIcon: document.querySelector('[data-field="localUser.muteIcon"]'),
            userCountDisplay: document.getElementById('userCountDisplay'),
            // 控制按钮
            micBtn: document.getElementById('micBtn'),
            videoBtn: document.getElementById('videoBtn'),
            recordBtn: document.getElementById('recordBtn'),
            connectionQuality: document.getElementById('connectionQuality')
        };

        // 绑定事件监听器
        this.bindEventListeners();

        // 订阅状态变化
        this.unsubscribe = stateManager.subscribe(this.render.bind(this));
        // 订阅消息状态变化
        this.messageUnsubscribe = chatMessage.subscribe(this.renderMessageState.bind(this));
        // 初始化渲染
        this.render(this.stateManager.getState(), { type: 'INIT' });

        window.addEventListener('resize', () => {
            if (this.elements.remoteVideo && this.elements.remoteVideo.srcObject) {
                const stream = this.elements.remoteVideo.srcObject;
                const videoTracks = stream.getVideoTracks();
                if (videoTracks.length > 0) {
                    const resolution = this.getVideoResolution(videoTracks[0]);
                    this.adjustVideoSize(this.elements.remoteVideo, resolution);
                }
            }
        });
    }

    // 渲染消息状态变化
    renderMessageState(messageState, changes) {
        switch (changes.type) {
            case 'NEW_MESSAGE':
                this.renderChatMessages(messageState.messages);
                this.renderUnreadCount(changes.unreadCount);
                break;
            case 'SIDEBAR_TOGGLE':
                this.renderSidebar(changes.isOpen);
                // 当侧边栏打开时，重置未读消息计数
                if (changes.isOpen) {
                    this.renderUnreadCount(0);
                } else {
                    this.renderUnreadCount(changes.unreadCount);
                }
                break;
        }
    }

    // 绑定事件监听器
    bindEventListeners() {
        // 事件监听器
    }


    /**
     * 渲染方法 - 根据状态变化更新UI
     * @param {Object} state - 当前应用状态
     * @param {Object} changes - 状态变化对象
     */
    render(state, changes) {
        // 根据变化类型执行不同的渲染操作
        switch (changes.type) {
            case 'INIT':
                // 初始化渲染 - 渲染所有UI元素
                this.renderRemoteVideo(state.session.remoteUser); // 渲染远程视频
                this.renderLocalVideo(state.session.localUser, state.localStream); // 渲染本地视频
                this.renderControlButtons(state.session.localUser.mediaState); // 渲染控制按钮
                this.renderChatMessages(chatMessage.getMessageState().messages); // 渲染聊天消息
                this.renderUserList(state.session.localUser, state.session.remoteUser, state.participants); // 渲染用户列表
                this.renderHeader(state.session);               // 渲染头部信息
                // 初始化时检查远程流状态，显示或隐藏占位背景
                if (this.elements.remoteVideoPlaceholder) {
                    if (state.remoteStream) {
                        this.elements.remoteVideoPlaceholder.classList.add('hidden'); // 有远程流时隐藏占位背景
                    } else {
                        this.elements.remoteVideoPlaceholder.classList.remove('hidden'); // 无远程流时显示占位背景
                    }
                }
                break;
            case 'DURATION_UPDATE':
                // 通话时长更新 - 渲染通话时长
                this.renderCallDuration(changes.duration);
                break;
            case 'LOCAL_MEDIA_CHANGE':
                // 本地媒体状态变化 - 更新相关UI
                this.renderControlButtons(state.session.localUser.mediaState); // 渲染控制按钮
                this.renderLocalVideo(state.session.localUser, state.localStream); // 渲染本地视频
                this.renderLocalUserStatus(state.session.localUser); // 渲染本地用户状态
                this.renderUserList(state.session.localUser, state.session.remoteUser, state.participants); // 渲染用户列表
                break;
            case 'LOCAL_STREAM_OBTAINED':
                this.renderLocalStream(state.localStream);
                this.renderLocalVideo(state.session.localUser, state.localStream);
                break;
            case 'REMOTE_STREAM_OBTAINED':
                // 远程流获取成功 - 更新远程视频显示
                this.renderRemoteStream(changes.stream, changes.connectionId, changes.isHost); // 渲染远程流
                // 当获取到远程流时，隐藏连接中提示
                if (this.elements.connectingOverlay) {
                    this.elements.connectingOverlay.classList.add('hidden');
                }
                break;
            case 'REMOTE_MEDIA_CHANGE':
                // 远程媒体状态变化 - 更新远程视频和用户列表
                this.renderRemoteVideo(state.session.remoteUser); // 渲染远程视频
                this.renderUserList(state.session.localUser, state.session.remoteUser, state.participants); // 渲染用户列表
                // Host端：精准更新发送者participant tile的占位背景
                // 只有Host端需要处理participantId对应的tile占位符（Participant端没有其他Participant的视频流）
                if (changes.participantId && state.session.localUser.isHost) {
                    // 从participants Map中读取该participant的video状态，而非remoteUser（多Participant场景remoteUser不精确）
                    const pInfo = state.participants[changes.participantId];
                    const showPlaceholder = pInfo ? !pInfo.mediaState.video : true;
                    this.renderParticipantVideoPlaceholder(changes.participantId, showPlaceholder);
                }
                break;
            case 'USER_LIST_UPDATE':
                // 用户列表更新 - 重新渲染用户列表
                this.renderUserList(changes.localUser, changes.remoteUser, state.participants);
                break;
            case 'PARTICIPANTS_UPDATE':
                // Participants信息变化 - 重新渲染用户列表并同步tile名称
                this.renderUserList(state.session.localUser, state.session.remoteUser, changes.participants || state.participants);
                // 同步更新participant tile的名称标签
                this.syncParticipantTileNames(changes.participants || state.participants);
                break;
            case 'NETWORK_CHANGE':
                // 网络状态变化 - 渲染网络状态
                this.renderNetworkStatus(changes.quality);
                break;
            case 'CALL_STATUS_CHANGE':
                // 通话状态变化 - 渲染通话状态
                this.renderCallStatus(changes.status);
                break;
            case 'CALL_ENDED':
                // 通话结束 - 渲染通话结束界面
                this.renderCallEnded();
                break;
            case 'PARTICIPANT_LEFT':
                // participant离开 - 更新UI但房间仍然存在
                this.renderParticipantLeft(changes.connectionId);
                break;
            case 'RESOLUTION_CHANGED':
                // 分辨率变化 - 更新UI中的分辨率选中状态
                this.renderResolutionChanged(changes.resolution);
                break;
        }
    }

    // 渲染通话状态
    renderCallStatus(status) {
        if (this.elements.connectingOverlay) {
            if (status === 'connecting') {
                this.elements.connectingOverlay.classList.remove('hidden');
            } else {
                this.elements.connectingOverlay.classList.add('hidden');
            }
        }
    }

    // 渲染头部
    renderHeader(session) {

        this.renderHeaderTitle();
        if (this.elements.encryptionBadge) {
            toggleElement(this.elements.encryptionBadge, session.isEncrypted);
        }

        // 始终显示网络状态指示器和质量
        if (this.elements.remoteNetworkIndicator) {
            this.elements.remoteNetworkIndicator.classList.remove('hidden');
        }
        if (this.elements.remoteNetworkQuality) {
            this.elements.remoteNetworkQuality.classList.remove('hidden');
        }

        this.renderCallDuration(session.duration);
    }
    renderHeaderTitle() {
        if (this.elements.headerTitle) {
            const connectionId = store.getConnectionId() || '';
            // 未连接时不显示红框部分
            this.elements.headerTitle.textContent = `通话 (${connectionId})`;

        }
    }

    // 渲染通话时长
    renderCallDuration(duration) {
        if (this.elements.callDuration) {
            this.elements.callDuration.textContent = formatTime(duration);
        }
    }

    // 渲染分辨率变化
    renderResolutionChanged(resolution) {
        if (!resolution) return;

        // 更新分辨率选项的选中状态
        const options = document.querySelectorAll('.resolution-option');
        options.forEach(btn => {
            const btnRes = btn.dataset.resolution;
            const isActive = (resolution.height >= 1440 && btnRes === '1440') ||
                             (resolution.height >= 1080 && resolution.height < 1440 && btnRes === '1080') ||
                             (resolution.height >= 720 && resolution.height < 1080 && btnRes === '720') ||
                             (resolution.height < 720 && btnRes === '480');
            btn.classList.toggle('active', isActive);
        });

        // 更新当前分辨率文本
        const currentResText = document.getElementById('currentResolutionText');
        if (currentResText) {
            currentResText.textContent = `当前: ${resolution.label}`;
        }
    }

    // 渲染远端视频
    renderRemoteVideo(remoteUser) {
        // 同步更新侧边栏用户列表
        this.renderUserList(this.stateManager.getState().session.localUser, remoteUser, this.stateManager.getState().participants);

        // 当远程视频关闭时显示占位符
        if (this.elements.remoteVideoPlaceholder) {
            const shouldShowPlaceholder = !remoteUser.mediaState.video;
            toggleElement(this.elements.remoteVideoPlaceholder, shouldShowPlaceholder);

            // 当远程视频关闭时，隐藏视频元素本身，避免冻结画面透过占位符
            if (this.elements.remoteVideo) {
                if (shouldShowPlaceholder) {
                    this.elements.remoteVideo.style.opacity = '0';
                } else {
                    this.elements.remoteVideo.style.opacity = '1';
                }
            }

            // 更新占位符文本内容
            if (shouldShowPlaceholder) {
                const placeholderContent = this.elements.remoteVideoPlaceholder.querySelector('.text-center');
                if (placeholderContent) {
                    const titleElement = placeholderContent.querySelector('p.text-white.text-lg.font-medium');
                    if (titleElement) {
                        titleElement.textContent = '对方摄像头已关闭';
                    }
                    const subtitleElement = placeholderContent.querySelector('p.text-sm.text-gray-400');
                    if (subtitleElement) {
                        subtitleElement.textContent = '对方暂时关闭了视频';
                    }
                }
            } else {
                // 恢复默认占位符文本
                const placeholderContent = this.elements.remoteVideoPlaceholder.querySelector('.text-center');
                if (placeholderContent) {
                    const titleElement = placeholderContent.querySelector('p.text-white.text-lg.font-medium');
                    if (titleElement) {
                        titleElement.textContent = '等待对方连接...';
                    }
                    const subtitleElement = placeholderContent.querySelector('p.text-sm.text-gray-400');
                    if (subtitleElement) {
                        subtitleElement.textContent = '请确保对方已加入通话';
                    }
                }
            }
        }

        // 渲染网络状态
        this.renderNetworkStatus(remoteUser.networkQuality);

        // 渲染header中的网络状态
        this.renderHeaderNetworkStatus(remoteUser.networkQuality);
    }

    // 渲染header中的网络状态
    renderHeaderNetworkStatus(networkQuality) {
        if (this.elements.remoteNetworkQuality) {
            const textElement = this.elements.remoteNetworkQuality.querySelector('span');
            const iconElement = this.elements.remoteNetworkQuality.querySelector('i');

            if (textElement && iconElement) {
                let qualityText = '未知';
                let iconClass = 'fas fa-signal text-gray-400';

                switch (networkQuality) {
                    case 'excellent':
                        qualityText = '优秀';
                        iconClass = 'fas fa-signal text-green-400';
                        break;
                    case 'good':
                        qualityText = '良好';
                        iconClass = 'fas fa-signal text-green-500';
                        break;
                    case 'fair':
                        qualityText = '一般';
                        iconClass = 'fas fa-signal text-yellow-400';
                        break;
                    case 'poor':
                        qualityText = '较差';
                        iconClass = 'fas fa-signal text-red-400';
                        break;
                }

                textElement.textContent = qualityText;
                iconElement.className = iconClass;
            }
        }
    }

    // 渲染本地视频
    renderLocalVideo(localUser, localStream) {
        if (this.elements.localVideoPlaceholder) {
            // 当没有视频流或视频关闭时显示占位符
            const shouldShowPlaceholder = !localStream || !localUser.mediaState.video;
            toggleElement(this.elements.localVideoPlaceholder, shouldShowPlaceholder);
        }

        if (this.elements.localAudioWave) {
            toggleElement(this.elements.localAudioWave, localUser.mediaState.isSpeaking);
        }

        // 同时渲染本地用户状态
        this.renderLocalUserStatus(localUser);
    }

    // 渲染本地视频流
    renderLocalStream(stream) {
        if (this.elements.localVideo && stream) {
            this.elements.localVideo.srcObject = stream;
            this.elements.localVideo.autoplay = true;
            this.elements.localVideo.muted = true; // 本地视频静音，避免回声
            console.log('srcObject set successfully:', this.elements.localVideo.srcObject);

            // 隐藏断开连接覆盖层
            if (this.elements.disconnectedOverlay) {
                this.elements.disconnectedOverlay.classList.add('hidden');
            }
        } else {
            console.error('Either localVideo element or stream is missing');
        }
    }

    // 渲染远程视频流
    renderRemoteStream(stream, connectionId, isHost) {
        if (isHost && connectionId) {
            // Host端: 渲染到 participant 视频网格
            this.renderParticipantStream(stream, connectionId);
        } else {
            // Participant端: 渲染到单一远端视频（Host的画面）
            this.renderSingleRemoteStream(stream);
        }
    }

    // 渲染Host端的多Participant视频网格
    // 每个participant tile显示该participant实际的远端视频流
    renderParticipantStream(stream, connectionId) {
        const grid = this.elements.participantGrid;
        if (!grid) return;

        // 显示网格，隐藏单路远端视频
        grid.classList.remove('hidden');

        // 查找或创建该 connectionId 的视频格子
        let tile = grid.querySelector(`[data-participant-id="${connectionId}"]`);
        if (!tile) {
            tile = document.createElement('div');
            tile.className = 'relative bg-black/60 rounded-xl overflow-hidden flex items-center justify-center';
            tile.dataset.participantId = connectionId;

            const video = document.createElement('video');
            video.className = 'w-full h-full object-contain';
            video.autoplay = true;
            video.playsinline = true;
            video.muted = false; // 不静音，播放participant的音频
            video.id = `participantVideo_${connectionId}`;
            tile.appendChild(video);

            // 参与者视频关闭时的占位背景（复用 remoteVideoPlaceholder 样式）
            const placeholder = document.createElement('div');
            placeholder.className = 'participant-video-placeholder absolute inset-0 flex items-center justify-center bg-gradient-to-br from-indigo-900/80 to-purple-900/80 hidden';
            placeholder.innerHTML = `
                <div class="text-center">
                    <div class="w-20 h-20 rounded-full bg-indigo-700/50 flex items-center justify-center mx-auto mb-3">
                        <i class="fas fa-video-slash text-2xl text-white/70"></i>
                    </div>
                    <p class="text-white text-sm font-medium">摄像头已关闭</p>
                </div>
            `;
            tile.appendChild(placeholder);

            // 参与者名称标签（优先使用participants中的真实姓名）
            const pInfo = this.stateManager.getState().participants[connectionId];
            const displayName = pInfo?.name || '参与者';
            const label = document.createElement('div');
            label.className = 'absolute bottom-3 left-3 glass px-3 py-1 rounded-full text-xs flex items-center gap-2';
            label.innerHTML = `<i class="fas fa-user text-purple-400"></i><span>${displayName}</span>`;
            tile.appendChild(label);

            // 在线标识
            const liveTag = document.createElement('div');
            liveTag.className = 'absolute top-3 right-3 bg-green-500/80 px-2 py-0.5 rounded-full text-xs flex items-center gap-1';
            liveTag.innerHTML = `<span class="w-1.5 h-1.5 bg-white rounded-full animate-pulse"></span><span>在线</span>`;
            tile.appendChild(liveTag);

            grid.appendChild(tile);
            console.log(`Created participant video tile for ${connectionId}`);
        }

        if (tile) {
            // 视频元素显示participant的远端视频流
            const video = tile.querySelector('video');
            if (video && stream) {
                // 避免重复设置同一流对象（音频先到、视频后到时流对象相同）
                if (video.srcObject === stream) {
                    console.log(`Same stream for participant ${connectionId}, ensuring playback`);
                    video.play().catch(e => console.log('Auto-play prevented:', e.message));
                } else {
                    video.srcObject = stream;
                    video.play().catch(e => console.log('Auto-play prevented:', e.message));
                    console.log(`Set remote stream for participant tile ${connectionId}`);
                }
            }

            // 隐藏单路远端视频和占位符
            const remoteVideoDiv = this.elements.remoteVideo?.closest('.absolute.inset-0.video-fade-in');
            if (remoteVideoDiv) {
                remoteVideoDiv.classList.add('hidden');
            }
        }

        // 根据参与者数量调整网格列数
        const tileCount = grid.querySelectorAll('[data-participant-id]').length;
        grid.style.gridTemplateColumns = getGridTemplateColumns(tileCount);

        // 隐藏连接中提示
        if (this.elements.connectingOverlay) {
            this.elements.connectingOverlay.classList.add('hidden');
        }

        // 隐藏远端视频占位符
        if (this.elements.remoteVideoPlaceholder) {
            this.elements.remoteVideoPlaceholder.classList.add('hidden');
        }
    }

    // 精准更新指定participant tile的占位背景
    // participantId: 发送media-state-changed的participant的连接ID
    // showPlaceholder: 是否显示占位背景（视频关闭时为true）
    renderParticipantVideoPlaceholder(participantId, showPlaceholder) {
        const grid = this.elements.participantGrid;
        if (!grid) return;
        const tile = grid.querySelector(`[data-participant-id="${participantId}"]`);
        if (!tile) return;
        const placeholder = tile.querySelector('.participant-video-placeholder');
        if (placeholder) {
            toggleElement(placeholder, showPlaceholder);
            console.log(`Updated placeholder for participant ${participantId}: ${showPlaceholder ? 'shown' : 'hidden'}`);
        }
    }

    // 同步更新所有participant tile的名称标签
    syncParticipantTileNames(participants) {
        if (!participants) return;
        const grid = this.elements.participantGrid;
        if (!grid) return;
        for (const [participantId, pInfo] of Object.entries(participants)) {
            this.updateParticipantTileName(participantId, pInfo.name);
        }
    }

    // 更新指定participant tile的名称标签
    updateParticipantTileName(participantId, name) {
        const grid = this.elements.participantGrid;
        if (!grid) return;
        const tile = grid.querySelector(`[data-participant-id="${participantId}"]`);
        if (!tile) return;
        const label = tile.querySelector('.absolute.bottom-3');
        if (label) {
            const nameSpan = label.querySelector('span');
            if (nameSpan && name) {
                nameSpan.textContent = name;
                console.log(`Updated tile name for participant ${participantId}: ${name}`);
            }
        }
    }

    // 渲染Participant端的单一远端视频（Host画面）
    renderSingleRemoteStream(stream) {
        if (!this.elements.remoteVideo || !stream) {
            console.error('Either remoteVideo element or stream is missing');
            return;
        }

        console.log('Rendering remote stream:', stream, 'tracks:', stream.getTracks().map(t => `${t.kind}(${t.readyState})`));

        // 关键修复：避免 srcObject = null 的重置模式
        // 如果 srcObject 已经是同一个 stream 对象，说明是同一流的轨道更新（如音频先到，视频后到）
        // 浏览器会自动识别新添加的轨道，无需重置 srcObject
        if (this.elements.remoteVideo.srcObject === stream) {
            console.log('Same stream object, track added - ensuring playback');
            this.elements.remoteVideo.play().catch(e => console.log('Auto-play prevented:', e.message));
            return;
        }

        // 首次设置或流对象变化：直接设置 srcObject（不使用 null 重置模式）
        this.elements.remoteVideo.srcObject = stream;
        this.elements.remoteVideo.autoplay = true;
        this.elements.remoteVideo.playsinline = true;
        this.elements.remoteVideo.muted = false;

        // 确保视频开始播放
        this.elements.remoteVideo.play().catch(e => {
            console.log('Auto-play prevented, will retry on interaction:', e.message);
        });

        // 隐藏断开连接覆盖层
        if (this.elements.disconnectedOverlay) {
            this.elements.disconnectedOverlay.classList.add('hidden');
        }

        // 监听视频轨道变化
        const videoTracks = stream.getVideoTracks();
        const audioTracks = stream.getAudioTracks();
        console.log(`Stream has ${videoTracks.length} video tracks, ${audioTracks.length} audio tracks`);

        if (videoTracks.length > 0) {
            // 有视频轨道：隐藏占位符
            if (this.elements.remoteVideoPlaceholder) {
                this.elements.remoteVideoPlaceholder.classList.add('hidden');
            }
            if (this.elements.connectingOverlay) {
                this.elements.connectingOverlay.classList.add('hidden');
            }

            // 监听视频轨道分辨率变化
            const activeVideoTrack = videoTracks.find(track => track.readyState === 'live');
            if (activeVideoTrack) {
                const resolution = this.getVideoResolution(activeVideoTrack);
                this.adjustVideoSize(this.elements.remoteVideo, resolution);
                activeVideoTrack.addEventListener('resize', () => {
                    const newResolution = this.getVideoResolution(activeVideoTrack);
                    this.adjustVideoSize(this.elements.remoteVideo, newResolution);
                });
            }
        } else {
            // 只有音频轨道（视频轨道尚未到达）：不显示占位符，等待视频轨道到达
            // 不设置 srcObject = null，保持音频播放
            console.log('Audio-only stream, waiting for video track...');
        }
    }

    // 渲染本地用户状态
    renderLocalUserStatus(localUser) {
        // 更新本地媒体状态文本
        if (this.elements.localMediaStatus) {
            if (!localUser.mediaState.audio) {
                this.elements.localMediaStatus.textContent = '静音中';
                this.elements.localMediaStatus.className = 'text-xs text-gray-500';
            } else if (!localUser.mediaState.video) {
                this.elements.localMediaStatus.textContent = '视频关闭';
                this.elements.localMediaStatus.className = 'text-xs text-gray-500';
            } else {
                this.elements.localMediaStatus.textContent = '在线';
                this.elements.localMediaStatus.className = 'text-xs text-green-400';
            }
        }

        // 更新静音图标
        if (this.elements.localMuteIcon) {
            if (!localUser.mediaState.audio) {
                this.elements.localMuteIcon.classList.remove('hidden');
                this.elements.localMuteIcon.className = 'fas fa-microphone-slash text-gray-500 text-xs';
            } else {
                this.elements.localMuteIcon.classList.add('hidden');
            }
        }
    }

    // 渲染侧边栏用户列表（支持多Participant动态渲染）
    renderUserList(localUser, remoteUser, participants) {
        if (!this.elements.userList) return;

        const participantsMap = participants || {};
        const participantCount = Object.keys(participantsMap).length;

        // 通话成员总数 = 本地用户(1) + participants中的条目数
        // Host端participants只含其他participant；Participant端participants含host+其他participant
        const userCount = 1 + participantCount;

        // 更新通话成员总数显示
        const userCountElement = this.elements.userCountDisplay;
        if (userCountElement) {
            userCountElement.textContent = `通话成员 (${userCount})`;
        }

        // 清空列表并重新渲染
        this.elements.userList.innerHTML = '';

        // 1. 渲染本地用户
        // 判断当前用户角色：Host端localUser是主持人；Participant端localUser是参与者
        this.elements.userList.appendChild(this.createUserEntry({
            user: localUser,
            role: 'local'
        }));

        // 2. 渲染远端成员
        if (participantCount > 0) {
            // 有participants数据（Host端或Participant端收到participants-sync后）
            for (const [pid, p] of Object.entries(participantsMap)) {
                if (p.role === 'host') {
                    this.elements.userList.appendChild(this.createUserEntry({
                        user: p,
                        role: 'host',
                        id: pid
                    }));
                } else {
                    this.elements.userList.appendChild(this.createUserEntry({
                        user: p,
                        role: 'participant',
                        id: pid
                    }));
                }
            }
        } else if (remoteUser.status !== 'offline') {
            // 兼容：Participant端未收到participants-sync时，使用remoteUser显示Host
            this.elements.userList.appendChild(this.createUserEntry({
                user: remoteUser,
                role: 'remote'
            }));
        }
    }

    // 创建通用用户条目
    createUserEntry(options) {
        const { user, role, id } = options;

        const div = document.createElement('div');
        const baseClass = 'flex items-center gap-3 p-2 rounded-lg';
        div.className = role === 'local'
            ? `${baseClass} hover:bg-white/5`
            : `${baseClass} bg-white/5`;

        // dataset.userId
        switch (role) {
            case 'local':
                div.dataset.userId = 'local';
                break;
            case 'remote':
                div.dataset.userId = 'remote';
                break;
            case 'host':
                div.dataset.userId = `host_${id}`;
                break;
            case 'participant':
                div.dataset.userId = `participant_${id}`;
                break;
        }

        const mediaState = user.mediaState;
        const mediaStatusText = !mediaState.audio ? '静音中' : (!mediaState.video ? '视频关闭' : '在线');
        const mediaStatusClass = (!mediaState.audio || !mediaState.video) ? 'text-xs text-gray-500' : 'text-xs text-green-400';
        const muteIconHtml = !mediaState.audio
            ? '<i class="fas fa-microphone-slash text-gray-500 text-xs"></i>'
            : '';

        // 头像区域
        let avatarHtml;
        if (role === 'local') {
            avatarHtml = `<img src="${user.avatar}" class="w-10 h-10 rounded-full object-cover">`;
        } else {
            avatarHtml = `
                <div class="relative">
                    <img src="${user.avatar}" class="w-10 h-10 rounded-full object-cover">
                    <div class="absolute -bottom-1 -right-1 w-3 h-3 bg-green-500 rounded-full border-2 border-slate-900"></div>
                </div>
            `;
        }

        // 角色标签
        let roleTag;
        if (role === 'local') {
            const isHost = user.isHost;
            roleTag = isHost
                ? '<span class="text-xs bg-indigo-500 px-1.5 rounded ml-1">主持人</span>'
                : '<span class="text-xs bg-purple-500 px-1.5 rounded ml-1">参与者</span>';
        } else if (role === 'participant') {
            roleTag = '<span class="text-xs bg-purple-500 px-1.5 rounded ml-1">参与者</span>';
        } else {
            // remote, host
            roleTag = '<span class="text-xs bg-indigo-500 px-1.5 rounded ml-1">主持人</span>';
        }

        // 媒体状态 data-field（仅local）
        const dataFieldAttr = role === 'local' ? ' data-field="localUser.mediaStatus"' : '';

        // 右侧内容
        let rightHtml;
        if (role === 'participant') {
            const speakingHtml = (mediaState.isSpeaking && mediaState.audio)
                ? '<div class="audio-wave w-6"><span></span><span></span><span></span><span></span><span></span></div>'
                : '';
            rightHtml = `
                <div class="flex items-center gap-2">
                    ${muteIconHtml}
                    ${speakingHtml}
                </div>
            `;
        } else {
            rightHtml = muteIconHtml;
        }

        div.innerHTML = `
            ${avatarHtml}
            <div class="flex-1">
                <div class="text-sm font-medium">
                    ${user.name}
                    ${roleTag}
                </div>
                <div class="${mediaStatusClass}"${dataFieldAttr}>${mediaStatusText}</div>
            </div>
            ${rightHtml}
        `;

        return div;
    }
    // 在renderer.js中添加方法
    // 获取视频流分辨率
    getVideoResolution(track) {
        if (track && track.getSettings) {
            const settings = track.getSettings();
            return {
                width: settings.width || 640,
                height: settings.height || 480
            };
        }
        return { width: 640, height: 480 }; // 默认值
    }

    // 调整视频元素大小并居中显示
    adjustVideoSize(videoElement, resolution) {
        if (!videoElement) return;

        const { width, height } = resolution;
        const aspectRatio = width / height;

        // 根据容器大小和视频宽高比调整视频显示
        const container = videoElement.parentElement;
        const containerWidth = container.clientWidth;
        const containerHeight = container.clientHeight;
        // 启用硬件加速
        videoElement.style.transform = 'translateZ(0)';
        videoElement.style.willChange = 'transform';
        // 设置容器为flex布局，使视频居中
        container.style.display = 'flex';
        container.style.alignItems = 'center';
        container.style.justifyContent = 'center';
        // 优化图像渲染
        videoElement.style.imageRendering = 'auto';
        // 确保视频元素在容器内正确显示
        videoElement.style.maxWidth = '100%';
        videoElement.style.maxHeight = '100%';
        videoElement.style.objectFit = 'contain'; // 保持原始比例，不裁剪
    }
    // 渲染控制按钮
    renderControlButtons(mediaState) {
        if (this.elements.micBtn) {
            toggleButtonState(this.elements.micBtn, !mediaState.audio);
        }

        if (this.elements.videoBtn) {
            toggleButtonState(this.elements.videoBtn, !mediaState.video);
        }

        if (this.elements.recordBtn) {
            toggleButtonState(this.elements.recordBtn, mediaState.recording);
        }
    }

    // 渲染聊天消息
    renderChatMessages(messages) {
        if (!this.elements.chatContent) return;

        // 清空聊天内容
        this.elements.chatContent.innerHTML = '';

        // 添加通话开始时间
        const startTimeElement = document.createElement('div');
        startTimeElement.className = 'text-center text-xs text-gray-500 my-4';
        const startTime = messages[0]?.timestamp || new Date().toISOString();
        startTimeElement.textContent = `通话开始 ${formatTimestamp(startTime)}`;
        this.elements.chatContent.appendChild(startTimeElement);

        // 添加消息
        messages.forEach(message => {
            const messageElement = this.createMessageElement(message);
            this.elements.chatContent.appendChild(messageElement);
        });

        // 滚动到底部
        this.elements.chatContent.scrollTop = this.elements.chatContent.scrollHeight;
    }

    // 创建消息元素
    createMessageElement(message) {
        const messageDiv = document.createElement('div');

        // 根据消息类型设置不同的CSS类
        let messageClass = 'chat-bubble';
        if (message.type === 'system') {
            messageClass += ' message-system';
        } else if (message.isSelf) {
            messageClass += ' message-self';
        } else {
            messageClass += ' message-other';
        }

        messageDiv.className = messageClass;
        messageDiv.dataset.messageId = message.id;

        let contentHTML = '';
        if (message.type === 'file' && message.content.startsWith('data:image/')) {
            // 图片消息
            contentHTML = `
                <div class="message-image-container">
                    <img src="${message.content}" class="message-image" alt="${message.fileName || '图片'}">
                    ${message.fileName ? `<div class="message-image-name">${message.fileName}</div>` : ''}
                </div>
            `;
        } else {
            // 文本消息
            contentHTML = `
                <div class="message-text">
                    ${message.content}
                </div>
            `;
        }

        messageDiv.innerHTML = `
            <div class="message-header">
                <img src="${message.senderAvatar}" class="message-avatar">
                <div>
                    <span class="message-sender">${message.senderName}</span>
                    <span class="message-time">${formatTimestamp(message.timestamp)}</span>
                </div>
            </div>
            <div class="message-content">
                ${contentHTML}
            </div>
        `;

        return messageDiv;
    }

    // 渲染未读消息数
    renderUnreadCount(count) {
        if (this.elements.unreadBadge) {
            if (count > 0) {
                this.elements.unreadBadge.textContent = count;
                this.elements.unreadBadge.classList.remove('hidden');
            } else {
                this.elements.unreadBadge.classList.add('hidden');
            }
        }
    }

    // 渲染侧边栏
    renderSidebar(isOpen) {
        if (this.elements.sidebar) {
            if (isOpen) {
                this.elements.sidebar.classList.remove('hidden');
            } else {
                this.elements.sidebar.classList.add('hidden');
            }
        }
    }

    // 渲染网络状态
    renderNetworkStatus(quality) {
        if (this.elements.networkStatus && this.elements.networkStatusText) {
            // 始终显示网络状态
            toggleElement(this.elements.networkStatus, true);

            // 根据网络质量设置不同的图标和颜色
            const networkStatus = this.elements.networkStatus;
            const networkStatusText = this.elements.networkStatusText;

            // 清除之前的图标
            const existingIcon = networkStatus.querySelector('i');
            if (existingIcon) {
                existingIcon.remove();
            }

            // 创建新的图标元素
            const icon = document.createElement('i');

            // 根据网络质量设置图标和样式
            switch (quality) {
                case 'excellent':
                    icon.className = 'fas fa-check-circle text-green-400';
                    networkStatusText.textContent = this.getNetworkQualityText(quality);
                    networkStatusText.className = 'text-green-400';
                    break;
                case 'good':
                    icon.className = 'fas fa-signal text-blue-400';
                    networkStatusText.textContent = this.getNetworkQualityText(quality);
                    networkStatusText.className = 'text-blue-400';
                    break;
                case 'fair':
                    icon.className = 'fas fa-exclamation-circle text-yellow-500';
                    networkStatusText.textContent = this.getNetworkQualityText(quality);
                    networkStatusText.className = 'text-yellow-500';
                    break;
                case 'poor':
                    icon.className = 'fas fa-exclamation-triangle text-red-500';
                    networkStatusText.textContent = this.getNetworkQualityText(quality);
                    networkStatusText.className = 'text-red-500';
                    break;
                case 'no_signal':
                    icon.className = 'fas fa-times-circle text-gray-500';
                    networkStatusText.textContent = this.getNetworkQualityText(quality);
                    networkStatusText.className = 'text-gray-500';
                    break;
                default:
                    icon.className = 'fas fa-question-circle text-gray-400';
                    networkStatusText.textContent = '未知';
                    networkStatusText.className = 'text-gray-400';
            }

            // 添加图标到网络状态元素
            networkStatus.insertBefore(icon, networkStatusText);
        }

        if (this.elements.connectionQuality) {
            const qualityText = this.getNetworkQualityText(quality);
            let statusClass = '';

            // 根据网络质量设置文本颜色
            switch (quality) {
                case 'excellent':
                    statusClass = 'text-green-400';
                    break;
                case 'good':
                    statusClass = 'text-blue-400';
                    break;
                case 'fair':
                    statusClass = 'text-yellow-500';
                    break;
                case 'poor':
                    statusClass = 'text-red-500';
                    break;
                case 'no_signal':
                    statusClass = 'text-gray-500';
                    break;
                default:
                    statusClass = 'text-gray-400';
            }

            // 更新连接质量文本和样式
            this.elements.connectionQuality.textContent = `连接质量: ${qualityText}`;
            this.elements.connectionQuality.className = `text-xs ${statusClass}`;
        }

        // 同步更新头部网络指示器
        this.updateHeaderNetworkIndicator(quality);

        // 同步更新头部网络质量文本
        this.renderHeaderNetworkStatus(quality);
    }

    // 更新头部网络指示器
    updateHeaderNetworkIndicator(networkQuality) {
        if (!this.elements.remoteNetworkIndicator) return;

        // 根据网络质量设置指示器颜色
        if (networkQuality === 'no_signal') {
            // 无信号时显示灰色点，取消动画
            this.elements.remoteNetworkIndicator.className = 'w-2 h-2 bg-gray-500 rounded-full';
        } else {
            // 有信号时显示绿色点，保持动画
            this.elements.remoteNetworkIndicator.className = 'w-2 h-2 bg-green-500 rounded-full animate-pulse';
        }
    }


    // 渲染通话结束
    renderCallEnded() {
        console.log('Call ended');

        // 清理participant网格
        const grid = this.elements.participantGrid;
        if (grid) {
            grid.querySelectorAll('[data-participant-id]').forEach(tile => {
                const video = tile.querySelector('video');
                if (video) video.srcObject = null;
                tile.remove();
            });
            grid.classList.add('hidden');
        }

        // 跳转到结束通话界面
        window.location.href = './endcall/endcall.html';
    }

    // 渲染participant离开（host端，房间仍然存在）
    renderParticipantLeft(connectionId) {
        console.log(`Participant left: ${connectionId}, updating UI`);

        const grid = this.elements.participantGrid;
        if (grid) {
            const tile = grid.querySelector(`[data-participant-id="${connectionId}"]`);
            if (tile) {
                const video = tile.querySelector('video');
                if (video) video.srcObject = null;
                tile.remove();
                console.log(`Removed participant video tile for ${connectionId}`);
            }

            const remainingTiles = grid.querySelectorAll('[data-participant-id]');
            if (remainingTiles.length === 0) {
                grid.classList.add('hidden');
                const remoteVideoDiv = this.elements.remoteVideo?.closest('.absolute.inset-0.video-fade-in');
                if (remoteVideoDiv) {
                    remoteVideoDiv.classList.remove('hidden');
                }
                if (this.elements.remoteVideoPlaceholder) {
                    this.elements.remoteVideoPlaceholder.classList.remove('hidden');
                }
            } else {
                grid.style.gridTemplateColumns = getGridTemplateColumns(remainingTiles.length);
            }
        }

        if (this.elements.remoteNetworkIndicator) {
            this.elements.remoteNetworkIndicator.className = 'w-2 h-2 bg-gray-500 rounded-full';
        }
    }

    // 获取状态文本
    getStatusText(status) {
        const statusMap = {
            'online': '在线',
            'offline': '离线',
            'connecting': '连接中'
        };
        return statusMap[status] || status;
    }

    // 获取网络质量文本
    getNetworkQualityText(quality) {
        const qualityMap = {
            'excellent': '优秀',
            'good': '良好',
            'fair': '一般',
            'poor': '较差',
            'no_signal': '无信号'
        };
        return qualityMap[quality] || quality;
    }

    // 销毁
    destroy() {
        if (this.unsubscribe) {
            this.unsubscribe();
        }
        if (this.messageUnsubscribe) {
            this.messageUnsubscribe();
        }
    }
}

export default UIRenderer;
