import React, { useState, useEffect, useRef } from 'react'; const ChatInterface = ({ socket, roomId }) => { const [messages, setMessages] = useState([ { text: "Hello! I'm your AI Tutor. Ask me things like \"Why does this step work?\" or \"What happens if the token expires?\"", sender: "ai" } ]); const [input, setInput] = useState(""); const [isMinimized, setIsMinimized] = useState(false); const [currentStep, setCurrentStep] = useState(0); const [protocol, setProtocol] = useState("JWT"); const messagesEndRef = useRef(null); const scrollToBottom = () => { messagesEndRef.current?.scrollIntoView({ behavior: "smooth" }); }; useEffect(() => { scrollToBottom(); }, [messages, isMinimized]); useEffect(() => { const handleStepChanged = (e) => setCurrentStep(e.detail); window.addEventListener("stepChanged", handleStepChanged); return () => window.removeEventListener("stepChanged", handleStepChanged); }, []); // Listen for WebSocket Broadcasts useEffect(() => { const handleWsMessage = (e) => { const data = e.detail; if (data.type === "chat_ai") { setMessages(prev => [...prev, { text: data.message, sender: "ai" }]); } else if (data.type === "chat_user") { setMessages(prev => [...prev, { text: data.message, sender: "user" }]); } }; window.addEventListener("wsMessage", handleWsMessage); return () => window.removeEventListener("wsMessage", handleWsMessage); }, []); const toggleProtocol = () => { const newProtocol = protocol === "JWT" ? "OAuth2" : "JWT"; setProtocol(newProtocol); window.dispatchEvent(new CustomEvent("protocolChanged", { detail: newProtocol })); // Broadcast protocol change so others see it (if we want global sync) if (socket && socket.readyState === WebSocket.OPEN) { socket.send(JSON.stringify({ type: "sync_state", protocol: newProtocol })); } }; const handleSend = (e) => { e.preventDefault(); if (!input.trim()) return; // We don't append immediately, we wait for the broadcast bounce-back so everyone is synced. // Prepare history payload for backend const historyPayload = messages .filter(m => m.sender === "user" || m.sender === "ai") .map(m => ({ role: m.sender === "ai" ? "assistant" : "user", content: m.text })); if (socket && socket.readyState === WebSocket.OPEN) { socket.send(JSON.stringify({ type: "chat", message: input, currentStep: currentStep, topic: protocol, history: historyPayload })); } setInput(""); }; const handleShare = () => { const url = window.location.href; navigator.clipboard.writeText(url) .then(() => alert(`Room URL copied to clipboard!\n${url}`)) .catch(console.error); }; if (isMinimized) { return (