"use client" import { useState, useEffect, useCallback } from "react" import { Phone, X, Copy, MessageSquare } from "lucide-react" import { getSupabase } from "@/lib/supabase" import { useWebRTCCall } from "@/hooks/useWebRTCCall" interface Contact { id: string name: string phone: string avatar_url: string | null } interface VoiceCallModalProps { open: boolean onClose: () => void } function formatPhoneForWhatsApp(phone: string): string { const digits = phone.replace(/[^0-9]/g, "") if (!digits) return "" if (digits.startsWith("27")) return digits if (digits.startsWith("0")) return "27" + digits.slice(1) return digits } export default function VoiceCallModal({ open, onClose }: VoiceCallModalProps) { const [contacts, setContacts] = useState([]) const [contactsLoading, setContactsLoading] = useState(false) const [contactsError, setContactsError] = useState(false) const [searchQuery, setSearchQuery] = useState("") const [phoneNumber, setPhoneNumber] = useState("") const [phoneError, setPhoneError] = useState(false) const [callLink, setCallLink] = useState(null) const [shareSent, setShareSent] = useState(false) const [shareError, setShareError] = useState(null) const [targetPhone, setTargetPhone] = useState("") const [showWaUrl, setShowWaUrl] = useState(null) const { createRoom } = useWebRTCCall() const handleCall = useCallback((phone?: string) => { setShareSent(false) setShareError(null) const { roomId, link } = createRoom() setCallLink(link) setTargetPhone(phone || "") console.log("[call] room created, roomId:", roomId) console.log("[call] join link:", link) console.log("[call] target phone:", phone || "none") }, [createRoom]) const copyLink = useCallback(async () => { if (!callLink) return try { await navigator.clipboard.writeText(callLink) setShareSent(true) setShareError(null) console.log("[share] link copied") } catch { setShareError("Failed to copy URL") console.error("[share] copy failed") } }, [callLink]) const sendWhatsApp = useCallback(() => { if (!callLink) return const originalPhone = targetPhone const formattedPhone = formatPhoneForWhatsApp(originalPhone) const generatedCallLink = callLink console.log("[wa] original phone:", originalPhone) console.log("[wa] formatted phone:", formattedPhone) console.log("[wa] call link:", generatedCallLink) if (!formattedPhone) { setShareError("Invalid phone number.") console.error("[wa] invalid phone number") return } const msg = encodeURIComponent(`Hi! Join me on this link so we can start our call:\n\n${generatedCallLink}`) const waUrl = `https://wa.me/${formattedPhone}?text=${msg}` console.log("[wa] WhatsApp URL:", waUrl) setShowWaUrl(waUrl) const w = window.open(waUrl, "_blank") if (!w || w.closed) { setShareError("Could not open WhatsApp. Please check your browser allows popups.") console.error("[wa] failed: window.open returned null or closed") } else { setShareSent(true) setShareError(null) console.log("[wa] success: WhatsApp opened") } }, [callLink, targetPhone]) useEffect(() => { if (!open) { setSearchQuery("") setPhoneNumber("") setPhoneError(false) setCallLink(null) setShareSent(false) setShareError(null) setTargetPhone("") setShowWaUrl(null) } }, [open]) const FALLBACK_CONTACTS: Contact[] = [ { id: "fallback-dillen", name: "Dillen", phone: "0799158142", avatar_url: null }, { id: "fallback-ewan", name: "Ewan", phone: "0845172665", avatar_url: null }, { id: "fallback-caitlin", name: "Caitlin", phone: "0612729281", avatar_url: null }, ] useEffect(() => { if (!open) return const fetchContacts = async () => { setContactsLoading(true) setContactsError(false) try { const sb = getSupabase() const { data, error } = await sb .from("contacts") .select("id, name, phone, avatar_url") .order("name", { ascending: true }) if (error) throw error setContacts([...(data || []), ...FALLBACK_CONTACTS]) } catch { setContacts(FALLBACK_CONTACTS) } finally { setContactsLoading(false) } } fetchContacts() }, [open]) useEffect(() => { if (!open) return const handleKeyDown = (e: KeyboardEvent) => { if (e.key === "Escape") onClose() } document.addEventListener("keydown", handleKeyDown) return () => document.removeEventListener("keydown", handleKeyDown) }, [open, onClose]) const filteredContacts = contacts.filter( (c) => c.name.toLowerCase().includes(searchQuery.toLowerCase()) || c.phone.toLowerCase().includes(searchQuery.toLowerCase()), ) if (!open) return null return (
{ if (e.target === e.currentTarget) onClose() }} >
{callLink ? ( shareSent ? ( <>

Call link copied.

Waiting for participant

The recipient must receive and open the call link.

{callLink}
Open Call ) : ( <>

Choose how to notify this person

Select a method to send the call link

{callLink}
{showWaUrl && (
{showWaUrl}
)}
{shareError && (

{shareError}

)} ) ) : ( <>

Start a Call

Search contacts or dial a number

CONTACTS

setSearchQuery(e.target.value)} placeholder="Search contacts..." className="bg-[#F5F5F5] dark:bg-[#1A1A1A] border border-[#E0E0E0] dark:border-[#333333] text-[#111111] dark:text-white placeholder-[#AAAAAA] dark:placeholder-[#555555] rounded-xl px-4 py-2.5 text-sm w-full mb-3 outline-none transition-colors focus:border-[#CC0000] dark:focus:border-[#FF4444]" />
{contactsLoading && (

Loading contacts...

)} {contactsError && (

Could not load contacts

)} {!contactsLoading && !contactsError && filteredContacts.length === 0 && (

No contacts found

)} {!contactsLoading && !contactsError && filteredContacts.map((contact) => (
{contact.avatar_url ? ( {contact.name} ) : ( contact.name.charAt(0).toUpperCase() )}

{contact.name}

{contact.phone}

))}

OR

DIAL A NUMBER

{ setPhoneNumber(e.target.value); setPhoneError(false) }} placeholder="+27 000 000 0000" className="bg-[#F5F5F5] dark:bg-[#1A1A1A] border border-[#E0E0E0] dark:border-[#333333] text-[#111111] dark:text-white placeholder-[#AAAAAA] dark:placeholder-[#555555] rounded-xl px-4 py-2.5 text-sm w-full outline-none transition-colors focus:border-[#CC0000] dark:focus:border-[#FF4444]" /> {phoneError && (

Please enter a phone number

)} )}
) }