import asyncio, wave, time, json, httpx, websockets, sys
import numpy as np, sounddevice as sd
import os
import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s.%(msecs)03d %(message)s', datefmt='%H:%M:%S')
API_KEY = os.getenv("VAPI_API_KEY")
ASSISTANT_ID = os.getenv("ASSISTANT_ID")
AUDIO_PATH   = "whatsapp.wav"         
times = {}
t0 = 0
async def main():
    r = httpx.post(
        "https://api.vapi.ai/call",
        headers={"Authorization": f"Bearer {API_KEY}"},
        json={"assistantId": ASSISTANT_ID,
              "transport": {"provider": "vapi.websocket"}}
    )
    ws_url = r.json()["transport"]["websocketCallUrl"]
    print(ws_url)
    greeting_done   = asyncio.Event()
    async with websockets.connect(ws_url) as ws:
        async def reader():
            stream = sd.OutputStream(
                samplerate=16000, channels=1, dtype="int16"
            )
            stream.start()
            async for raw in ws:
                if isinstance(raw, (bytes, bytearray)):
                    stream.write(np.frombuffer(raw, dtype="<i2"))
                    continue
                evt = json.loads(raw)
                logging.info(f"Event:{evt}")
                times[(evt.get("type"), evt.get("role"), evt.get("status"), evt.get("turn"))] = time.perf_counter()
                if (evt.get("type") =="speech-update"
                      and evt["role"] == "assistant" and evt["status"] == "stopped" and evt.get("turn") == 0):
                    await asyncio.sleep(0.3)
                    greeting_done.set()
                    
        async def writer():
            global t0
            await greeting_done.wait()
            with wave.open(AUDIO_PATH, "rb") as w:
                while chunk := w.readframes(1600):   # 100 ms
                    await ws.send(chunk)
                    await asyncio.sleep(0.10)
                t0 = time.perf_counter()
        await asyncio.gather(reader(), writer())
asyncio.run(main())