import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useCallback, useEffect, useRef, useState } from "react";
import { serverRequest } from "../utils";
import loading_icon from '../assets/images/loading.gif';
import ai_icon from '../assets/images/ai.png';
import stop_icon from '../assets/images/stop.png';
import logo from '../assets/images/logo-new.png';
const defaultRequest = {
    requestStatus: "not_initiated",
    responseStatus: "not_recieved",
    haveAnIssue: false,
    issue: "",
    data: null
};
const AvaVoice = () => {
    // const [tokenRequest,setTokenRequest]=useState<Request<any>>()
    const [status, setStatus] = useState("listening");
    const [connectionRequest, setConnectionRequest] = useState();
    const ephemeralToken = useRef(null);
    const pcRef = useRef(null);
    const localStreamRef = useRef(null);
    const remoteAudioRef = useRef(null);
    const getToken = useCallback(async () => {
        let query = `query Query($agentId: ID!) {
            ephemeralToken(id: $agentId)
          }`;
        let res = await serverRequest({
            url: "https://app.avakado.ai/graphql/",
            reqType: "POST",
            headers: { 'Content-Type': 'application/json' },
            accessToken: localStorage.getItem("AccessToken") ?? "",
            body: {
                query,
                variables: {
                    agentId: "68da93cd0c3694119ebdc4ac"
                },
            },
            handleError: true
        });
        return {
            success: res?.data?.ephemeralToken ? true : false,
            data: res?.data?.ephemeralToken?.value
        };
    }, []);
    const startSession = async () => {
        setConnectionRequest({ ...defaultRequest, requestStatus: "initiated" });
        const res = await getToken();
        setConnectionRequest({ ...defaultRequest, requestStatus: "initiated", responseStatus: "recieved", haveAnIssue: res.data ? false : true });
        ephemeralToken.current = res?.data;
        if (res.success) {
            pcRef.current = new RTCPeerConnection();
            // Set up to play remote audio from the model
            remoteAudioRef.current = document.createElement("audio");
            remoteAudioRef.current.autoplay = true;
            pcRef.current.ontrack = (e) => (remoteAudioRef.current ? remoteAudioRef.current.srcObject = e.streams[0] : null);
            // Add local audio track for microphone input in the browser
            localStreamRef.current = await navigator.mediaDevices.getUserMedia({
                audio: true,
            });
            pcRef.current.addTrack(localStreamRef.current.getTracks()[0]);
            // Set up data channel for sending and receiving events
            const dc = pcRef.current.createDataChannel("oai-events");
            // Start the session using the Session Description Protocol (SDP)
            const offer = await pcRef.current.createOffer();
            await pcRef.current.setLocalDescription(offer);
            const sdpResponse = await fetch("https://api.openai.com/v1/realtime/calls", {
                method: "POST",
                body: offer.sdp,
                headers: {
                    Authorization: `Bearer ${ephemeralToken.current}`,
                    "Content-Type": "application/sdp",
                },
            });
            const answer = {
                type: "answer",
                sdp: await sdpResponse.text(),
            };
            await pcRef.current.setRemoteDescription(answer);
        }
    };
    const stopSession = useCallback(() => {
        pcRef.current?.close();
        pcRef.current = null;
        localStreamRef.current?.getTracks().forEach((track) => track.stop());
        localStreamRef.current = null;
    }, []);
    useEffect(() => {
        startSession();
        return () => stopSession();
    }, []);
    return (_jsx("div", { className: "fullwidth padding flexbox-row border", children: connectionRequest?.requestStatus == "initiated" && connectionRequest.responseStatus == "recieved"
            ?
                connectionRequest.haveAnIssue
                    ?
                        _jsx("span", { className: 'small-text-l-regular', children: "Something went wrong" })
                    :
                        _jsxs("div", { className: "flexbox-row fullwidth gap flexbox-center", children: [_jsxs("div", { className: "flexbox-row flexbox-row-fit gap", children: [_jsx("img", { className: "img-fit icon-default", src: logo }), _jsx("span", { className: 'small-text-l-regular', children: "You may speak with me now" })] }), status == "idle"
                                    ?
                                        _jsx("img", { onClick: () => startSession().then(() => setStatus("listening")), className: "img-fit icon-default", src: ai_icon })
                                    :
                                        _jsx("img", { onClick: () => { stopSession(); setStatus("idle"); }, className: "img-fit icon-default", src: stop_icon })] })
            :
                _jsxs("div", { className: "flexbox-row gap flexbox-center", children: [_jsx("span", { className: 'small-text-l-regular', children: "Getting everything ready for you! Hang tight\u2026!" }), _jsx("img", { className: "img-fit icon-default", src: loading_icon })] }) })
    // <div className={'avamodule-app-wrapper-page'}>
    // {
    //     connectionRequest?.requestStatus=="initiated" && connectionRequest.responseStatus=="recieved" 
    //     ?
    //      connectionRequest.haveAnIssue
    //      ?
    //      <span>Something went wrong</span>
    //      :
    //      <VoiceScreen/>
    //     :
    //     <div className='avamodule-setup-wrapper'>
    //         {/* <img src={loading_ava_gif} className='avamodule-ava-loader'/> */}
    //         <div style={{display:'flex',flexDirection:"row",alignItems:'center',gap:"10px"}}>
    //             <span className='avamodule-hi'>Getting everything ready for you! Hang tight…!</span>
    //         </div>
    //     </div>
    // }
    // </div>
    );
};
const VoiceScreen = () => {
    const [status, setStatus] = useState("listening");
    const voiceAmplitude = useMicVolume();
    console.log("Voice Amplitude", voiceAmplitude);
    return (_jsx("div", { className: 'avamodule-ava-wrapper', children: _jsxs("div", { className: 'avamodule-ava-subwrapper', children: [_jsx("span", { children: "You can speak now!" }), _jsx("span", { children: voiceAmplitude })] }) }));
};
export function useMicVolume() {
    const [volume, setVolume] = useState(0);
    const raf = useRef(0);
    useEffect(() => {
        let audioCtx, analyser, dataArray, source;
        const init = async () => {
            const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
            const AudioContextClass = window.AudioContext || window.webkitAudioContext;
            const audioCtx = new AudioContextClass();
            source = audioCtx.createMediaStreamSource(stream);
            analyser = audioCtx.createAnalyser();
            analyser.fftSize = 256;
            dataArray = new Uint8Array(analyser.frequencyBinCount);
            source.connect(analyser);
            const loop = () => {
                analyser.getByteFrequencyData(dataArray);
                const avg = dataArray.reduce((a, b) => a + b) / dataArray.length;
                setVolume(avg / 255);
                raf.current = requestAnimationFrame(loop);
            };
            loop();
        };
        init();
        return () => cancelAnimationFrame(raf.current);
    }, []);
    return volume; // value between 0 and 1
}
export default AvaVoice;
//# sourceMappingURL=AvaVoice.js.map