
import { message } from "antd";
import SocketService from "./socket";

class WebRtc {
    private mediaStream: MediaStream | Blob | null = null;
    private pee: RTCPeerConnection | null = null;
    private ws: SocketService | null = null;
    private video: HTMLVideoElement | null = null;
    private userToId: string = "";
    async init(userId) {
        this.userToId = userId
        this.ws = SocketService.getInstance();
        this.ws.on("message", this.onMessage);

    }
    onMessage = (e: any) => {
        let msg = JSON.parse(e)
        if (!msg) {
            return console.log('failed to parse msg')
        }
        switch (msg.type) {
            case 'offer':
                let offer = msg.content.body.description;
                this.pee?.setRemoteDescription(offer)
                this.pee?.createAnswer().then(answer => {
                    this.pee?.setLocalDescription(answer)
                    this.ws?.send({
                        type: 'answer',
                        data: {
                            to: msg.content.body.from,
                            from: "admin",
                            description: { 'sdp': answer.sdp, 'type': answer.type },
                            session_id: msg.content.body.from + "-admin",
                        }
                    })
                })
                break;
            case "read":
                this.sendOffer()
                break;
            case 'candidate':
                let candidate = msg.content.body.description
                if (!candidate) {
                    return console.log('failed to parse candidate')
                }
                this.pee?.addIceCandidate(candidate)
                break;
            case "answer":
                this.pee?.setRemoteDescription(msg.content.body.description)
                break;
            case "reject":
                message.info("对方拒绝了通话邀请")
                this.close()
                break;
            case "bye":
                this.close()
                break;
        }
    }
    async createOffer() {
        const configuration = {
            iceServers: [
                {
                    urls: "stun:118.114.255.222:3478",
                    username: "admin",
                    credential: "admin123456",
                    "ttl": 86400
                },
                {
                    urls: "turn:118.114.255.222:3478",
                    username: "admin",
                    credential: "admin123456",
                    "ttl": 86400
                }
            ],
            sdpSemantics: "unified-plan",
        }
        this.gets(configuration)
    }

    async gets(configuration) {
        this.pee = new RTCPeerConnection(configuration);
        // 获取远方流添加到页面播放
        this.pee.ontrack = event => {
            const re = document.querySelector('#remoteVideo') as HTMLVideoElement;
            re.autoplay = true
            re.controls = true
            re.srcObject = event.streams[0];
            event.track.onmute = function (event) {
                re.play()
            }
            event.streams[0].onremovetrack = ({ track }) => {
                if (re.parentNode) {
                    re.parentNode.removeChild(re)
                }
            }
        };
        this.pee.onicecandidate = e => {
            if (!e.candidate) {
                return
            }
            this.ws?.send({
                type: "candidate", data: {
                    to: this.userToId,
                    from: "admin",
                    description: e.candidate,
                    media: "video",
                    session_id: this.userToId + "-admin",
                }
            })
        }
        this.ws?.send({
            type: "call",
            data: {
                to: this.userToId,
                from: "admin",
                description: "call",
                media: "video",
                session_id: this.userToId + "-admin",
            }
        })
    }
    sendOffer() {
        let that = this;
        that.pee?.createOffer().then(function (offer) {
            that.pee?.setLocalDescription(offer);
            that.ws?.send({
                type: "offer",
                data: {
                    to: that.userToId,
                    from: "admin",
                    description: offer,
                    media: "video",
                    session_id: that.userToId + "-admin",
                }
            })
        }).catch(function (error) {
            // 错误处理
            console.error(error);
        });
    }
    async getMedia() {
        try {
            this.video = document.getElementById('rtcVideo') as HTMLVideoElement;
            const stream = await navigator.mediaDevices.getUserMedia({
                video: true,
                audio: true
            });
            this.mediaStream = stream;
            stream.getTracks().forEach(track => this.pee?.addTrack(track, stream))
            if (this.video) {
                this.video.srcObject = this.mediaStream;
                this.video.autoplay = true;
            }
        } catch (error) {
            console.log(error);
        }
    }
    async calls() {
        await this.createOffer()
        await this.getMedia()
    }
    close() {
        this.video?.pause();
        this.pee?.close();
        this.ws?.send({
            type: "bye",
            data: {
                to: this.userToId,
                from: "admin",
                description: "bye",
                media: "video",
                session_id: this.userToId + "admin",
            }
        });
        (this.mediaStream as MediaStream)?.getTracks().forEach(track => track.stop());
    }
}

export const webRTC = new WebRtc()