<template>

    <div class="video-user-container">
        <!-- 远程视频 -->
        <video autoplay class="remote-video" ref="remoteVideoRef"></video>
        <!-- 本地视频 -->
        <video autoplay class="local-video" ref="localVideoRef"></video>

        <!-- 挂断通话 -->
        <svg class="leave-btn icon" @click="leave()" t="1739368256646" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3572" width="40" height="40"><path d="M0 512a512 512 0 1 0 1024 0A512 512 0 1 0 0 512z" fill="#F75855" p-id="3573"></path><path d="M502.24 414.2c78.71 2.19 155.93 11.61 225.57 52.4 46.19 27.06 59.2 52.68 52.6 96.3-4.54 30-21.84 44.86-51.68 46.7-58.81 3.61-84.16-15.87-90.44-72.24-2.11-18.94-14-26.82-29.03-30.22-63.34-14.31-127.14-13.52-190.84-2.28-20.32 3.59-29.81 17.2-28.68 37.58 2.13 38.35-20.49 54.18-54.04 60.39-41.35 7.65-70-3.01-84.89-31.53-15.68-30.04-10.26-65.69 14.51-90.09 28.34-27.91 64.05-42.34 101.72-51.48 44.29-10.76 89.33-17.04 135.2-15.53z" fill="#FEFEFE" p-id="3574"></path></svg>
    </div>

</template>

<script>
  import axios from 'axios';
  import { inject, defineEmits, defineComponent, ref, onMounted, onUnmounted, watch, onBeforeUnmount } from 'vue';
  import { message } from 'ant-design-vue';
  export default defineComponent({
    props: {
        openVideo: Boolean,
        selectChatUserRef: Object
    },
    setup(props, { emit }) {
        const socket = ref(null);
        const messageQueue = ref([]); // 存储未发送的消息队列
        const isConnected = ref(false);
        const loginUser = ref(inject('loginUser'));
        // 反转下角色，由接听人来发offer信息
        const offerUser = ref(props.openVideo);
        const selectChatUser = ref(props.selectChatUserRef);
        const reconnectInterval = ref(5000); // 重连间隔时间，单位：毫秒
        const heartbeatInterval = ref(30000); // 心跳间隔时间，单位：毫秒
        // 本地音视频流
        const remoteVideoRef = ref(null)
        const localVideoRef = ref(null)
        const localStream = ref(null)
        // 远程音视频流
        const remoteStream = ref(null)
        // 配置ICE Server（用于网络穿透）
        const iceServerConfiguration = {
            "iceServers": [
                {
                    "urls": "stun:stun.l.google.com:19302"
                }
            ]
        }

        const peerConn = ref(null);
        // 修改点 1：使用标准的 RTCPeerConnection
        const PeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
        // 修改点 2：重构初始化本地流的逻辑
        const initLocalStream = async () => {
            if (peerConn.value == null && !offerUser.value) {        
                // 作为呼叫方呼叫
                sendObjMessage({
                    type: "call",
                    userId: loginUser.value.userId,
                    targetUserId: selectChatUser.value.userId
                });
            }
            try {
                // 获取本地媒体流
                localStream.value = await navigator.mediaDevices.getUserMedia({
                    video: true,
                    audio: true
                });
                localVideoRef.value.srcObject = localStream.value;
                // 初始化 PeerConnection
                peerConn.value = new PeerConnection(iceServerConfiguration);
                // 添加本地轨道（替代已废弃的 addStream）
                localStream.value.getTracks().forEach(track => {
                    peerConn.value.addTrack(track, localStream.value);
                });
                // 修改点 3：使用现代 ontrack 事件监听
                peerConn.value.ontrack = (event) => {
                    if (event.streams && event.streams.length > 0) {
                        remoteStream.value = event.streams[0];
                        remoteVideoRef.value.srcObject = remoteStream.value;
                    }
                };
                // ICE 候选处理
                peerConn.value.onicecandidate = (event) => {
                    if (event.candidate) {
                        sendObjMessage({
                            type: "candidate",
                            candidate: event.candidate,
                            userId: loginUser.value.userId,
                            targetUserId: selectChatUser.value.userId
                        });
                    }
                };
                // 创建并发送 Offer
                if (offerUser.value) {
                    const offer = await peerConn.value.createOffer();
                    await peerConn.value.setLocalDescription(offer);
                    sendObjMessage({
                        type: "offer",
                        offer: offer,
                        userId: loginUser.value.userId,
                        targetUserId: selectChatUser.value.userId
                    });
                }
            } catch (error) {
                console.error('初始化本地流失败:', error);
            }
        };

        // 5：完善处理 Offer 的逻辑
        const handleOffer = async (offer) => {
            try {
                if (!peerConn.value) {
                    // 初始化接收方的 PeerConnection
                    peerConn.value = new PeerConnection(iceServerConfiguration);
                    // 获取本地媒体流（接收方也需要本地流）
                    const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
                    localVideoRef.value.srcObject = stream;
                    stream.getTracks().forEach(track => {
                        peerConn.value.addTrack(track, stream);
                    });
                    // 设置远程流监听
                    peerConn.value.ontrack = (event) => {
                        if (event.streams && event.streams.length > 0) {
                            remoteStream.value = event.streams[0];
                            remoteVideoRef.value.srcObject = remoteStream.value;
                        }
                    };
                    // ICE 候选处理
                    peerConn.value.onicecandidate = (event) => {
                        if (event.candidate) {
                            sendObjMessage({
                                type: "candidate",
                                candidate: event.candidate,
                                userId: loginUser.value.userId,
                                targetUserId: selectChatUser.value.userId
                            });
                        }
                    };
                }
                await peerConn.value.setRemoteDescription(new RTCSessionDescription(offer));
                const answer = await peerConn.value.createAnswer();
                await peerConn.value.setLocalDescription(answer);
                sendObjMessage({
                    type: "answer",
                    answer: answer,
                    userId: loginUser.value.userId,
                    targetUserId: selectChatUser.value.userId
                });
            } catch (error) {
                console.error("处理 Offer 失败:", error);
            }
        };

        // 完善处理 Answer 的逻辑
        const handleAnswer = async (answer) => {
            try {
                if (!peerConn.value) {
                    console.error("PeerConnection 未初始化");
                    return;
                }
                await peerConn.value.setRemoteDescription(new RTCSessionDescription(answer));
            } catch (error) {
                console.error("处理 Answer 失败:", error);
            }
        };

        const handleCandidate = async (candidate) => {
            try {
                if (!peerConn.value) {
                    console.error("PeerConnection 未初始化");
                    return;
                }
                if (peerConn.value.iceConnectionState === 'closed') {
                    console.error("PeerConnection 已关闭，无法添加 ICE 候选");
                    return;
                }
                if (!candidate || typeof candidate !== 'object' || !candidate.candidate || !candidate.sdpMid) {
                    console.error("Invalid ICE candidate:", candidate);
                    return;
                }
                await peerConn.value.addIceCandidate(candidate);
                console.log("成功添加 ICE 候选");
            } catch (error) {
                console.error("处理 ICE 候选失败:", error);
            }
        };
    
        const connectWebSocket = () => {
            
            socket.value = new WebSocket(`/connect-service/ws/p2p/video/PC_WEB_CHAT/` + loginUser.value.userId);
            socket.value.onopen = () => {
                console.log('WebSocket 已连接');
                isConnected.value = true;
                // 发送队列中的消息
                messageQueue.value.forEach(message => socket.value.send(message));
                messageQueue.value = [];
                startHeartbeat();
                // 调起本地摄像头，初始化音视频流
                initLocalStream();
            };

            socket.value.onmessage = (event) => {
                console.log('收到WS消息:', event.data);
                const messageData = JSON.parse(event.data);
                switch(messageData.type) {
                    case "offer": 
                        handleOffer(messageData.offer);
                        break;
                    case "answer": 
                        handleAnswer(messageData.answer);
                        break;
                    case "candidate" :
                        handleCandidate(messageData.candidate);
                        break;
                    case "leave" :
                        handleLeave(messageData.sender);
                    break;
                }
            };

            socket.value.onerror = (error) => {
                console.error('WebSocket 错误:', error);
                isConnected.value = false;
                // 关闭当前连接
                socket.value.close();
                // 尝试重连
                setTimeout(connectWebSocket, reconnectInterval.value);
            };

            socket.value.onclose = () => {
                console.log('WebSocket 已关闭');
                isConnected.value = false;
                // 尝试重连
                setTimeout(connectWebSocket, reconnectInterval.value);
            };
        };

        const startHeartbeat = () => {
            const heartbeat = () => {
                if (isConnected.value) {
                socket.value.send('ping'); // 发送心跳包
                }
            };
            setInterval(heartbeat, heartbeatInterval.value);
        };
        
        // 链接ws
        connectWebSocket();


        const sendObjMessage = (obj) => {
            sendMessage(JSON.stringify(obj))
        }
        const sendMessage = (message) => {
            if (isConnected.value) {
                socket.value.send(message);
            } else {
                messageQueue.value.push(message);
            }
        };
        
        const cleanup = () => {
             // WebSocket 清理
            if (socket.value) {
                try {
                if ([WebSocket.OPEN, WebSocket.CONNECTING].includes(socket.value.readyState)) {
                    socket.value.close()
                }
                } catch (err) {
                    console.error('关闭 WebSocket 失败:', err)
                } finally {
                    socket.value = null
                }
            }
            // WebRTC 清理
            if (peerConn.value) {
                try {
                    peerConn.value.close()
                } catch (err) {
                    console.error('关闭 PeerConnection 失败:', err)
                } finally {
                    peerConn.value = null
                }
            }
            // 媒体流清理 (关键补充)
            if (localStream.value) {
                localStream.value.getTracks().forEach(track => {
                    track.stop() // 必须停止每个媒体轨道
                })
                localStream.value = null
            }
            if (remoteStream.value) {
                remoteStream.value.getTracks().forEach(track => {
                    track.stop() // 必须停止每个媒体轨道
                })
                remoteStream.value = null
            }
            // 发送终止信令 (重要)
            // TODO
        }

        // 处理用户挂断场景
        const handleLeave = (sender) => {
            message.info("对方已挂断");
            cleanup();
            // 触发关闭事件
            emit('close', 'close');
        }

        const leave = () => {
            // 通知远程用户对方已下线
            sendObjMessage({
                type: "leave",
                userId: loginUser.value.userId,
                targetUserId: selectChatUser.value.userId
            });
            cleanup();
            // 一对一音视频当前客户端挂断通话
            // 触发关闭事件
            emit('close', 'close');
        }

        onBeforeUnmount(() => {
            cleanup();
        }) ;
        onMounted(() => {
        
        });
        onUnmounted(() => {
       
        });
      
      return {
        selectChatUser,
        localVideoRef,
        remoteVideoRef,
        initLocalStream,
        handleOffer,
        handleAnswer,
        handleCandidate,
        cleanup,
        leave,
        handleLeave
      };
    }
  });

</script>

<style>
    .video-user-container {
        position: absolute;
        top: 50px;
        left: 0px;
        width: 100%;
        height: 530px;
        background-color: black;
    }
    .remote-video {
        position: absolute;
        right: 20px;
        top: 20px;
        width: 500px;
        height: 380px;
    }
    .local-video {
        position: absolute;
        left: 20px;
        top: 20px;
        width: 500px;
        height: 380px;
    }
    .video-title {
        position: absolute;
        left: 10px;
        top: 15px;
        font-size: 15px;
        color: white;
    }
    .leave-btn {
        position: absolute;
        left: 48%;
        bottom: 40px;
        border: 2px solid rgb(239, 133, 133);
        border-radius: 100px;
    }
</style>