import { useState, useEffect, useRef } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import { Button } from '../ui/button'; import { Badge } from '../ui/badge'; import { Textarea } from '../ui/textarea'; import { Video, VideoOff, Mic, MicOff, PhoneOff, MessageSquare, ClipboardEdit, Save, Wifi, AlertTriangle, Clock, CheckCircle2, XCircle, } from 'lucide-react'; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from '../ui/dialog'; import { Label } from '../ui/label'; import { useAuth } from '../../lib/authContext'; import { useWebRTC } from '../../hooks/useWebRTC'; import adminApi from '../../lib/api/adminApi'; import { toast } from 'sonner'; export function InterviewSession() { const { sheikhId } = useParams<{ sheikhId: string }>(); const navigate = useNavigate(); const { user } = useAuth(); // Use "interview-{sheikhId}" as the WebRTC room ID const roomId = `interview-${sheikhId ?? 'unknown'}`; const [isVideoOn, setIsVideoOn] = useState(true); const [isAudioOn, setIsAudioOn] = useState(true); const [sessionTime, setSessionTime] = useState(0); const [newMessage, setNewMessage] = useState(''); const [showChat, setShowChat] = useState(false); const [showNotes, setShowNotes] = useState(false); const [notes, setNotes] = useState(''); const [isSavingNotes, setIsSavingNotes] = useState(false); const [lastSavedNotes, setLastSavedNotes] = useState(''); // Post-interview decision dialog const [showDecision, setShowDecision] = useState(false); const [decisionType, setDecisionType] = useState<'approve' | 'reject' | null>(null); const [rejectionReason, setRejectionReason] = useState(''); const [processing, setProcessing] = useState(false); const localVideoRef = useRef(null); const remoteVideoRef = useRef(null); const { localStream, remoteStream, isConnected, messages, sendChatMessage, toggleVideo, toggleAudio, connectionQuality, } = useWebRTC(roomId, user?.id ?? 'admin'); useEffect(() => { if (localVideoRef.current && localStream) localVideoRef.current.srcObject = localStream; }, [localStream]); useEffect(() => { if (remoteVideoRef.current && remoteStream) { remoteVideoRef.current.srcObject = remoteStream; } }, [remoteStream]); // Session timer useEffect(() => { const timer = setInterval(() => setSessionTime(prev => prev + 1), 1000); return () => clearInterval(timer); }, []); const formatTime = (seconds: number) => { const h = Math.floor(seconds / 3600); const m = Math.floor((seconds % 3600) / 60); const s = seconds % 60; return `${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`; }; const handleSendMessage = () => { if (newMessage.trim()) { sendChatMessage(newMessage); setNewMessage(''); } }; const handleSaveNotes = async (isAutoSave = false) => { if (notes === lastSavedNotes) return; if (!isAutoSave) setIsSavingNotes(true); try { // حفظ الملاحظات على السيرفر await adminApi.saveInterviewNotes(sheikhId, notes); setLastSavedNotes(notes); if (!isAutoSave) toast.success('Notes saved successfully'); } catch (error) { if (!isAutoSave) toast.error('Failed to save notes'); } finally { if (!isAutoSave) setIsSavingNotes(false); } }; // const handleSaveNotes = async (isAutoSave = false) => { // if (notes === lastSavedNotes) return; // if (!isAutoSave) setIsSavingNotes(true); // // Notes are local for now — just mark as saved // setLastSavedNotes(notes); // if (!isAutoSave) setIsSavingNotes(false); // }; // Auto-save notes every 60s useEffect(() => { const timer = setInterval(() => handleSaveNotes(true), 60000); return () => clearInterval(timer); }, [notes, lastSavedNotes]); const handleEndInterview = () => { setShowDecision(true); }; const handleDecisionConfirm = async () => { if (!sheikhId || !decisionType || processing) return; setProcessing(true); try { if (decisionType === 'approve') { await adminApi.approveSheikh(Number(sheikhId)); } else { await adminApi.rejectSheikh(Number(sheikhId), rejectionReason); } setShowDecision(false); navigate('/admin/sheikh-approval'); } catch (err) { console.error('Decision failed:', err); const apiErr = err as { status?: number; message?: string }; if (apiErr?.status === 500 && apiErr?.message?.includes('already approved')) { toast.info('Sheikh was already approved. Redirecting...'); setShowDecision(false); navigate('/admin/sheikh-approval'); } else { toast.error('Failed to process decision. Please try again.'); } } finally { setProcessing(false); } }; const getConnectionColor = () => { switch (connectionQuality) { case 'good': return 'text-emerald-500'; case 'fair': return 'text-yellow-500'; case 'poor': return 'text-red-500'; default: return 'text-gray-500'; } }; const getConnectionLabel = () => { if (!isConnected) return 'Connecting...'; switch (connectionQuality) { case 'good': return 'Excellent'; case 'fair': return 'Stable'; case 'poor': return 'Poor Connection'; default: return 'Waiting for Sheikh...'; } }; return (
{/* Header */}

Verification Interview

Sheikh ID #{sheikhId}

{connectionQuality === 'poor' ? : } {getConnectionLabel()}
{formatTime(sessionTime)}
LIVE
{/* Main Content */}
{/* Video Area */}
{/* Remote Video (Sheikh) — always in DOM so ref is always attached */}
{/* Local Video PiP (Admin) */}
{/* Chat Sidebar */} {showChat && (

Chat

{messages.map((msg, i) => (

{msg.message}

{msg.sender} · {msg.time}

))}