<template>
    <!-- 音频元素 -->
    <audio ref="localAudio" autoplay muted class="audio-element"></audio>
    <div id="audio"></div>
    <div class="livekit-container">
        <div v-if="!status" class="meeting-container"> 
            <!-- 视频容器 -->
            <div class="video-layout" :class="{ 'screen-sharing-active': hasActiveScreenShare }">
                <!-- 左侧共享屏幕区域 -->
                <div class="screen-share-area" v-if="hasActiveScreenShare">
                    <div class="screen-share-header">
                        <h3>共享屏幕</h3>
                        <div class="sharing-user">
                            由 {{ screenSharingUser }} 共享
                        </div>
                    </div>
                    <div class="screen-share-video">
                        <div class="video-wrapper screen-share-wrapper">
                            <div class="video-tracks">
                                <!-- 屏幕共享视频 -->
                                <video 
                                    v-if="activeScreenShareTrack"
                                    :ref="el => setScreenShareVideoRef(el)"
                                    autoplay 
                                    playsinline 
                                    class="screen-share-element"
                                    @loadedmetadata="handleScreenShareLoaded">
                                </video>
                                <!-- 如果没有屏幕共享，显示提示 -->
                                <div v-if="!activeScreenShareTrack" class="video-placeholder">
                                    <i class="el-icon-monitor"></i>
                                    <span>暂无屏幕共享</span>
                                </div>
                            </div>
                            <div class="video-overlay">
                                <span class="participant-name">{{ screenSharingUser }}</span>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- 右侧视频区域 -->
                <div class="participants-area" :class="{ 'with-screen-share': hasActiveScreenShare }">
                    <div class="participants-header">
                        <h3>会议名称：测试会议名称</h3>
                        <h3>参会者 ({{ participantCount }})</h3>
                    </div>
                    <div class="video-grid" :class="{ 'grid-layout': !hasActiveScreenShare && participantCount > 1 }">
                        <!-- 本地视频 -->
                        <div class="participant-card local-participant">
                            <div class="participant-header">
                                <h3>我的视频 ({{ hostUid }})</h3>
                                <div class="status-indicator">
                                    <span class="status-dot" :class="{ 'speaking': isLocalSpeaking }"></span>
                                    <span>{{ microphoneEnabled ? '音频在线' : '音频离线' }}</span>
                                </div>
                            </div>
                            <div class="video-wrapper">
                                <video ref="localVideo" autoplay muted playsinline class="video-element"></video>
                                <div class="video-overlay">
                                    <span class="participant-name">{{ hostUid }}</span>
                                    <span class="audio-indicator" :class="{ 'muted': !microphoneEnabled }">
                                        <i :class="microphoneEnabled ? 'el-icon-microphone' : 'el-icon-turn-off-microphone'"></i>
                                    </span>
                                </div>
                                <!-- 视频占位符 -->
                                <div v-if="!cameraEnabled" class="video-placeholder">
                                    <i class="el-icon-user"></i>
                                    <span>摄像头已关闭</span>
                                </div>
                            </div> 
                        </div>

                        <!-- 远程视频-->
                        <div class="participant-card" v-for="participant in remoteParticipantsArray" :key="participant.identity">
                            <div class="participant-header">
                                <h3>{{ participant.identity }}</h3>
                                <div class="status-indicator">
                                    <span class="status-dot" :class="{ 'speaking': participant.isSpeaking }"></span>
                                    <span>{{ participant.audioEnabled ? '音频在线' : '音频离线' }}</span>
                                </div>
                            </div>
                            <div class="video-wrapper">
                                <div class="video-tracks">
                                    <!-- 摄像头视频 - 使用 ref 绑定 -->
                                    <video 
                                        v-if="participant.hasCameraTrack"
                                        :ref="el => setParticipantVideoRef(el, participant.identity, 'camera')"
                                        autoplay 
                                        playsinline 
                                        class="video-element"
                                        @loadedmetadata="() => handleVideoLoaded(participant.identity, 'camera')">
                                    </video>
                                    <!-- 如果没有视频轨道，显示提示 -->
                                    <div v-if="!participant.hasCameraTrack && !participant.hasScreenTrack" class="video-placeholder">
                                        <i class="el-icon-user"></i>
                                        <span>暂无视频流</span>
                                    </div>
                                </div>
                                <div class="video-overlay">
                                    <span class="participant-name">{{ participant.identity }}</span>
                                    <span v-if="participant.hasScreenTrack" class="screen-sharing-indicator">
                                        <i class="el-icon-monitor"></i> 正在共享
                                    </span>
                                    <span class="audio-indicator" :class="{ 'muted': !participant.audioEnabled }">
                                        <i :class="participant.audioEnabled ? 'el-icon-microphone' : 'el-icon-turn-off-microphone'"></i>
                                    </span>
                                </div>
                            </div>
                            <!-- 远程参与者音频元素 -->
                            <audio 
                                :ref="el => setParticipantAudioRef(el, participant.identity)"
                                autoplay 
                                class="participant-audio">
                            </audio>
                        </div>
                    </div>  
                </div>
            </div>
            
            <!-- 固定在底部的控制按钮 -->
            <div class="fixed-controls">
                <div class="controls-container">
                    <el-button @click="toggleCamera" :type="cameraEnabled ? 'danger' : 'success'" class="control-btn" size="large">
                        <i :class="cameraEnabled ? 'el-icon-video-camera' : 'el-icon-video-camera-solid'"></i>
                        {{ cameraEnabled ? '关闭摄像头' : '开启摄像头' }}
                    </el-button>
                    <el-button @click="toggleMicrophone" :type="microphoneEnabled ? 'danger' : 'success'" class="control-btn" size="large">
                        <i :class="microphoneEnabled ? 'el-icon-microphone' : 'el-icon-turn-off-microphone'"></i>
                        {{ microphoneEnabled ? '关闭麦克风' : '开启麦克风' }}
                    </el-button>
                    <el-button @click="toggleScreenShare" :type="isScreenSharing ? 'danger' : 'primary'" class="control-btn" size="large">
                        <i class="el-icon-monitor"></i>
                        {{ isScreenSharing ? '停止共享' : '共享屏幕' }}
                    </el-button>
                    <el-button @click="leaveRoom" type="warning" class="control-btn leave-btn" size="large">
                        <i class="el-icon-switch-button"></i>
                        离开会议
                    </el-button>
                </div>
            </div>
        </div>
    </div>
</template>

<script setup>
import { reactive, ref, onMounted, onUnmounted, nextTick, computed, watch } from "vue";  
import { ElMessage } from 'element-plus';
import { getRoomToken, getRoomList ,getInvite,getTokenApi,exitRoomApi} from "@/api/conferencingRoom.js"
import { Room, RoomEvent, ParticipantEvent, Track } from "livekit-client";
import { useRoute, useRouter } from 'vue-router'
import { useRoomStore } from '@/stores/modules/room.js'
import  useUserStore  from '@/stores/modules/user'

const userStore = useUserStore()
const roomStore = useRoomStore() 
const route = useRoute();
const router = useRouter()

// LiveKit 服务器配置
const wsURL = "wss://meeting.cnsdt.com:443";

const hostUid = ref('')
const status = ref(true); 

// 音视频相关引用和数据
const localVideo = ref(null);
const localAudio = ref(null);
const cameraEnabled = ref(false);
const microphoneEnabled = ref(false);
const isScreenSharing = ref(false);
const isLocalSpeaking = ref(false);

// 远程参与者管理
const remoteParticipants = ref(new Map());
const videoElementsMap = ref(new Map());
const audioElementsMap = ref(new Map());

// 屏幕共享相关
const screenSharingUser = ref('');
const activeScreenShareTrack = ref(null);
const screenShareVideo = ref(null);

// 计算属性
const participantCount = computed(() => {
    return remoteParticipants.value.size + 1; // 包括自己
});

const remoteParticipantsArray = computed(() => {
    return Array.from(remoteParticipants.value.values());
});

const hasActiveScreenShare = computed(() => {
    return screenSharingUser.value !== '' || isScreenSharing.value;
});

// 创建 Room 实例
const room = new Room({
    adaptiveStream: true,
    dynacast: true,
    // 音频捕获配置
    audioCaptureDefaults: {
        echoCancellation: true,
        noiseSuppression: true,
        autoGainControl: true,
    },
    videoCaptureDefaults: {
        resolution: { width: 1280, height: 720 }
    },
    publishDefaults: {
        screenShareEncoding: {
            maxBitrate: 3_000_000,
            maxFramerate: 30,
        },
        videoEncoding: {
            maxBitrate: 2_500_000,
            maxFramerate: 30,
        },
        // 音频发布配置
        audioEncoding: {
            maxBitrate: 64000, // 64kbps for audio
        },
        dtx: true, // 不连续传输，节省带宽
        red: true, // 冗余编码，提高抗丢包能力
    }
});

// 设置视频元素引用
function setParticipantVideoRef(el, identity, type) {
    if (!el) return;
    
    if (!videoElementsMap.value.has(identity)) {
        videoElementsMap.value.set(identity, {});
    }
    
    const elements = videoElementsMap.value.get(identity);
    elements[type] = el;
    videoElementsMap.value.set(identity, elements);
    
    // 如果已经有轨道数据，立即附加
    const participantData = remoteParticipants.value.get(identity);
    
    if (participantData) {
        if (type === 'camera' && participantData.cameraTrack) {
            attachTrackToVideo(el, participantData.cameraTrack);
        } else if (type === 'screen' && participantData.screenTrack) {
            attachTrackToVideo(el, participantData.screenTrack);
        }
    }
}

// 设置音频元素引用
function setParticipantAudioRef(el, identity) {
    if (!el) return;
    
    audioElementsMap.value.set(identity, el);
    
    // 如果已经有音频轨道数据，立即附加
    const participantData = remoteParticipants.value.get(identity);
    if (participantData && participantData.audioTrack) {
        attachTrackToAudio(el, participantData.audioTrack);
    }
}

// 设置屏幕共享视频引用
function setScreenShareVideoRef(el) {
    if (!el) return;
    screenShareVideo.value = el;
    
    // 如果已经有屏幕共享轨道，立即附加
    if (activeScreenShareTrack.value) {
        attachTrackToVideo(el, activeScreenShareTrack.value);
    }
}

// 设置事件监听器
function setupRoomListeners() {
    room.removeAllListeners();
    
    room
    .on(RoomEvent.Connected, handleConnected)
    .on(RoomEvent.Disconnected, handleDisconnected)
    .on(RoomEvent.Reconnected, handleReconnected)
    .on(RoomEvent.TrackSubscribed, handleTrackSubscribed)
    .on(RoomEvent.TrackUnsubscribed, handleTrackUnsubscribed)
    .on(RoomEvent.ParticipantConnected, handleParticipantConnected)
    .on(RoomEvent.ParticipantDisconnected, handleParticipantDisconnected)
    .on(RoomEvent.LocalTrackPublished, handleLocalTrackPublished)
    .on(RoomEvent.LocalTrackUnpublished, handleLocalTrackUnpublished)
    .on(RoomEvent.TrackMuted, handleTrackMuted)
    .on(RoomEvent.TrackUnmuted, handleTrackUnmuted)
    .on(RoomEvent.ActiveSpeakersChanged, handleActiveSpeakersChanged)
    .on(RoomEvent.DataReceived, handleDataReceived)
    .on(RoomEvent.ConnectionStateChanged, handleConnectionStateChanged);
}

// 事件处理函数
async function handleConnected() {
    console.log("成功连接到房间:", room.name);
    status.value = false;
 
    ElMessage.success('已成功连接到房间');
    
    // 初始化现有远程参与者
    room.remoteParticipants.forEach(participant => {
        addRemoteParticipant(participant);
        setupParticipantListeners(participant);
        // 立即检查并更新参与者的轨道状态
        updateParticipantTracks(participant);
    });

    // 自动开启麦克风
    try {
        await enableMicrophone();
        ElMessage.success('麦克风已自动开启');
    } catch (error) {
        console.warn('自动开启麦克风失败:', error);
    }
}

function handleDisconnected(reason) {
    console.log("断开连接:", reason);
    status.value = true;
    cameraEnabled.value = false;
    microphoneEnabled.value = false;
    isScreenSharing.value = false;
    remoteParticipants.value.clear();
    videoElementsMap.value.clear();
    audioElementsMap.value.clear();
    screenSharingUser.value = '';
    activeScreenShareTrack.value = null;
    
    ElMessage.error('连接已断开');
}

function handleReconnected() {
    console.log("已重新连接"); 
    ElMessage.success('已重新连接到房间');
}

// 处理轨道订阅事件
function handleTrackSubscribed(track, publication, participant) {  
    console.log("轨道已订阅:", track.kind, "轨道来源:", publication.source, "来自:", participant.identity);
    
    if (track) {
        if (track.kind === Track.Kind.Video) {
            // 更新参与者轨道信息
            updateParticipantTrack(participant, publication.source, track);
            
            // 如果是屏幕共享，更新屏幕共享状态
            if (publication.source === Track.Source.ScreenShare) {
                updateScreenShareState(participant, track);
            }
            
            // 立即附加到视频元素（如果元素已存在）
            attachTrackToParticipantVideo(participant.identity, publication.source, track); 
        } else if (track.kind === Track.Kind.Audio) {
            // 处理音频轨道订阅
            updateParticipantAudioTrack(participant, track);
            attachTrackToParticipantAudio(participant.identity, track);
        }
    }
    
    // 更新参与者的轨道状态
    updateParticipantTracks(participant);
}

function handleTrackUnsubscribed(track, publication, participant) { 
    // 移除对应的轨道信息
    if (track.kind === Track.Kind.Video) {
        removeParticipantTrack(participant, publication.source);
        // 清理视频元素
        detachTrackFromParticipantVideo(participant.identity, publication.source);
        
        // 如果是屏幕共享，更新屏幕共享状态
        if (publication.source === Track.Source.ScreenShare) {
            updateScreenShareState(participant, null);
        }
    } else if (track.kind === Track.Kind.Audio) {
        // 处理音频轨道取消订阅
        removeParticipantAudioTrack(participant);
        detachTrackFromParticipantAudio(participant.identity);
    }
    updateParticipantTracks(participant);
}

function handleParticipantConnected(participant) {
    addRemoteParticipant(participant);
    setupParticipantListeners(participant);
    // 立即检查参与者的轨道状态
    updateParticipantTracks(participant);
    ElMessage.info(`新用户加入: ${participant.identity}`);
}

function handleParticipantDisconnected(participant) {
    // 如果离开的用户是屏幕共享者，清除屏幕共享状态
    if (participant.identity === screenSharingUser.value) {
        screenSharingUser.value = '';
        activeScreenShareTrack.value = null;
        if (screenShareVideo.value && screenShareVideo.value.srcObject) {
            screenShareVideo.value.srcObject = null;
        }
    }
    
    removeRemoteParticipant(participant);
    ElMessage.info(`用户离开: ${participant.identity}`);
}

function handleLocalTrackPublished(publication) {
    if (publication.track) {
        if (publication.kind === Track.Kind.Video) {
            if (publication.source === Track.Source.Camera) {
                attachLocalVideoTrack(publication.track);
            } else if (publication.source === Track.Source.ScreenShare) {
                // 本地用户开始屏幕共享
                screenSharingUser.value = room.localParticipant.identity;
                activeScreenShareTrack.value = publication.track;
                if (screenShareVideo.value) {
                    attachTrackToVideo(screenShareVideo.value, publication.track);
                }
            }
        } else if (publication.kind === Track.Kind.Audio) {
            // 本地音频轨道发布
            microphoneEnabled.value = true;
            console.log('本地音频轨道已发布');
        }
    }
}

function handleLocalTrackUnpublished(publication) {
    if (publication.kind === Track.Kind.Video) {
        if (publication.source === Track.Source.Camera) {
            cameraEnabled.value = false;
        } else if (publication.source === Track.Source.ScreenShare) {
            // 本地用户停止屏幕共享
            if (screenSharingUser.value === room.localParticipant.identity) {
                screenSharingUser.value = '';
                activeScreenShareTrack.value = null;
                if (screenShareVideo.value && screenShareVideo.value.srcObject) {
                    screenShareVideo.value.srcObject = null;
                }
            }
        }
    } else if (publication.kind === Track.Kind.Audio) {
        microphoneEnabled.value = false;
    }
}

function handleTrackMuted(publication, participant) {
    updateParticipantTracks(participant);
}

// 处理轨道取消静音事件
function handleTrackUnmuted(publication, participant) {
    updateParticipantTracks(participant);
}

// 设置参与者事件监听器
function setupParticipantListeners(participant) {
    participant
    .on(ParticipantEvent.TrackSubscribed, (track, publication) => {
        handleTrackSubscribed(track, publication, participant);
    })
    .on(ParticipantEvent.TrackUnsubscribed, (track, publication) => {
        handleTrackUnsubscribed(track, publication, participant);
    })
    .on(ParticipantEvent.TrackMuted, (publication) => {
        handleTrackMuted(publication, participant);
    })
    .on(ParticipantEvent.TrackUnmuted, (publication) => {
        handleTrackUnmuted(publication, participant);
    })
    .on(ParticipantEvent.IsSpeakingChanged, (speaking) => {
        updateParticipantSpeaking(participant, speaking);
    });
}

// 处理活动说话者变化事件
function handleActiveSpeakersChanged(speakers) {
    // 更新本地说话状态
    const localIsSpeaking = speakers.some(speaker => speaker.identity === room.localParticipant.identity);
    isLocalSpeaking.value = localIsSpeaking;
    
    // 更新远程参与者说话状态
    remoteParticipants.value.forEach((data, identity) => {
        const isSpeaking = speakers.some(speaker => speaker.identity === identity);
        if (data.isSpeaking !== isSpeaking) {
            data.isSpeaking = isSpeaking;
            remoteParticipants.value.set(identity, { ...data });
        }
    });
}

// 处理数据接收事件
function handleDataReceived(payload, participant, kind) {
    try {
        const decoder = new TextDecoder();
        const strData = decoder.decode(payload);
        ElMessage.info(`收到消息 from ${participant.identity}: ${strData}`);
    } catch (error) {
        console.error('处理接收消息失败:', error);
    }
}

function handleConnectionStateChanged(state) {
    console.log('连接状态改变:', state);
}

// 更新屏幕共享状态
function updateScreenShareState(participant, track) {
    if (track) {
        // 有新的屏幕共享轨道
        screenSharingUser.value = participant.identity;
        activeScreenShareTrack.value = track;
        
        // 附加到屏幕共享视频元素
        if (screenShareVideo.value) {
            attachTrackToVideo(screenShareVideo.value, track);
        }
    } else {
        // 如果当前屏幕共享者是该参与者，清除屏幕共享状态
        if (participant.identity === screenSharingUser.value) {
            screenSharingUser.value = '';
            activeScreenShareTrack.value = null;
            if (screenShareVideo.value && screenShareVideo.value.srcObject) {
                screenShareVideo.value.srcObject = null;
            }
        }
    }
}

// 参与者管理函数
function addRemoteParticipant(participant) {
    if (!participant || participant.identity === room.localParticipant?.identity) {
        return;
    }
    const participantData = {
        identity: participant.identity,
        cameraTrack: null,
        screenTrack: null,
        audioTrack: null,
        hasCameraTrack: false,
        hasScreenTrack: false,
        audioEnabled: false,
        videoEnabled: participant.isCameraEnabled,
        isSpeaking: false
    };
    remoteParticipants.value.set(participant.identity, participantData);
    console.log("添加远程参与者:", participant.identity);
}

function removeRemoteParticipant(participant) {
    if (remoteParticipants.value.has(participant.identity)) {
        // 清理音视频元素
        const identity = participant.identity;
        detachTrackFromParticipantVideo(identity, 'camera');
        detachTrackFromParticipantVideo(identity, 'screen');
        detachTrackFromParticipantAudio(identity);
        remoteParticipants.value.delete(identity);
        videoElementsMap.value.delete(identity);
        audioElementsMap.value.delete(identity);
    }
}

// 更新参与者轨道信息
function updateParticipantTrack(participant, source, track) {
    const data = remoteParticipants.value.get(participant.identity);
    if (!data) return;
    if (source === Track.Source.Camera) {
        data.cameraTrack = track;
        data.hasCameraTrack = true;
    } else if (source === Track.Source.ScreenShare) {
        data.screenTrack = track;
        data.hasScreenTrack = true;
    }
    remoteParticipants.value.set(participant.identity, { ...data });
}

function removeParticipantTrack(participant, source) {
    const data = remoteParticipants.value.get(participant.identity);
    if (!data) return;
    if (source === Track.Source.Camera) {
        data.cameraTrack = null;
        data.hasCameraTrack = false;
    } else if (source === Track.Source.ScreenShare) {
        data.screenTrack = null;
        data.hasScreenTrack = false;
    }
    remoteParticipants.value.set(participant.identity, { ...data });
}

// 更新参与者音频轨道信息
function updateParticipantAudioTrack(participant, track) {
    const data = remoteParticipants.value.get(participant.identity);
    if (!data) return;
    data.audioTrack = track;
    data.audioEnabled = true;
    remoteParticipants.value.set(participant.identity, { ...data });
}

function removeParticipantAudioTrack(participant) {
    const data = remoteParticipants.value.get(participant.identity);
    if (!data) return;
    data.audioTrack = null;
    data.audioEnabled = false;
    remoteParticipants.value.set(participant.identity, { ...data });
}

// 附加轨道到视频元素
function attachTrackToVideo(videoElement, track) {
    if (!videoElement || !track) return;
    try {
        // 使用 MediaStream 方式附加轨道
        const mediaStream = new MediaStream();
        mediaStream.addTrack(track.mediaStreamTrack);
        videoElement.srcObject = mediaStream;
    } catch (error) {
        console.error('附加轨道到视频元素失败:', error);
    }
}

// 附加轨道到音频元素
function attachTrackToAudio(audioElement, track) {
    if (!audioElement || !track) return;
    try {
        const mediaStream = new MediaStream();
        mediaStream.addTrack(track.mediaStreamTrack);
        audioElement.srcObject = mediaStream;
        // 确保音频元素可以播放
        audioElement.play().catch(error => {
            console.warn('音频播放失败:', error);
        });
    } catch (error) {
        console.error('附加轨道到音频元素失败:', error);
    }
}

// 附加轨道到参与者的视频元素
function attachTrackToParticipantVideo(identity, source, track) {
    const videoElements = videoElementsMap.value.get(identity);
    if (!videoElements) return;
    const type = source === Track.Source.Camera ? 'camera' : 'screen';
    const videoElement = videoElements[type];
    if (videoElement) {
        attachTrackToVideo(videoElement, track);
    }
}

// 附加轨道到参与者的音频元素
function attachTrackToParticipantAudio(identity, track) {
    const audioElement = audioElementsMap.value.get(identity);
    if (audioElement) {
        attachTrackToAudio(audioElement, track);
    }
}

// 从参与者的视频元素分离轨道
function detachTrackFromParticipantVideo(identity, source) {
    const videoElements = videoElementsMap.value.get(identity);
    if (!videoElements) return;
    const type = source === Track.Source.Camera ? 'camera' : 'screen';
    const videoElement = videoElements[type];
    if (videoElement && videoElement.srcObject) {
        videoElement.srcObject = null;
    }
}

// 从参与者的音频元素分离轨道
function detachTrackFromParticipantAudio(identity) {
    const audioElement = audioElementsMap.value.get(identity);
    if (audioElement && audioElement.srcObject) {
        audioElement.srcObject = null;
    }
}

function updateParticipantTracks(participant) {
    const data = remoteParticipants.value.get(participant.identity);
    if (!data) return;
    // 检查视频轨道状态
    let hasCamera = false;
    let hasScreen = false;
    let hasAudio = false;
    
    // 检查已发布的轨道
    participant.videoTrackPublications.forEach(publication => {
        if (publication.isSubscribed && publication.track) {
            if (publication.source === Track.Source.Camera) {
                hasCamera = true;
                // 确保轨道信息更新
                if (!data.cameraTrack) {
                    data.cameraTrack = publication.track;
                }
            } else if (publication.source === Track.Source.ScreenShare) {
                hasScreen = true;
                if (!data.screenTrack) {
                    data.screenTrack = publication.track;
                }
            }
        }
    });
    
    // 检查音频轨道
    participant.audioTrackPublications.forEach(publication => {
        if (publication.isSubscribed && publication.track) {
            hasAudio = true;
            if (!data.audioTrack) {
                data.audioTrack = publication.track;
            }
        }
    });
    
    data.hasCameraTrack = hasCamera;
    data.hasScreenTrack = hasScreen;
    data.audioEnabled = hasAudio;
    data.videoEnabled = participant.isCameraEnabled;
    remoteParticipants.value.set(participant.identity, { ...data });
}

function updateParticipantSpeaking(participant, speaking) {
    const data = remoteParticipants.value.get(participant.identity);
    if (data && data.isSpeaking !== speaking) {
        data.isSpeaking = speaking;
        remoteParticipants.value.set(participant.identity, { ...data });
    }
}

function handleVideoLoaded(identity, type) {
    console.log(`视频加载完成: ${identity}的${type}视频`);
}

function handleScreenShareLoaded() {
    console.log('屏幕共享视频加载完成');
}

// 视频轨道处理函数
function attachLocalVideoTrack(track) {
    if (localVideo.value && track) {
        try {
            const mediaStream = new MediaStream();
            mediaStream.addTrack(track.mediaStreamTrack);
            localVideo.value.srcObject = mediaStream;
            cameraEnabled.value = true;
        } catch (error) {
            console.error('附加本地视频轨道失败:', error);
        }
    }
}

// 媒体控制函数
async function enableCamera() {
    try {
        await room.localParticipant.setCameraEnabled(true);
        cameraEnabled.value = true;
        return true;
    } catch (error) {
        console.error('开启摄像头失败:', error);
        cameraEnabled.value = false;
        throw error;
    }
}

async function enableMicrophone() {
    try {
        await room.localParticipant.setMicrophoneEnabled(true);
        microphoneEnabled.value = true;
        return true;
    } catch (error) {
        console.error('开启麦克风失败:', error);
        microphoneEnabled.value = false;
        throw error;
    }
}

async function toggleCamera() {
    try {
        if (cameraEnabled.value) {
            // 关闭摄像头
            await room.localParticipant.setCameraEnabled(false);
            cameraEnabled.value = false;
            // 清理本地视频元素
            if (localVideo.value && localVideo.value.srcObject) {
                localVideo.value.srcObject.getTracks().forEach(track => track.stop());
                localVideo.value.srcObject = null;
            }
            ElMessage.info('摄像头已关闭');
        } else {
            // 确保视频元素存在
            if (!localVideo.value) {
                console.warn('本地视频元素未找到，等待DOM更新');
                await nextTick();
            }
            // 开启摄像头
            await room.localParticipant.setCameraEnabled(true);
            cameraEnabled.value = true;
            ElMessage.success('摄像头已开启');
            // 手动获取并附加视频轨道，增加延迟
            setTimeout(() => {
                attachLocalCameraTrack();
            }, 200);
        }
    } catch (error) {
        console.error('切换摄像头失败:', error);
        ElMessage.error('切换摄像头失败: ' + error.message);
    }
}

async function attachLocalCameraTrack() {
    try {
        // 等待一小段时间确保轨道已经创建
        await new Promise(resolve => setTimeout(resolve, 100));
        // 获取本地参与者的摄像头轨道发布
        const videoPublications = Array.from(room.localParticipant.videoTrackPublications.values());
        const cameraPublication = videoPublications.find(pub => 
            pub.source === Track.Source.Camera && pub.track
        );
        if (cameraPublication && cameraPublication.track) {
            attachLocalVideoTrack(cameraPublication.track);
        } else {
            // 如果没有找到，等待更长时间再检查
            setTimeout(() => {
                const videoPublications = Array.from(room.localParticipant.videoTrackPublications.values());
                const cameraPublication = videoPublications.find(pub => 
                    pub.source === Track.Source.Camera && pub.track
                );
                if (cameraPublication && cameraPublication.track) {
                    attachLocalVideoTrack(cameraPublication.track);
                } else {
                    console.warn('最终未找到摄像头轨道');
                }
            }, 1000);
        }
    } catch (error) {
        console.error('手动附加摄像头轨道失败:', error);
    }
}

async function toggleMicrophone() {
    try {
        if (microphoneEnabled.value) {
            await room.localParticipant.setMicrophoneEnabled(false);
            microphoneEnabled.value = false;
            ElMessage.info('麦克风已关闭');
        } else {
            // 确保有音频输入设备权限
            try {
                // 先检查麦克风权限
                await navigator.mediaDevices.getUserMedia({ audio: true });
            } catch (error) {
                ElMessage.error('无法访问麦克风，请检查权限设置');
                return;
            }
            
            await room.localParticipant.setMicrophoneEnabled(true);
            microphoneEnabled.value = true;
            ElMessage.success('麦克风已开启');
            
            // 等待音频轨道发布
            setTimeout(() => {
                const audioPublications = Array.from(room.localParticipant.audioTrackPublications.values());
                const audioPublication = audioPublications.find(pub => pub.track);
                if (audioPublication && audioPublication.track) {
                    console.log('本地音频轨道已发布:', audioPublication.track);
                }
            }, 500);
        }
    } catch (error) {
        console.error('切换麦克风失败:', error);
        ElMessage.error('切换麦克风失败: ' + error.message);
    }
}

async function toggleScreenShare() {
    try {
        if (isScreenSharing.value) {
            await room.localParticipant.setScreenShareEnabled(false);
            isScreenSharing.value = false;
            ElMessage.info('屏幕共享已停止');
        } else {
            await room.localParticipant.setScreenShareEnabled(true);
            isScreenSharing.value = true;
            ElMessage.success('屏幕共享已开始');
        }
    } catch (error) {
        console.error('切换屏幕共享失败:', error);
        ElMessage.error('切换屏幕共享失败: ' + error.message);
    }
}

async function joinRoomBtn() {
    try {
        const res = await getRoomToken({max_participants: 20});
        const token = res.data.access_token;
        if (!token) {
            throw new Error('获取 token 失败');
        } 
        setupRoomListeners();
        await room.connect(wsURL, token, {
            autoSubscribe: true,
        });  
    } catch (error) { 
        ElMessage.error(`连接失败: ${error.message}`);
        status.value = true;
    }
}

// 离开会议函数
async function leaveRoom() {
    try {
        const res = await exitRoomApi(room.name)
        console.log(res,'离开房间成功')
        // 停止屏幕共享（如果正在共享）
        if (isScreenSharing.value) {
            await room.localParticipant.setScreenShareEnabled(false);
        }
        
        // 关闭摄像头和麦克风
        await room.localParticipant.setCameraEnabled(false);
        await room.localParticipant.setMicrophoneEnabled(false);
        
        // 断开与房间的连接
        await room.disconnect();
        
        // 重置所有状态
        resetRoomState();
        
        ElMessage.success('已离开会议');  
        router.push({
            path: '/coordinate', 
        }) 
        
    } catch (error) {
        console.error('离开会议失败:', error);
        ElMessage.error('离开会议失败: ' + error.message);
    }
}

// 重置房间状态函数
function resetRoomState() {
    // 重置本地状态
    cameraEnabled.value = false;
    microphoneEnabled.value = false;
    isScreenSharing.value = false;
    isLocalSpeaking.value = false;
    status.value = true;
    hostUid.value = '';
    
    // 重置远程参与者
    remoteParticipants.value.clear();
    videoElementsMap.value.clear();
    audioElementsMap.value.clear();
    
    // 重置屏幕共享状态
    screenSharingUser.value = '';
    activeScreenShareTrack.value = null;
    
    // 清理视频元素
    if (localVideo.value && localVideo.value.srcObject) {
        localVideo.value.srcObject.getTracks().forEach(track => track.stop());
        localVideo.value.srcObject = null;
    }
    
    // 清理音频元素
    if (localAudio.value && localAudio.value.srcObject) {
        localAudio.value.srcObject.getTracks().forEach(track => track.stop());
        localAudio.value.srcObject = null;
    }
    
    if (screenShareVideo.value && screenShareVideo.value.srcObject) {
        screenShareVideo.value.srcObject.getTracks().forEach(track => track.stop());
        screenShareVideo.value.srcObject = null;
    }
    
    // 清理所有远程参与者的音视频元素
    videoElementsMap.value.forEach((elements, identity) => {
        if (elements.camera && elements.camera.srcObject) {
            elements.camera.srcObject.getTracks().forEach(track => track.stop());
            elements.camera.srcObject = null;
        }
        if (elements.screen && elements.screen.srcObject) {
            elements.screen.srcObject.getTracks().forEach(track => track.stop());
            elements.screen.srcObject = null;
        }
    });
    
    audioElementsMap.value.forEach((audioElement, identity) => {
        if (audioElement && audioElement.srcObject) {
            audioElement.srcObject.getTracks().forEach(track => track.stop());
            audioElement.srcObject = null;
        }
    });
}

// 在组件卸载时也清理资源
onUnmounted(() => {
    if (room && room.state === 'connected') {
        leaveRoom();
    }
});

onMounted(async () => { 
    // 确保在连接前请求音频权限
    try {
        // 预请求音频权限
        await navigator.mediaDevices.getUserMedia({ audio: true });
        console.log('音频权限已获取');
    } catch (error) {
        console.warn('音频权限获取失败:', error);
        ElMessage.warning('请允许麦克风权限以使用音频功能');
    }
    
    if(route.query.type == '1'){ 
        await joinRoomBtn()
        hostUid.value = roomStore.userUid
        // 邀请用户参与房间
        await getInvite(room.name,{user_uids:[roomStore.detailUid], participant_role: "participant"})
    } else { 
        const userInfo = await userStore.getInfo()
        hostUid.value = userInfo.uid 
        // 确保 hostUid 更新到模板
        await nextTick(); 
        const res = await getTokenApi(route.query.room_uid)
        if(res.meta.code == 200){ 
            const token = res.data.access_token;
            setupRoomListeners();
            await room.connect(wsURL, token, {
                autoSubscribe: true,
            });  
        }  
    }
});
</script>

<style>
/* 添加音频状态指示器样式 */
.audio-indicator {
    margin-left: 8px;
    font-size: 12px;
}

.audio-indicator.muted {
    color: #f56c6c;
}

.audio-indicator:not(.muted) {
    color: #67c23a;
}

.status-dot.speaking {
    background-color: #67c23a;
    animation: pulse 1.5s infinite;
}

@keyframes pulse {
    0% { opacity: 1; }
    50% { opacity: 0.5; }
    100% { opacity: 1; }
}

/* 隐藏音频元素，不显示在页面上 */
.audio-element, .participant-audio {
    display: none;
}
/* 全局样式 */
* {
    box-sizing: border-box;
}

body {
    margin: 0;
    padding: 0;
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    background: #0f0f1a;
    color: #e0e0e0;
}

.livekit-container {
    min-height: 100vh;
    padding: 20px;
    background: linear-gradient(135deg, #0f0f1a 0%, #1a1a2e 100%);
}

/* 表单样式 */
.form-container {
    max-width: 480px;
    margin: 60px auto;
    padding: 40px;
    background: rgba(255, 255, 255, 0.05);
    backdrop-filter: blur(10px);
    border-radius: 16px;
    border: 1px solid rgba(255, 255, 255, 0.1);
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
}

.form-header {
    text-align: center;
    margin-bottom: 32px;
}

.form-header h2 {
    margin: 0 0 8px 0;
    font-size: 28px;
    font-weight: 600;
    color: #ffffff;
}

.form-header p {
    margin: 0;
    color: #a0a0b0;
    font-size: 16px;
}

.livekit-form {
    width: 100%;
}

.livekit-form .el-form-item {
    margin-bottom: 24px;
}

.livekit-form .el-form-item__label {
    color: #c0c0d0;
    font-weight: 500;
    margin-bottom: 8px;
    font-size: 14px;
}

.livekit-input {
    width: 100%;
}

.livekit-input .el-input__inner {
    background: rgba(255, 255, 255, 0.08);
    border: 1px solid rgba(255, 255, 255, 0.15);
    border-radius: 10px;
    color: #e0e0e0;
    padding: 12px 16px;
    font-size: 16px;
    transition: all 0.3s ease;
}

.livekit-input .el-input__inner:focus {
    border-color: #4a6cf7;
    box-shadow: 0 0 0 2px rgba(74, 108, 247, 0.2);
}

.livekit-input .el-input__inner::placeholder {
    color: #6a6a7a;
}

.radio-group {
    display: flex;
    gap: 16px;
}

.custom-radio {
    margin-right: 0;
}

.custom-radio .el-radio__input.is-checked + .el-radio__label {
    color: #4a6cf7;
}

.custom-radio .el-radio__inner {
    background: rgba(255, 255, 255, 0.08);
    border: 1px solid rgba(255, 255, 255, 0.2);
}

.custom-radio .el-radio__inner::after {
    background-color: #4a6cf7;
}

.join-button {
    width: 100%;
    background: linear-gradient(135deg, #4a6cf7 0%, #6a4af7 100%);
    border: none;
    border-radius: 10px;
    padding: 14px;
    font-size: 16px;
    font-weight: 600;
    margin-top: 8px;
    transition: all 0.3s ease;
    box-shadow: 0 4px 12px rgba(74, 108, 247, 0.3);
}

.join-button:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 16px rgba(74, 108, 247, 0.4);
}

/* 会议界面样式 */
.meeting-container {
    width: calc(100vw - 40px) ;
    margin: 0 auto;
    padding: 20px;
}

/* 视频布局 */
.video-layout {
    display: flex;
    flex-direction: column;
    gap: 20px;
    height: calc(100vh - 80px);
}

/* 当有屏幕共享时的布局 */
.video-layout.screen-sharing-active {
    flex-direction: row;
    gap: 20px;
}

/* 屏幕共享区域 */
.screen-share-area {
    flex: 3;
    background: rgba(255, 255, 255, 0.05);
    backdrop-filter: blur(10px);
    border-radius: 16px;
    border: 1px solid rgba(255, 255, 255, 0.1);
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

.screen-share-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 16px 20px;
    background: rgba(0, 0, 0, 0.2);
    border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}

.screen-share-header h3 {
    margin: 0;
    font-size: 18px;
    font-weight: 600;
    color: #ffffff;
}

.sharing-user {
    color: #a0a0b0;
    font-size: 14px;
}

.screen-share-video {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
}

.screen-share-wrapper {
    width: 100%;
    height: 100%;
    max-height: 100%;
}

.screen-share-element {
    width: 100%;
    height: 100%;
    object-fit: contain;
    background: #000;
    border-radius: 8px;
}

/* 参会者区域 */
.participants-area {
    flex: 1;
    background: rgba(255, 255, 255, 0.05);
    backdrop-filter: blur(10px);
    border-radius: 16px;
    border: 1px solid rgba(255, 255, 255, 0.1);
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

.participants-area.with-screen-share {
    max-width: 400px;
}

.participants-header {
    padding: 16px 20px;
    background: rgba(0, 0, 0, 0.2);
    border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}

.participants-header h3 {
    margin: 0;
    font-size: 18px;
    font-weight: 600;
    color: #ffffff;
}

.video-grid {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 16px;
    padding: 16px;
    overflow-y: auto;
    max-height: calc(100vh - 200px); /* 为底部控制栏留出空间 */
    margin-bottom: 80px; /* 确保内容不被底部控制栏遮挡 */
}
.video-grid.grid-layout {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 16px;
    align-items: start;
}

.participant-card {
    background: rgba(255, 255, 255, 0.05);
    backdrop-filter: blur(10px);
    border-radius: 12px;
    border: 1px solid rgba(255, 255, 255, 0.1);
    overflow: hidden;
    transition: all 0.3s ease;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
    display: flex;
    flex-direction: column;
    min-height: 280px; /* 统一最小高度 */
}

.video-grid.grid-layout .video-wrapper {
    height: 200px; /* 在网格布局中也保持相同高度 */
}
.participant-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.3);
}

.local-participant {
    border: 2px solid rgba(74, 108, 247, 0.5);
}

.participant-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 12px 16px;
    background: rgba(0, 0, 0, 0.2);
    border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}

.participant-header h3 {
    margin: 0;
    font-size: 14px;
    font-weight: 600;
    color: #ffffff;
}

.status-indicator {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    color: #a0a0b0;
}

.status-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background-color: #4ade80;
}

.video-wrapper {
    position: relative;
    width: 100%;
    height: 100%; /* 固定高度 */
    overflow: hidden;
    background: #000; /* 统一背景色 */
    border-radius: 8px; 
}

.video-element {
    width: 100%;
    height: 100%;
    object-fit: cover;
    background: #000; 
}

.video-overlay {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    padding: 8px 12px;
    background: linear-gradient(transparent, rgba(0, 0, 0, 0.7));
    color: white;
    display: flex;
    justify-content: space-between;
    align-items: center;
    z-index: 2;
}

.participant-name {
    font-size: 12px;
    font-weight: 500;
}

.screen-sharing-indicator {
    font-size: 11px;
    color: #4a6cf7;
    display: flex;
    align-items: center;
    gap: 4px;
}

.video-placeholder {
    width: 100%;
    height: 100%;
    background: linear-gradient(135deg, #2a2a3a 0%, #1a1a2a 100%);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    color: #a0a0b0;
    font-size: 14px;
    position: absolute;
    top: 0;
    left: 0;
}

.video-placeholder i {
    font-size: 32px;
    margin-bottom: 8px;
    color: #4a4a5a;
}

.fixed-controls {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    background: rgba(15, 15, 26, 0.95);
    backdrop-filter: blur(20px);
    border-top: 1px solid rgba(255, 255, 255, 0.1);
    padding: 16px 20px;
    z-index: 1000;
}

.controls-container {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 16px;
    max-width: 1200px;
    margin: 0 auto;
}

.video-controls {
    display: flex;
    gap: 8px;
    padding: 12px;
    background: rgba(0, 0, 0, 0.2);
    justify-content: center;
    margin-top: auto; /* 将控制按钮推到卡片底部 */
}
.control-btn {
    border-radius: 12px;
    border: none;
    font-weight: 600;
    transition: all 0.3s ease;
    padding: 12px 24px;
    font-size: 14px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}

.control-btn:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.3);
}

.control-btn i {
    margin-right: 8px;
    font-size: 16px;
}

.leave-btn {
    background: linear-gradient(135deg, #f56c6c 0%, #e64a4a 100%);
    border: none;
}

.leave-btn:hover {
    background: linear-gradient(135deg, #e64a4a 0%, #d63030 100%);
}

/* 响应式调整 */
@media (max-width: 768px) {
    .form-container {
        margin: 20px auto;
        padding: 24px;
    }
    
    .video-layout.screen-sharing-active {
        flex-direction: column;
    }
    
    .participants-area.with-screen-share {
        max-width: 100%;
    }
    
    /* 在小屏幕上使用单列布局 */
    .video-grid.grid-layout {
        grid-template-columns: 1fr;
    }
    
    /* 移动端控制栏调整 */
    .fixed-controls {
        padding: 12px 16px;
    }
    
    .controls-container {
        gap: 8px;
        flex-wrap: wrap;
    }
    
    .control-btn {
        padding: 10px 16px;
        font-size: 12px;
        flex: 1;
        min-width: 120px;
    }
    
    .control-btn i {
        margin-right: 6px;
        font-size: 14px;
    }
}

/* 中等屏幕上的网格布局 */
@media (min-width: 769px) and (max-width: 1200px) {
    .video-grid.grid-layout {
        grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    }
}

/* 大屏幕上的网格布局 */
@media (min-width: 1201px) {
    .video-grid.grid-layout {
        grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    }
}

/* 超小屏幕调整 */
@media (max-width: 480px) {
    .controls-container {
        gap: 6px;
    }
    
    .control-btn {
        padding: 8px 12px;
        font-size: 11px;
        min-width: 100px;
    }
    
    .control-btn i {
        margin-right: 4px;
        font-size: 12px;
    }
}
</style>