import React, { useEffect, useState, useCallback, useRef } from 'react'; import { useTranslation } from 'react-i18next'; import { Smartphone, Loader2, CheckCircle, XCircle, ExternalLink } from 'lucide-react'; import QRCode from 'qrcode'; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { Button } from '@/components/ui/button'; import { usePezkuwi } from '@/contexts/PezkuwiContext'; import { useIsMobile } from '@/hooks/use-mobile'; const CONNECTION_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes interface WalletConnectModalProps { isOpen: boolean; onClose: () => void; } type ConnectionState = 'generating' | 'waiting' | 'connected' | 'error'; export const WalletConnectModal: React.FC = ({ isOpen, onClose }) => { const { t } = useTranslation(); const { connectWalletConnect, selectedAccount, wcPeerName } = usePezkuwi(); const isMobile = useIsMobile(); const [qrDataUrl, setQrDataUrl] = useState(''); const [wcUri, setWcUri] = useState(''); const [connectionState, setConnectionState] = useState('generating'); const [errorMsg, setErrorMsg] = useState(''); const timeoutRef = useRef | null>(null); const connectedRef = useRef(false); const clearConnectionTimeout = useCallback(() => { if (timeoutRef.current) { clearTimeout(timeoutRef.current); timeoutRef.current = null; } }, []); const startConnection = useCallback(async () => { setConnectionState('generating'); setErrorMsg(''); connectedRef.current = false; clearConnectionTimeout(); try { const uri = await connectWalletConnect(); setWcUri(uri); // Start connection timeout timeoutRef.current = setTimeout(() => { if (!connectedRef.current) { setConnectionState('error'); setErrorMsg(t('walletModal.wcTimeout', 'Connection timed out. Please try again.')); } }, CONNECTION_TIMEOUT_MS); if (isMobile) { // Mobile: open pezWallet via deep link automatically const deepLink = `pezkuwiwallet://wc?uri=${encodeURIComponent(uri)}`; window.location.href = deepLink; setConnectionState('waiting'); } else { // Desktop: generate QR code const dataUrl = await QRCode.toDataURL(uri, { width: 300, margin: 2, color: { dark: '#000000', light: '#ffffff', }, }); setQrDataUrl(dataUrl); setConnectionState('waiting'); } } catch (err) { clearConnectionTimeout(); setConnectionState('error'); setErrorMsg(err instanceof Error ? err.message : 'Connection failed'); } }, [connectWalletConnect, isMobile, clearConnectionTimeout, t]); // Listen for successful connection - registered BEFORE startConnection to avoid race useEffect(() => { if (!isOpen) return; const handleConnected = () => { connectedRef.current = true; clearConnectionTimeout(); setConnectionState('connected'); setTimeout(() => onClose(), 1500); }; window.addEventListener('walletconnect_connected', handleConnected); // Start connection after listener is registered startConnection(); return () => { window.removeEventListener('walletconnect_connected', handleConnected); clearConnectionTimeout(); setQrDataUrl(''); setWcUri(''); setConnectionState('generating'); connectedRef.current = false; }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [isOpen]); const handleOpenPezWallet = () => { if (wcUri) { window.location.href = `pezkuwiwallet://wc?uri=${encodeURIComponent(wcUri)}`; } }; return ( WalletConnect {isMobile ? t('walletModal.wcOpenWallet', 'Connect with pezWallet app') : t('walletModal.wcScanQR', 'Scan with pezWallet to connect')}
{/* Generating state */} {connectionState === 'generating' && (

{t('walletModal.wcGenerating', 'Generating connection...')}

)} {/* Waiting state */} {connectionState === 'waiting' && ( <> {isMobile ? ( // Mobile: deep link button

{t('walletModal.wcWaitingMobile', 'Approve the connection in pezWallet')}

{t('walletModal.wcWaiting', 'Waiting for wallet to connect...')}

{t('walletModal.wcInstallHint', "Don't have pezWallet? It will be available on Play Store soon.")}

) : ( // Desktop: QR code <> {qrDataUrl && (
WalletConnect QR Code
)}
{t('walletModal.wcWaiting', 'Waiting for wallet to connect...')}

{t('walletModal.wcInstructions', 'Open pezWallet app → Settings → WalletConnect → Scan QR code')}

)} )} {/* Connected state */} {connectionState === 'connected' && (

{t('walletModal.wcConnected', 'Connected!')}

{wcPeerName && (

{wcPeerName}

)} {selectedAccount && ( {selectedAccount.address.slice(0, 8)}...{selectedAccount.address.slice(-6)} )}
)} {/* Error state */} {connectionState === 'error' && (

{errorMsg}

)}
); };