'use client'; import { useCallback, useEffect, useRef, useState } from 'react'; import { initializeVapi, vapiConfig } from '@/lib/vapi'; export type VapiCallStatus = 'idle' | 'connecting' | 'active' | 'ended' | 'error'; interface CallStats { durationSeconds: number; creditsUsed: number; } const formatError = (error: unknown) => { if (error instanceof Error) return error.message; if (typeof error === 'string') return error; return 'Something went wrong starting the call.'; }; export const useVapi = () => { const clientRef = useRef(null); const timerRef = useRef(null); const [status, setStatus] = useState('idle'); const [error, setError] = useState(null); const [durationSeconds, setDurationSeconds] = useState(0); const [callStats, setCallStats] = useState(null); useEffect(() => { if (status === 'active') { timerRef.current = setInterval(() => { setDurationSeconds((prev) => prev + 1); }, 1000); } else { if (timerRef.current) { clearInterval(timerRef.current); } } return () => { if (timerRef.current) { clearInterval(timerRef.current); } }; }, [status]); const startCall = useCallback(async () => { setError(null); setCallStats(null); setDurationSeconds(0); setStatus('connecting'); try { if (!clientRef.current) { clientRef.current = initializeVapi(); } const assistantId = vapiConfig.assistantId; if (!assistantId) { throw new Error('Missing NEXT_PUBLIC_VAPI_ASSISTANT_ID'); } const client = clientRef.current; const response = (await client?.start?.({ assistantId })) ?? (await client?.startCall?.({ assistantId })) ?? (await client?.call?.({ assistantId })); if (response?.id) { // Future: store call id for status lookup } setStatus('active'); } catch (err) { setError(formatError(err)); setStatus('error'); } }, []); const endCall = useCallback(async () => { try { const client = clientRef.current; await client?.stop?.(); await client?.end?.(); } catch (err) { setError(formatError(err)); } finally { setStatus('ended'); setCallStats({ durationSeconds, creditsUsed: Math.max(1, Math.round(durationSeconds / 60)), }); } }, [durationSeconds]); return { status, error, durationSeconds, callStats, startCall, endCall, }; };