'use client'
/* eslint-disable @typescript-eslint/no-explicit-any */
import React, { useEffect, useRef, useState } from 'react'

// https://www.baeldung.com/webrtc
export default function WebRTComponent() {
    const WSRef = useRef<WebSocket>(undefined)
    const videoRef1 = useRef<HTMLVideoElement | null>(null)
    const localStreamRef1 = useRef<MediaStream | null>(null)
    const [offers, setOffers] = useState<RTCSessionDescriptionInit[]>([])
    const peerConnection = useRef<RTCPeerConnection>(undefined)
    const dataChannel = useRef<RTCDataChannel>(undefined)

    const send = (message: any) =>
        WSRef.current!.send(JSON.stringify(message));

    const onWSMessage = async (message: MessageEvent) => {
        console.log(`Received : `, message.data)
        const parsed = JSON.parse(message.data)
        switch (parsed.type) {
            case 'Offers':
                // setOffers(o => parsed.data as RTCSessionDescriptionInit[])
                console.log('parsed.data',parsed.data)
                await acceptOffer(parsed.data)
                // await acceptOffer(parsed.data[parsed.data.length - 1])
                break;
            case 'Answers':
                console.log(`Answers:`,parsed.data)
                peerConnection.current!
                    .setRemoteDescription(new RTCSessionDescription({ ...parsed.data.sdp }))
                    .catch((err) => console.error(err));    // 
                break;
        }
    }

    const handleConectWS = async () => {
        WSRef.current = new WebSocket('ws://localhost:4000/socket');
        WSRef.current.onopen = async function (event) {
            peerConnection.current = new RTCPeerConnection(undefined) // <-- Later add Stun servers as backup
            await setup()
        }
        WSRef.current.onmessage = async (ev) => onWSMessage(ev)

    }


    // 1. Get user media
    const Start = async () => {
        console.log('Requesting local stream');
        const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: true });
        console.log(`Start Local Stream`)
        if (!videoRef1.current) console.error(`Video not yet available`)
        videoRef1.current!.srcObject = stream
        localStreamRef1.current = stream;
        console.log(`Set local stream`)
    }

    const joinServer = async () => {
        const configuration = {};
        console.log('RTCPeerConnection configuration:', configuration);
        peerConnection.current = new RTCPeerConnection(configuration)

        peerConnection.current.createOffer().then(offer => {
            send({
                type: 'OfferSDP',
                data: offer
            })
            peerConnection.current?.setLocalDescription(offer)
        })

        peerConnection.current.onicecandidate = function (event) {
            console.log(`Received ICE Candidate :`, event)
        }
        // pc.addEventListener('icecandidate', e => console.log(`icecandidate`, pc, e));
    }

    const acceptOffer = async (recv: any) => {
        console.log(`acceptOffer`, recv)
        peerConnection.current!.setRemoteDescription(new RTCSessionDescription(recv))
            .then(() => peerConnection.current!.createAnswer())
            .then((answer) => peerConnection.current!.setLocalDescription(answer))
            .then(() => send({ type: 'AnswerSDP', data: { sdp: peerConnection.current!.localDescription } }))
            .catch((err) => console.error('Failed to handle offer', err));

    }


    // 2. Make call
    const makeCall = () => {
        // Get available streams
        const videoTracks = localStreamRef1.current!.getVideoTracks();
        const audioTracks = localStreamRef1.current!.getAudioTracks();

        if (videoTracks.length > 0) {
            console.log(`Using video device: ${videoTracks[0].label}`);
        }
        if (audioTracks.length > 0) {
            console.log(`Using audio device: ${audioTracks[0].label}`);
        }
        const configuration = {};

        // 3. Start WebRTC
        console.log('RTCPeerConnection configuration:', configuration);

        // const pc1 = new RTCPeerConnection(configuration);
        // console.log('Created local peer connection object pc1');
        // pc1.addEventListener('icecandidate', e => onIceCandidate(pc1, e));
        // const pc2 = new RTCPeerConnection(configuration);
        // console.log('Created remote peer connection object pc2');
        // pc2.addEventListener('icecandidate', e => onIceCandidate(pc2, e));
        // pc1.addEventListener('iceconnectionstatechange', e => onIceStateChange(pc1, e));
        // pc2.addEventListener('iceconnectionstatechange', e => onIceStateChange(pc2, e));
        // pc2.addEventListener('track', gotRemoteStream);

    }

    // 4. On ICE Candidate
    // const onIceCandidate = async (peerConnection: RTCPeerConnection, e: Event) => {
    //     try {
    //         await(getOtherPc(pc).addIceCandidate(event.candidate));
    //         onAddIceCandidateSuccess(pc);
    //     } catch (e) {
    //         onAddIceCandidateError(pc, e);
    //     }
    //     console.log(`${getName(pc)} ICE candidate:\n${event.candidate ? event.candidate.candidate : '(null)'}`);
    // }

    async function setup() {
        // 1. Get local media stream
        // await Start()
        // 2. Join WS Server
        const handleJoin = () => {
            send({ type: 'Join' })
        }
        handleJoin()
    }
    useEffect(() => {
        handleConectWS()
        // const load = async () => {
        //     WSRef.current.onmessage = (ev) => {
        //         // '{"event":"candidate","data":{"candidate":"candidate:1041930304 1 udp 2113937151 b7178aee-2d1d-4762-b709-1b25cf436cb5.local 61551 typ host generation 0 ufrag bEe6 network-cost 999","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"bEe6"}}'
        //         const data = JSON.parse(ev.data)
        //         // console.log(`Recevied WS : `, Object.keys(data))
        //         console.log(`Recevied WS : `, data.event)
        //         switch (data.event) {
        //             case 'offer':
        //                 console.log(`Check foreign offer`, data.data)
        //                 // Need to handle answer here
        //                 peerConnection.current.setRemoteDescription(new RTCSessionDescription({ sdp: data.data.sdp, type: 'offer' }))
        //                     .then(() => peerConnection.current.createAnswer())
        //                     .then((answer) => peerConnection.current.setLocalDescription(answer))
        //                     .then(() => send({ event: 'answer', data: { sdp: peerConnection.current.localDescription } }))
        //                     .catch((err) => console.error('Failed to handle offer', err));
        //                 break;
        //             case 'answer':
        //                 console.log(`Check foreign answer`, data.data)
        //                 peerConnection.current.setRemoteDescription(new RTCSessionDescription({ ...data.data.sdp })).catch((err) => console.error(err));    // 
        //                 break;
        //             case 'candidate':
        //                 console.log(`Check foreign candidate`, { ...data.data })
        //                 if (data.data.candidate) {
        //                     peerConnection.current.addIceCandidate(new RTCIceCandidate({ ...data.data })).catch((err) => console.warn('Bad candidate', err));
        //                 }

        //                 break;
        //         }
        //     }
        // }
        // load()
    }, [])



    return (
        <div>WebRTCChat
            <video ref={videoRef1} playsInline autoPlay muted className='border w-96 h-96 bg-red-100' />
            <button onClick={() => Start()}>Start</button>
            <button onClick={() => joinServer()}>Join</button>
            <button onClick={() => makeCall()}>Make Call</button>
            <button onClick={() => {
                { alert('SEND'); dataChannel.current!.send("message"); }
            }} >Send</button>

            <div>
                <b>Offers</b>
                {/* <div className='flex flex-col'>
                    {offers.map((o, i) => <div key={`Offer-${i}`}>
                        {JSON.stringify(o.sdp)}
                        <button onClick={() => {
                            acceptOffer(o.sdp ?? "")
                        }}>Connect</button>
                    </div>)}
                </div> */}
            </div>
        </div>
    )
}
